AHMT: Kombi() fonksiyonu upgrade

Yürüyen İnternet yazısı ile uçuşa geçip 🙂 HTTP benzeri ya da ötesi kendi protokollerimizi yapabileceğimizden bahsetmiştik.

Yeniden AHMT’e dönelim. Hareket algılayıcı taraf ile direk kombiyi kontrol edecek tarafın, Radyo sinyalleriyle Kablosuz haberleşmesi için AHMT’e nRF2401L ilave etmiştik.


Bkz: #1, #2, #3#4#5#6#7#8#9#10#11#12#13#14, yürüyen internetgörseller


 

Kütüphane kısımını düzenledik ama Fonksiyonları da buna göre düzenlememiz lazım ki bir bütün olarak sistemimiz sağlıklı bir şekilde çalışabilsin.. // madem öyle ilgili kısımlara bütün olarak bakalım..

Let we do

Tanımlama kısmında şu kodları ekleyelim:

#include
#include
RH_NRF24 nrf24;

void setup(){ içine } şunları ekleyelim:

while (!Serial); // Leonardo için
if (!nrf24.init())
Serial.println("kurulum hatasi");
// Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
if (!nrf24.setChannel(1))
Serial.println("radyoKanali hatasi");
if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
Serial.println("nRFhiz hatasi");

Kombi fonksiyonumuzu şu şekilde yeniden düzenleyelim:

void kombi ( byte alt, byte ust ) { /* alt ve üst sıcaklık değerlerini kullanıyoruz */
byte dereceDeger = derece();
if ( dereceDeger < alt ) { yanson(2); Serial.print("kombi Yandi: "); uint8_t data[] = "AC"; Serial.print( "AC" ); nrf24.send ( data, sizeof( data ) ); nrf24.waitPacketSent(); /* Radyo sinyali olarak gonderelim */ /* digitalWrite (role, LOW); */ } else if ( dereceDeger >= ust ) {
Serial.print( "kombi Sondu: ");
uint8_t data[] = "KAPA"; Serial.print( "KAPA" );
nrf24.send( data, sizeof ( data ) );
nrf24.waitPacketSent();
/* digitalWrite ( role, HIGH ); */
}
else {
yanson(30);
Serial.print( "-kombi else-" ); /* digitalWrite ( role, LOW) ; */
}
}

 


kombi() fonksiyonu içindeki digitalWrite ( role, LOW ) ve digitalWrite ( role, HIGH ) kısmı, inceleyen gözle bakan birisi için ters gelmiş olmalı.

Gelmediyse de açıklama yapayım 🙂
Zira bu basit terslik yüzünden başka bir projede bir kaç gün kaybetmiştik.

Aslında orta okulda öğrenmiştik..

“Hojcaam bu gerçek hayatta ne işimize yarayacak kii” sesleri eşleğinde öğretmenler şunu hemen hepimize anlatmıştı:
Bunun gibi __/ __  bir devre açık demek.. ama bu aynı zamanda elektrik geçmediği için lamba kapalı demek. Lambayı açmak için devreyi kapatmamız lazım.

Dolayısıyla, Role’ye LOW gönderiyoruz.
yani içindeki mıknatıs-devre düzeneğini kapatacak,
veyani üzerinden elektrik geçmeye başlayacak,
veyani röleye bağlı olan kombi çalışmaya başlayacak 😉

HIGH durumu için de tersi elbette..

Ecrin, Eymen, HomoDeus, byte ISI(){}, void kombi(){}

#1, #2, #3#4#5, #6


Veri tiplerini inceleme gibi bir amacım yoktu ancak projedeki fonksiyonların nasıl çalıştığını irdelerken, konu veri tiplerine gelmiş oldu. İyi de oldu.

Aslında konu çok uzayacak olmasa, mümkün olduğunda ve yeri geldiğinde Mantıksal Kapı Devrelerine kadar inmek bile çok keyifli olabilir.

-yakın gelecek olmasa bile orta vadeli gelecek manasında- Yarın; Niyazi amcanın kızı Ecrin ya da Filiz teyzenin oğlu Eymen kendi işlemcisini tasarlayacaksa, “p ve q’lar”, “1 VEYA 0 = 1 eder”ler, “XOR”lar, “Seri bağlı PNP”ler.. havada uçuyor olmalı.

Günümüzde bile pek ala hissettiğimiz HomoTapiens, HomoSapiens ve HomoDeus ayrışmaları giderek keskinleşeceği için elbetteki büyük bir kitle matematiğe ve mantığa Uranüs kadar uzak olacaklar ama bulunduğu gezegeni olumlu yönde daha ileriye taşıyacak birileri de olacaktır mutlaka.


 

AHMT’in kodlarına dönecek olursak,

Daha önce Arduino’nun ana döngüsü olan void loop() {} içinde, şöyle yazmıştık:

istenenISI = map(analogRead(A3),7,1023,10,30);
Serial.print("istenen ISI: "); Serial.print(istenenISI);

Burada, kullanıcı odayı hangi sıcaklıkta istiyorsa onu ayarlamak için bir potansiyometreyi çeviriyordu ve biz de ANALOG bağaca gelen değerleri okuyorduk. Ki kullanıcı  hangi ara değerleri istemiş görelim. -digitaller gibi sadece var/yok değil, 0, 5, 8, 18, 26.. vb.-

yukarıdaki şekilde void loop(){} içinde işimizi görüyorduk ancak kodlar ilerledikçe kullanıcının ayarlamış olduğu değeri başka yerlerde de kullanmamız gerekecek. Ve bunu tek hamlede almak işimizi hayli pratikleştirebilir.

Bu yüzden ufak değişikliklerle bunu bir fonksiyon olarak yazalım ve lazım olukça kullanalım 😉


Son birkaç yazıda temellerini attığımız üzere, fonksiyonumuzdan bize bir sonuç döndürmesini istediğimiz için,

bize dönecek olan değerin tipine göre bir kullanım yapıyoruz. Oda için istenen ısı değerleri döneceği için 0-255 aralığı yani BYTE kullanmak yerinde olacaktır.

byte ISI(){ istenenISI=0;
istenenISI = map(analogRead(A3),7,1023,10,30);
Serial.print("istenen ISI: "); Serial.print(istenenISI);
return istenenISI;
}

fonksiyonun başına ve sonuna dikkat..


 

Bize bir sonuç ya da rakam vermeyecek ama hayli kritik bir işlev görecek olan fonksiyonumuz ise void kombi(){}

neden byte kombi(){} değil de void kombi(){} diye soruyorsanız, “büyük ihtimal seriye ortadan dalmışsınız” derim. Vira #1  🙂

void kombi(byte alt, byte ust){
byte dereceDeger = derece();
if (dereceDeger<alt){ yanson(15); Serial.print("kombi Yandi: "); /* digitalWrite(role, LOW); */ }
else if (dereceDeger>=ust) {yanson(4); Serial.print("kombi Sondu: "); /* digitalWrite(role, HIGH); */ }
else {yanson(1); Serial.print("kombi else: "); /* digitalWrite(role, LOW); */}
}

 

burası fiziksel olarak işi yüklenen kısım olacağı için bir sonraki yazıda burayı biraz açalım..


görsel

 

Arduino Veri Tipleri, AHMT derece() fonksiyonu

Evvel zaman içinde, kalbur saman içinde: ##1, ##2, ##3##4, ##5


Arduino fonksiyonlarını kullanırken, ne zaman Void ne zaman Byte ya da Int kullandığımıza bakmıştık. Olayın mantığı açısından Byte ve Int örnekleri kafi sanırım. Ama yine de yanlış anlaşılma olmaması için sadece bunlarla kısıtlı olmadığını belirtelim. Aşağıdaki veri tiplerinin hepsi kullanılabilir. Yeri gelmişken kimin ne olduğuna değinelim.

Arduino Veri Tipleri

bool  // Evet Hayır Doğru Yanlış HIGH LOW tanımları için  kullanılır

boolean // standart değildir ve bool ile aynı işlevi görür

byte // 8 adet 0/1’den oluşur. Yani 1 Byte. Sayı olarak 0-255 arası değerler için  kullanılır

char // tahmin edilenin aksine özünde -127 ve +127 aralığındaki sayılara karşılık gelir. char x = 65 tanımı ASCII tablosunda A olarak tanımlandığı için A’ya denk olur.  Harf işlemleri için kullanılır.

String  // Metin kelime/cümle tanımları için kullanılır. Sayılar için kullanıldığında ASCII metin görünümünü verir. String() fonksiyonu ile karıştırmamak gerekir.

int // en az 16 adet 0/1’den oluşur. Yani 2 Byte. -32,768 ila 32,767 arasındaki değerler için kullanılır. AMA! Bu standart değildir. İşletim sistemi ya da İşlemci’ye göre farklılık arz edebilir. Örneğin Arduino Due için INT demek 32bit/4byte demek olduğu için -2,147,483,648 ila 2,147,483,647 arası değerleri taşıyabilir.

int16_t // yukarıdaki sorunu çözmek ve cihaz değişikliklerinde sorun yaşamamak için “tam olarak 16 bit” manasında kullanılır.

long // en az 32 adet bitten oluşur. Yani 4 Byte. -2,147,483,648 ila 2,147,483,647 değerler için kullanılır. Standart olmama durumu yine vardır.

int32_t // tam olarak 32 bitten oluşur.

float // ondalıklı sayılar için kullanılır. Örn: 12.34 ya da 56.78E+4 gibi..

double // AtMega işlemcili (AVR dili kullanan) kartlar için Float ile aynı işlevi görür

short // Arduinolar için int ile aynı işlevi görürür

unsigned char // Eksiden başlamak yerine 0’dan başlar. Dolayısıyla char -127 ila +127 arasında iken, işaretsiz unsigned char 0-255 arası değer alabilir.

unsigned int // benzer şekilde eksiden (-32,768) başlamak yerine Sıfırdan başladığı için 65,535’e kadar değer alabilir

unsigned long // 0 – 4,294,967,295 arası değer alabilir.

void // değer döndürmeyen fonksiyonlar için kullanılır

word // 0 – 65,535 arası değer alır, unsigned int ile aynı işlevi görür.


https://www.arduino.cc/reference/en/#variables


byte derece() { } fonksiyonu

Daha önce sıcaklık ölçmek için fonksiyon yazmıştık.

Görüldüğü üzere void fx(){} olarak kullanmışız. Yani; Evet sıcaklık pinine gelen voltaj değerlerini okuyup bunun kaç dereceye denk geldiğini hesaplatıyoruz ancak fonksiyonu kullandığımızda elimize “eşittir şu” diyecek şekilde bir değer sunmuyor bize.

Bunun olabilmesi için yukarıdaki veri tiplerini de göz önünde bulundurarak, fonksiyonumuzu şu şekilde tanımlayabiliriz:

neredeyse aynı. Sadece küçük ama önemli nüanslar var:

* byte fx(){} olarak kullandık, bize sunacağı değer 0-255 arasında olacağı için. (int ya da long da kullanabilirdik ama oda sıcaklığı için 255 zaten hayli yeterli)

* return derece; var, hesapladığı değeri bize sunması/döndürmesi için

* başta değerleri sıfırlıyoruz. Her fonksiyon için şart değil elbet ancak biz sıkça kullanacağımız için, önceki ölçüm değeri ile karışıklık olmaması için sıfırlayalım, kafamız rahat olsun 😉

 

AHMT sicaklikOlc() fonksiyonu

Evveliyat: ##1, ##2, ##3, ##4


ISI ve sıcaklık ile ilgili kısımlara gelmiştik. Biraz açıklamasını da yaparak devam edelim.. // görsel

sicaklikOlc() fonksiyonu

C gibi temel dillerden geliyorsanız Arduino kodları sizin için çocuk oyuncağı olabilir. Hoş farklı dillerden geliyorsanız da çok zor değil hatta bi hayli basit ve net.

Arduino değişken tanımlama

Örneğin bir değişken tanımlarken
Php’de $x=15;
JavaScript’te var x=15;
Python’da x=15

şeklinde belirtiyoruz. Burada ise değişkenin kaç bit/byte’lık oluğuna göre türünü belirtiyoruz. Ya da metin/karakter olma durumunu da söylüyoruz: byte x=15;

Arduino fonksiyonlar

Benzer şekilde fonksiyon tanımlarken de sade ve net. Sadece ufak farklılıklar var.
Python’da def fx(): bişeyler yap..
JavaScript ve php’de function fx() { bişeyler yap.. }

şeklinde tanımlarken burada
void fx() { bişeyler yap.. }
ya da
byte fx(){ bişeyler yap.. }
olarak tanımlıyoruz. void fx() kullanımı, Return ile sonuç döndürmeyen fonksiyonlar için. Şayet fonksiyonumuz bir sonuç üretiyorsa bu durumda üretilecek verinin türünü belirtmemiz gerekiyor. Örneğin fonksiyonmuz byte tipinde bir sonuç döndürüyorsa
byte fx() { bişeyler yap.. return sonuc; } şeklinde tanımlama yapıyoruz. Fonksiyonumuza bir argüman gönderip, ona göre sonuç alıyorsak bunu da byte fx(a){ a.. do.. return } şeklinde kullanıyoruz.

En genel hali ile şöyle:

dönüşTipi funksiyonİsmi( argüman-lar ){
sonuçTipi sonuç;
bişeyler yap..
return sonuç;
}

Böyle çok havada kalıyor sanırım. Yukarıdaki tanımlamaları da kapsayan kısa bir örnek yapalım.

////////////////////////////
void yaz() {Serial.println("Merhaba"); }
// Bi şeyler yapıyor ama bize bir sonuç ile geri döndürmeyeceği için
// void fx(){} kullanıyoruz.

////////////////////////////

byte cevre() {
byte A=20;
byte B=40;
byte cevreuzunlugu = 2*(A+B);
return cevreuzunlugu; }
//return ile 255'ten küçük bir değer döndüreceği için
// byte fx(){} şeklinde kullanıyoruz

////////////////////////////

int alan() {
byte C=30;
byte D=50;
int kapladigiAlan = C*D;
return kapladigiAlan; }
//return ile 255'ten büyük bir değer döndüreceği için
// int fx(){} şeklinde kullanıyoruz

////////////////////////////

int y = 350;
byte x = 75;
void topla(){ int z = x+y; Serial.println(z); }
//return ile bir değer döndürMEyeceği için
// void fx(){} şeklinde kullanıyoruz

////////////////////////////

int p = 300;
byte j = 15;
int carp(int k, int m){
int sonuc;
sonuc = k * m;
return sonuc; }
//return ile 255'ten büyük 32768'den küçük bir değer döndüreceği için
// int fx(){} şeklinde kullanıyoruz
// dışarıdan bizim verdiğimiz değişkenleri kullanarak işlem yapması için
// int fx(int arguman1){} şeklinde kullanıyoruz

////////////////////////////

//tanımladığımız fonksiyonları iş başında görelim 😉

void setup() { Serial.begin(9600);
yaz();
byte ornekIKI = cevre(); Serial.println(ornekIKI);
int ornekUC = alan(); Serial.println(ornekUC);
topla();
int ornekBES = carp(p,j); Serial.println(ornekBES);
}
void loop() {}



 

Bu bilgiler ışığında AHMT’in kodlarına yeniden bakalım..Bu sefer bi tık daha sıcak gelebilir 😉

Sıcaklık Volt ve Sıcaklık değişkenlerimizin integer ve float (noktalı sayı) olduğunu, ayrıca hangi bacağa bağlantı yaptığımızı tanımladık.

Return ile bir sonuç döndürmeyeceği için fonksiyon oluştururken void sicaklikOlc(){} olarak kullandık.

Fonksiyonun içinde ise SicaklikPini’ne bağlı sensörden gelen değerleri okuduk (doğal olarak derece değil volt) sonra kaç voltun kaç santigrat dereceye denk geldiğini hesaplatıyoruz. Bu arada bu işlemin sağlıklı olabilmesi için void setup(){} içinde  kullanacağız.

Kodun ilerleyen kısımlarında, herhangi bir yerde LM35’ten gelen ortam sıcaklığının o andaki değeri lazım olduğunda şöyle demek yeterli olacak:

sicaklikOlc();