Dijital Ay Çiçeği #3 Dön Bebeğim

Tarkan’ın Mavi Ceketli olduğu zamanlar vardı.. Efendi, uslu, musikişinas bir topluluğun seveceği Türk Sanat Müziği söylediği zamanlar..

Sonra parladıkça parladı..

Dön Bebeğim parçası önceki ve sonraki iki dönem arasında bir yerlere tekabül ediyor sanırım. Zira klipten anlıyoruz ki, artık çekimler yurt dışında yapılıyor, Mavi ceket hala var ama bir yandan da muzırlıklar başlamış..

 


 

Klipteki müzik kutusu balerini nasıl dönüyorsa bizim de elimizdeki güneş panelini döndürmemiz lazım 😉

Birinci yazında hazırlık yapmış, ikinci yazıda da cihaza elektrik geldiğinde ilk defa -ve bir defa- çalışacak olan Setup() fonksiyonumuzu yazmıştık.

Toplu ve sadeleşmiş hayliyle şöyle:

Burada, sadelik açısından kodların sadece tek ekseni kapsadığını hatırlatmak isterim. Güneşi doğudan batıya takip etmek elbetteki güzel. Ancak İDEAL bir sistem için yeterli değil. Panel, doğu-batı ekseninde dönerken aynı zamanda panelin yüzeyini yukarıya ve aşağıya bakacak şekilde de hareket ettirmemiz lazım.

Öğlen vakti sadece güney dönmüş bir paneldense, güneye ve yüzeyi yukarı bakan bir panel çok daha verimli olacaktır. Bu yüzden ideal bir sistemde aşağıdaki xMotor.attach(6); // Tek motor için
xMotor.write(aci); 
 kısımlarından birer tane daha olmalı 😉


#include
Servo xMotor;
const byte ldrSag=A1;
const byte ldrSol=A3;
byte aci=90;
int gunesSag, gunesSol;
void setup() { Serial.begin(9600);
// servo için PWM pinleri 3-5-6-9-10-11 olabilir
xMotor.attach(6); // Tek motor için
xMotor.write(aci);
}

 


Güneş (dünya) sürekli hareket halinde olduğuna göre, bizim de sürekli güneşin yerini bulmamız gerekiyor.

Bu yüzden iki ayrı koldaki IŞIK Şiddeti değerlerini karşılaştıracağız ve Sonsuz bir döngü içinde olacak.

 

Şimdii..
Diyelimdeki Sağ taraftaki ışık soldakinden fazla.

Motorun Sağa dönmesi lazım değil mi.. //ki Ay çiçeği olsun 😉

O zaman şöyle bir şeyler yazalım:

if (gunesSag > gunesSol) {
gunesSag = analogRead(ldrSag); gunesSol = analogRead(ldrSol);
Serial.print("sag"); Serial.print(gunesSag);
Serial.print(" Sol"); Serial.println(gunesSol);
aci = aci + 1;
xMotor.write(aci); delay(100);
}

Görüleceği üzere
güneşSağ>güneşSol İSE,
AÇI değerimizi bir arttırıyor ve Motor’a bu açıyı gönderiyoruz.

Motor o esnada atıyorum 27 derecelik konumda ise 28 dereceye dönüyor.

–E ama 1 dereceden ne olacak ki? 

Evet. İşte bu yüzden Loop() içinde, yani;
100 mili saniye sonra diğer IF‘e geçecek, ( delay(100) )
ve kabaca yarım saniye içinde Işık değerlerini yeniden okuyacak ve gerekiyorsa 1 derece daha dönecek.


Pek tabi iki taraftaki ışık değeri eşit ise, güneşi bulduk demektir. Dilerseniz burada bir süre (10 saniye 10 dakika..)  bekleyebilirsiniz.

1 dakika beklesin / dakika da bir kontrol edip o zaman dönsün derseniz; delay(1000*60) 
5 dakikada bir kontrol etsin derseniz;  delay(1000*60*5) kullanabilirsiniz 😉

 


Görsel

 

Dijital Ay Çiçeği #1 // 8000$ Değerinde post :)

İtiraf: Güneş takip sistemini tarif etmek için Digital Ay Çiçeği tabiri çok hoşuma gidiyor. Yazının kapak resmi olması için bununla ilgili bir şeyler ararken, karşıma görseldeki Robotic Sunflower Umbrella diye bir şey çıktı. Ve değeri 8000$ mış. Ben de başlığa bunu ilave ettim 

Biz güneş panellerini daha verimli kullanmak için, güneşi takip ettireceğiz. Onlar da güneşi takip ettirmiş ancak şemsiye yön vermek amacıyla. Bu da çok güzel fikirmiş! Alkışlıyorum.

Malumunuz Dünya, Güneşin etrafında dönerken “mükemmel çember” yerine Elips bir yörüngede dolanıyor.


wikipedia 0

Ve bu yüzden küçükken kışların; dünyanın güneşe uzak olduğu zamanlar,
yazların ise dünyanın güneşe yakın olduğu zamanlar gerçekleştiğini sanırdım.

Yukarıda görselde de görüleceği üzere: Asıl etkili mesele bu değil. En uzak olduğundaki aylardan biri Temmuz, en yakın olduğu tarih ise 3 Ocak.

— Ee? O zaman -40°C ile +40°C gibi 80 dereceye varan farklar nasıl oluşuyor?

— AÇI.

Güneş’in açısı ne kadar DİK AÇI ile gelirse o kadar sıcak oluyor.

Özetle;
27 derecelik açı, 5 milyon kilometre mesafeden daha etkili.

[Bu arada “dünya güneşe 10 cm daha uzak/yakın olsa, hayat olmazdı” sözünün ne kadar Hurafe olduğu aşikar.]

Bu durumda, öylesine güneye bakan güneş panelleri yerine, gün içinde güneşle birlikte hareket ederek daima dik açıyı yakalamaya çalışmak, yazla kış farkı kadar önemli.

Let’s do it

NŞA’da paneller çift eksende hareket etmeli. Ama karışık olmaması için tek motorla gidelim..

Burada sadece xMotor kullanacağız.

Benzer şekilde daha iyi anlaşılması için aşağı yukarı eksenlerini şimdilik pas geçeceğiz ama mantığın aynı olduğunu sanırım söylememe gerek yok. Sağdan sola doğru dönen, elimize alıp motoru çevirdiğimizi düşünün. Bu kez de yukarıdan aşağıya yahut çapraz dönecektir.

Sadeleşmiş halleri şöyle;

#include <Servo.h>
Servo xMotor;
const byte ldrSag=A1;
const byte ldrSol=A3;

#include Servo.h kısmı, Servo motorun sürücüsünü içeri çağırdığımız kısım.

ldrSag, Güneş Panelimizin sağ tarafına yerleştireceğimiz Işık Sönsörü (LDR) ‘yi bağlayacağımız Analog Pin

ldrSol da diğer taraftaki için.

Şimdi de panelin Dönüş Açısı ve bunu hesaplamak için kullanacağımız değişken tanımlarını ilave edelim.

Ok.
Cihazımıza ilk elektrik geldiğinde BİR sefer çalışacak olacak, Setup() fonksiyonumuzu yazalım.

Sade bir kullanım isteyenler dikey-yatay eksen kodlarını kullanmayabilir. Yani sadece tek eksen için şunlar yeterli:

void setup() { Serial.begin(9600);
// servo için PWM pinleri 3-5-6-9-10-11 olabilir
xMotor.attach(6); // Tek motor için
xMotor.write(aci);
}

Burada dikkat edilmesi gereken bir nüans var: Servo motorun bağlanacağı pinler, PWM özelliğine sahip pinler olmalı. Kullandığınız karta göre göre bu değişebilir. Bizim örneğimizde yukarıda açıklama kısmında geçen pinler kullanılabildiği için bunlardan bi tanesini (6 nolu pini) seçtik.

Hazırlıklarımız hazır.

Devam eden yazıda,
Ay Çiçeği mantığının nasıl işlediğini buna benzer bir algoritmayı bizim nasıl kurgulayabileceğimize bakacağız ve bakmakla kalmayıp panelimizi ay çiçeği gibi güneşe döndürecek kodlarımızı da yazacağız.

 

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..

Yürüyen İnternet

Hareketi/sıcaklığı/zamanı algılayıp bunlara göre kombiyi yönetebilmesi için AHMT‘i,  Hareketin bulunduğu mekana koyalım demiştik. Ve bu durumda Balkondaki kombi ile iletişim sorunu çıkmıştı.

Biz de asırlık  bir teknolojiyi, Radyo frekanslarını kullanarak çözüme gitmiş. AHMT’e bir de radyo frekans modülü (nRF2401L) eklemiştik. [Ya Evde Yoksan? + Radyo’dan Haberleşme]

Fakat o da ne modülün kütüphane kodlarında garip bir şey vardı..

Görsel1 Görsel2

Saniyede 2 Megabit’lik bir hızdan bahsediyor.

nRF modülü için teorik olarak 500 metre – 1000 metre gibi rakamlar söz konusu olsa da; şehir içi evler ve yollar gibi gerçek hayat ortamlarında bizzat test ettiğimizde, açık alanda 200 metre civarında, arada en fazla bir duvar olmak şartıyla ev içi ortamlarda az bir kayıpla haberleşebiliyor.

Bu mesafe Bluetooth’un 10-15 katı, Wifi modemlerin 2-3 katı bir uzaklık demek. Üstelik hız da; -şimdilerde vatandaşlık maaşı deneyleri yapan- Finlandiya’nın, daha önce Geniş Bant İnterneti İnsan Haklarına Dahil Edip ardından tüm vatandaşlarına ücretsiz olarak sunduğu 1 Mbit hızın iki katı.

Diyorum ki;
Yürüyen uçak yapabiliriz 

Kendi Kablosuz İnternet Protokollerimizi bile geliştirebiliriz.

E hadi standart demeyelim ama kendi özel iletişim sistemlerimizi kurabiliriz pek ala. “Uçuyorsun..” diyeceklere şöyle yanıt vermek isterim:  Düne kadar (1992) ASCII  varken, Bob ve Ken kafa kafaya verip UTF-8’i çıkardılarsa, yeni bir tanesi daha neden olmasın?

Atıyorum;
Daha önce geçtiği üzere bazı kelimeler daha çok kullanılıyor. [Steemit’te En Çok Kullanılan Kelimeler]

Çok basit 3-5 analiz ile Türkçe’de en sık kullanılan kelimeleri bulmak pek ala mümkün. Kaldı ki UTF8’in sunduğu  2,097,152 karakter sayısı hacmine, Türkçe’deki 616.767 kelime+deyimin 3.4 katı sığdırılabilir. (ekler ve tanınmayan heceler için öyle zemberek vari kelime yorumlama işlemlerine hiç girmeden basit formüller bulunabilir)

Yani?

İki saniye şuraya bi bakalım:
https://onlineutf8tools.com/convert-utf8-to-binary

“yağmur yağacak” yazabilmek için 32 byte harcadım.
bize hayli yetecek şekilde her kelimeyi 4 byte ile kodlamış olsak, 8 byte ile aynı iletişimi kurabiliriz. Yani şöyle:

y = 0111101
yerine
yağmur = 0111101

Abartırsak, bu sistem, web sitesi tarzı 4000X adet sunucu sayısının, 1000X adete düşmesi demek aynı zamanda text bazlı internetin 4 kat hızlanması demek.

Hatta yukarıdaki kelime öbeğindeki gibi sık kullanılan kelimeler ilk 1-2 byte içine oturacak şekilde ayarlanırsa çok daha optimize bir sistem ortaya çıkabilir.

Dünya Kabul Edecek mi?

AHMT’in Kombi haberleşmesi için Radyo frekans 1/0-AÇ/KAPA gönderebiliyorsak,
0111101 gönderince, arkadaşımın cihazının ekranına y yazdırmak yerine yağmur yazdırmak çok mümkün. Anteni biraz güçlendirince, toplasan 3-4-5 hava alanı kadar yer kaplayan Uşak’ta bizim işimizi hayli hayli görür..

Dünya kendi bilir 

 

Ya Evde Yoksan? + Radyo’dan Haberleşme

Harekete daha duyarlı hale getirdiğimiz AHMT‘i, Hareketsizlik durumları için de daha optimal hale getirmiştik. Bunun için kombi() fonksiyonumuzu belli bir süre boyunca dönecek bir döngü içine almıştık.

/* // 60*5 demek: 5 dakika yanacak */
for ( k = 1; k < 60 * 5; k++ ) {...; delay(1000); }


Bkz: #1, #2, #3#4#5#6#7#8#9#10#11#12#13, #14, görsel



Ya, Evde Yoksak?
(haliyle hareket te yoksa)

 

 

Ve işten/okuldan eve gelecek olduğumuzda, sıcak bir ev istiyorsak..
böyle durumlar için DS3231 saat modülünü işletmiştik. Yukarıdakine benzer bir döngüyü bu kısım için de kullansak sanki daha şık olacak.

Yani SAAT kısmı için kodlarımız şöyle olacak;


String saat = zaman.getTimeStr();
Serial.print ( "saat" ) ; Serial.println ( saat) ;
if (saat == "06:00:00") {
Serial.print (" **Eve gelişe yarim saat kaldı.. hareket olsun veya olmasın kombi yansın " ) ;
yanson ( 10 ) ;
for ( k = 1; k < 60 * 10; k++ ) {
Serial.print ( k );
kombi ( ISIdeger - 3 , ISIdeger ); delay ( 1000 ) ;
}
}

for’daki, k < 60*10 kısmıyla;
eve gelmeden önce, ne kadar süre ile kombi fonksiyonun tetikleneceğini ayarlamış oluyoruz. (10 dakika vb)

ISIdeger-3 ve ISIdeger kısımlarıyla, istenen sıcaklık aralığı da ayarlanabilir. (ISIdeger düğmeyi/potu çevirerek ayarladığımız değer)


Peki.. güzel.
Bu cihaz hareketi algılamak için salon ya da oturma odası gibi mekanlarda olacak.
Amma velkain


Kombi mutfakta ya da balkonda
.
Nasıl olacak bu iş?

Bu soruya, 100-150 yıl önceden gelen bir yanıt verebiliriz: Radyo.

Ki ilginç bir şekilde Radyo, Melon Şapka ya da İlaç Müzik türü yayınlardan çok önce (1894 Lodge, 1898 Tesla) ses için değil Uzaktan bir cihazı Çalıştırmak için kullanılmış. 


nRF24L01

Buradaki n harfinin Nordic/Norveç/İskandinav’a atıf yapıyor olması bana farklı şeyler düşündürüyor..
.. bir chip‘im bile yok anlıyor musun,
.. iklim değişikliği ise ayrı mevzu.. 

anyway..
Kodlarımıza nRF kütüphanemizi ekleyelim. (farklı kütüphaneler var, nRF modülünden hiç tepki gelmiyorsa, bir başka kütüphaneyi deneyebilirsiniz)

#include
#include
RH_NRF24 nrf24;

Arduino’ya güç geldiğinde Radyo modülümüzü başlatmak için,   void setup() { . . } içine  şu kodları ilave edelim:

while ( !Serial ); // Leonardo için, seri portu bekleyelim
if ( !nrf24.init() )
Serial.println ( "kurulum hatasi" );
// Başlatma sonrası yayın: 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" );

HEY dur bi dakika, Bİ DAKİKA! Nasıl yani? Burada 2 Mbps diyor!?

Evet, düşündüğün şey 😉

E o zaman Çok harika, Yürüyen Uçak yapabiliriz!

Evet!! Kesinlikle!!

 

AHMT, Sadece Gerekli ise Lütfen..

Valize teker eklemek gibi dramatik bir örnek olmasa da; Ses sensörü yerine PIR sensörü takarak AHMT’i harekete daha duyarlı hale getirmiştik.


Bkz: #1, #2, #3#4#5#6#7#8#9#10#11#12, #13görsel


Son durumdaki kodları biraz geliştirelim.

if (biri) {
Serial.println("biri var"); kombi(ISIdeger - 3 , ISIdeger);
} else {
Serial.println("kimse yok"); }

Burada, PIR sensöründen gelecek değere göre, ısıyı kontrol edip kombiye Çalış demesi için, kombi() fonksiyonunu çağırıyoruz.

Ancak yazılımsal olarak imla hatası olmasa da mantıksal olarak öyle mi tartışılabilir. Zira koda dikkat edilecek olursa, “biri” durumuna göre tetikleniyor. Biri=1 ise kombi’yi çağırıyoruz, Biri=0 ise kimse yok yazıyoruz.

Burada sürekli hareket etmemiz lazım ki kombi() fonksiyonu tetiklensin. Aksi halde herhangi bir aksiyon olmayacak. Yani çok fazla hareket etmeden uzanmış youtube izliyorsanız, biraz sonra üşümeye başlayabilirsiniz 


Şöyle bir güncelleme yapsak?

PIR sensöründen Biri=1, değeri geliyorsa, evde hareketlenme başlamış birileri eve gelmiş demektir. Ve kitap unutma/cüzdan unutma gibi vakalar yoksa çok büyük ihtimalle evde uzun bir müddet birileri olacak demektir.

Her iki -hatta tasarruf ögesini de eklersek 3- durumu düşünerek kodlarımızı şu hale getirelim:

if ( biri > 0) {
Serial.println ("biri var");
/* // 60*5 demek: 5 dakika yanacak */
for ( k = 1; k < 60 * 5; k++ ) {
Serial.print (k);
kombi ( ISIdeger - 3 , ISIdeger );
delay (1000); /* // çalışma süresi için durmalı */ }
} else {
Serial.println ( "kimse yok" );
kombi ( ISIdeger - 3 , ISIdeger );
}

gayet kolay ve pratik bir şekilde, kombi() fonksiyonunu bir döngünün içine aldık. Ve döndü adı üstünde başa dönmeden içerisine 1 saniye bekleme koyduk. Böylece; for’un çalışma şeklini belirtirken yazdığımız  k < 60 * 5 kısmında 5 yerine 10 yazarsak 10 dakika ya da Ne kadar süre boyunca kombi()’yi kontrol etmesi gerektiğini ayarlamış oluruz.

Dikkat! 10 dakika boyunca kombi yanacak demiyorum. 10 dakika boyunca kombi() fonksiyonunu çağıracağız.

Aradaki fark ne ki?

Birisinde,
hareketi algıladığında kombi yanacak.
10 dakika sonunda
yeniden hareketi dinlemeye(?) başlayacak.

Diğerinde,
hareketi algıladığında kombi’nin çalışmasına gerek var mı bakacak,
zaten istenen sıcaklık aralığında ise kombi yanmayacak
ama ortam sıcaklığı evde birisi varken olması gereken sıcaklıktan düşükse kombi yanacak.

// evet daha karpuz kesmedik,  evde birisi yokken olması gereken min ve max sıcaklık aralıklarını da kodlarımıza ekleyeceğiz 😉 //ki evde kimse yokken tümden kapanıp, eve birisi geldiğinde iyice buz olmuş evi ısıtana kadar millet hasta olmasın..

AHMT, Kalk salonda biri var galiba :) – İnovasyon

Son yazıdaki Mertcan’ın, çocukların ciğerini solduran ailelere atarlanmasından da anladığımız üzre, geniş alanlar önemli 😉 Biz de elimizdeki cihazın hafızasını optimal kullanmak için;

var yok veya doğru yanlış yahut 1/0 durumları için bool
2, 3, 5, 8, 18, 50, 150, 255 gibi değerler için byte
± 32768 arası için için int
0 – 65536 arası için unsigned int
±  2,147,483,648 arası için long
0 – 4,294,967,295 arası için unsigned long

şeklinde tanımlamalar yaparsak, ileride sorun yaşama ihtimalimiz azalır.

Bu yüzden hatırlarsanız,


Bkz: #1, #2, #3#4#5#6#7#8#9#10#11, #12görsel


Şimdi hareket / PIR sensöründen gelen değerleri, yorumlatalım..

analogRead ile değişken değerleri okurken (örn: sıcaklık, basınç..), digitalRead ile evet/hayır – 1/0 şeklindeki ikili değerleri okuyuyoruz.

biri = digitalRead(pir);

Tabi buraya bir değer gelmesi için, öncesinde  PIR sensörünün Data pinini ( + data -), Arduino’nun 6 dolu Digital pinine fiziksel olarak bağlıyoruz.

bu şekilde biri ‘nin değeri PIR’ın data değerine eşit olacak..
Yani Salonda hareket varsa 🙂 biri = 1 olacak

Ekranda görelim: Serial.print("biriDegeri:"); Serial.println(biri);


Alogaritmaların EN temeli olan IF ile biri hakkında dedikodu yapalım 🙂

Eğer biri, yakışıklı ya da güzelse.. Yok yok öğle değil 🙂

Eğer biri =1 ise, demek ki bir salonda bi hareket vardır. Hemen polisi arayalım.
Tamam tamam.. 🙂 Bunu ekrana yazalım.

if(biri) {
Serial.println ("biri var");
} else {
Serial.println ("kimse yok");
}


İnovasyon

Tekerlek ne zaman icat edildi? MÖ 3000 civarı.

Bavul, 1000 yıl önce?

Peki Tekerlekli Valiz? Daha dün!

> > içten yanmalı motora sahip ilk otomobilin 1885 yılında yapıldığını referans alırsak tekerlekli valiz neredeyse 100 yıl sonra 1972 yılında icat edilmiş. arada atom bombası yapılmış, internet kurulmuş, aya kadar bi arkadaşa bakıp çıkılmış.

Piyasadaki, kablolu ya da kablosuz, kombiyi kontrol eden tüm termostatlar Sadece ISI’yı ölçüp buna göre kombiyi yönetiyor. Biz ise Hareketi de dahil etmiş olacağız. (Ki takip edenlerin bildiği üzere artı bir de Saat olayını ekliyoruz malum. // Oldu olacak, olmuşken Kablosuz olsun.)

Valize teker eklemek kadar basit ama Devasa bir değişiklik durumu olur mu bilmem ama Kombinin yönetimini harekete bağlamak için şu sade kodları yazabiliriz:

Tabi bu haliyle sadece harekete ve sonrasında PIR’dan 15 saniye boyunca gelecek sinyale duyarlı olmuş oldu, hareketi algıladıktan sonra belli bir süre çalışması için biraz elden geçirmek lazım..

Dil Milliyetçiliği – pIR Sensörü bozuk mu Sürekli 1/High Gönderiyor

Tanımlar aşağıdaki gibi olacak ama Başlık hakkında bir kaç kelam etmek isterim detaya geçmeden önce..


 

Bir ırkı, ırk yapan en temel şey sanırım Dil. Bu yüzden sağda solda dilini kaybeden özünü/ülkesini/medeniyetini..  kaybeder gibi sözler duyuyoruz. Tarih kitaplarını falan karıştırsak konuyla ilgili bir sürü şey çıkar sanırım. Fakat o kadar maziye gitmeye gerek yok. Günümüz dünya küresine/haritasına bakmak da sözün ne kadar doğru olduğunu gösterebilir.

Bununla birlikte, parti meselelerinden uzakta, dünyanın herhangi bir ülkesindeki her hangi bir kişinin aşırı milliyetçi olduğunu biliyorsam, o kişinin konulara çok dar açıdan baktığını iddia edebilirim. Bakış açısı daha da darsa prof bile olsa pek ala cahil olduğunu iddia edebilirim. Buna çok içerlerse, en azından günümüz ve gelecek adına işlevi kalmamış bir beyin olduğunu söyleyebilirim //O da beni kendi ülkesinin vatan haini ilan eder 🙂


Bkz: #1, #2, #3#4#5#6#7#8#9#10, #11görsel


 

Diyeceksiniz ki “E be kardeşim ‘Konuşur gibi Türkçe Kod’ serisinde 14 yazı yayınlayan sen değil miydin?”

Evet benim. Mesele şu ki Japonya’da doğmuş olsa idim, “Kodlarımızı Japonca Yazabilmek için Shodo 書道 kütüphanesi” adında yine 14 yazılık bir seri yazabilirdim.

Benim tercihime bağlı olmadan Japonya’da doğduğum için Japonca konuşuyor olmak
ile
Japonya’da doğdum diye geçmişten günümüze tüm Japon imparatorlarını ve günümüz Japon ırkını Kutsayıp, herkesten üstün görmek arasında merih kadar fark var.


Çok fazla Türkçe kaynak olmadığı için, yazının başlığını özellikle seçtim. Hata aramalarında çıksın diye. (Daha dün akşam; komşunun çocuğu kendini oyununu yapmaya istekliydi fakat karışımıza çıkan sayfaların İngilizce olması hevesini kırdı.)


 

pIR Sensörü sağlıklı çalışmıyor 1/High Gönderiyor

Bu sorun 3 hafta belki de 1 ay kaybetmemize sebep oldu. Ama sorun da çözümü de Çok Komikmiş  

Geçen yazılarda geçtiği üzere sensörün üzerinde 3 tane pin, iki tane de ayarlama düğmesi/potansiyometresi var.

Artı(+) Eksi(-) Data(↕) kablolarını DOĞRU bağladığımız halde, sensör olması gerektiği gibi çalışmıyor. Sanki sürekli hareket varmış gibi Sürekli 1/high gönderiyordu. Tak çıkar yer değiştir bir sürü şey denedik. Nihayet sensörün bozuk olduğuna kadar verdik 🙂

Meselenin aslı ise komik dediğim kısım: Şimdi düşünün, hareketle otomatik yanan bir ışık sizin hareketinizle yandı. Hemen 2 saniye sonra sönüyor mu? Hayır elbette en az bir kaç+ dakika yanıyor.

Sensörü takıyoruz, doğal olarak bu esnada minik de olsa hareket algıladığı için HIGH veriyor. 2 Dakika beklesek/beklemek aklımıza gelse, olay çözülecek aslında ama biz güya test etmek için elimizi yeniden önünden geçirip hareket sonrası LOW gelmesini bekliyoruz.  Oysa 2 dakika sonra bitecek HIGH’ın süresini daha da uzatmış oluyoruz. Ve diyoruz ki;  sensör bozuk, sürekli high gönderiyor 


Hareket sensöründen gelen değeri bu kodlarla okuyacağız. Ekrana sürekli biriDegeri: 1 yazarsa panik yapmayın 🙂 ya biraz bekleyin ya da Sarı Düğmelerden, alttan bakınca soldakini çevirip süreyi 15 saniyeye kadar düşürün.


 

Bu kısımda ise dikkat çekmek istediğim bir nokta var.

Ne yazık ki youtube’da ve değişik sitelerde kod yazan arkadaş, her önüne gelen yere

int degisken_adi;

yazıp geçiyor. Bu örnekte mesela, PIR’dan gelecek duruma göre, odada birisi olup olmadığı durumuna bakacağız. Yani, ya VAR ya da YOK. Makina için BİR ya da SIFIR  bu kadar. Neden sadece 2 bit yer kaplayacak bir işlem için 32678 bit kullanalım ki? Böyle bir örnek için
bool degisken_adi; gayet yeterli ve de verimli olarak işimizi görebilir.

Sonra, makina kilitlendi.. dondu.. durduk yere bozuldu vs.  Yapmayın efenim olmaz böyle, cihaz nefes alsın, kendisine biraz oyun alanı kalsın 🙂

 

 

 

Yankı out, Kızılötesi in

Hareket, Sıcaklık ve Zamanı daha akıllıca kullanma Termostat’ı AHMT’in üretim macerasında hatırlarsanız, PIR sensöründe sorun olmuştu ve biz de ilerde değiştirmek üzere yolumuza mesafe sensörü ile devam etmiştik:


Bkz: #1, #2, #3#4#5#6#7#8#9, #10, görsel


Advisable thermostat for Heat, Moving and Time açılımında M’yi yani hareketi farklı yöntemlerle algılayabiliriz.

  • Zemine konacak basınç sensörleriyle
  • Ortamdaki Kızılötesi sıcaklık değişimini takip eden sensörlerle (pIR)
  • Ultrasonic ses dalgaları vericisi ve alıcısıyla (hoparlör/mikrofon) , gönderilen sesin daha yakın mesafeden (aradaki bi engel/birisi..) yankılanmasına göre
  • Üzerine sürekli ışık düşürülen, LDR sensörlerinden okunan ışık şiddetinin değişimine göre

 

Zemini söküp sensör döşeme gibi bir lüksümüz yok.  Ses sensörü sadece önünden geçilen durumları algıladığı için bu proje için tam olarak ideal değil. Evin içinde Laser ışıklarına da gerek yok (bi bu da yine önünden geçilmesi durumunda tetikleneceği için, eh ama pek optimal değil). Son seçeneğimiz:

PIR Sensörü

Pek çok apartmanın merdivenindeki ve cafe gibi topluluk mekanlarının lavabolarında, kapı önü aydınlatmalarında  sıklıkla karşımıza çıkan sensör. Pasive InfraRed sensörü.

 

Bizim kullanma amacımız ise, Evde hareketin olup olmadığını algılamak. Ve hareket yoksa kombiyi minimum seviyede kullanmak.


Donanımsal değişim yaptığımızza göre, UltraSonic mesafe sensörü HRC-04 ile ilgili kodları silip, PIR için kod yazmalıyız..

Sileceğimiz yerler:

Tanımlama bölümünde:

 

Setup bölümünde:

 

Mesafe ölçmek için yazdığımız fonksiyon:

 

Asıl işlemlerin gerçekleştiği Loop içindeki, irdeleme yapıp karar verdiğimiz kısım:


 

PIR kullanımı

pIR sensörü kendi içinde biraz atraksiyonlu olsa da  bağlantısal açısından sade bir mantığı var:

Hareket varsa, data pinine elektrik geliyor, yani 1/high oluyor.

Bu kadar.

Kullanım açısından ise, yerleştirileceği yere göre ayarlamak üzere üzerinde 2 adet pot/düğme bulunuyor.

Birisi algılama hassaslığı için (ki zannediyorum kaç derecelik bir alanı göreceğini belirleyerek bunu sağlıyoruz)

Diğeri de, hareket algılandığında ne kadar süre boyunca 1/high geleceği. Yani daha bilindik örnekle; merdiven otomatiği hareketi algılar ama 30-40 saniye sonra erken söner ya hani.. işte süreyi ayarlamak için çevirdiğimiz yer burası. (bkz: yukarıdaki resimde, soldaki sarı Timing ON-delay düğmesi )


görseller: ozcott,   toolstation
ileri okuma

Zamanı Bilmek

“What time is it?” sorusu ile “What is the time?” sorusuna verilecek cevaplar hayli farklı olsa gerek 😉

Her gün kullandığımız bir kelime Zaman. Ama 2 kelimelik bir soru bizi derin düşüncelere gark edebilir.

Zaman nedir?


Görsel
Evveliyat: #1, #2, #3#4#5#6#7, #8, #9

Cevabı size bırakıp, başka bir soru daha sorayım.

Zamanı nasıl ölçeriz?

Günümüzde 1 Saniye’nin yaklaşık tanımı şöyle: Sezyum atomun 9.192.631.770 defa titreşimi için geçen süre.

? Neredeyse komik bir tanımlama. Ancak Sezyum hayli karalı olduğu için zamanı, 100 milyon yılda 1 saniye sapacak hassasiyette ölçebilir. Bu da geçen yazıda bahsi geçen senkronizasyon sorunlarını minimize etmek demek.

Bununla birlikte, daha yakın zamanda geliştirilen başka atom saatleri de var. Örneğin:

.. stronsiyum atom saati o kadar hassastır ki, Büyük Patlama’dan beri (yaklaşık 14 milyar yıldan beri) çalışıyor olsaydı bugün zamanı 1 saniyeden daha az bir hata ile gösteriyor olurdu.

..

genel görelilik kuramının en önemli sonuçlarından biri, zamanın akış hızının kütleçekiminden etkilenmesidir. Dolayısıyla yeryüzünden farklı yüksekliklerdeki saatler farklı hızlarla çalışır. Dünya gibi küçük gezegenlerin etraflarındaki zayıf kütleçekim alanlarında bu etkiyi sıradan saatlerle ölçmek çok zordur. Ancak en son geliştirilen stronsiyum atom saatlerinin yüksekliğini sadece 2 santimetre değiştirerek zamanın akış hızında meydana gelen değişiklikleri gözlemlemek mümkün.

http://bilimgenc.tubitak.gov.tr/makale/atom-saatleri


Bizim AHMT örneğinde bu kadar hassas ölçümlere gerek yok ancak, Elektrikler kesilse bile Zaman Bilgisi’ni hafızasında tutacak, “Saat kaç? Bu günün tarihi ne?” gibi sorulara yanıt verecek bir modül kullanıyoruz.

Neden?

Hatırlarsanız, AHMT‘i sıcaklığa ve harekete duyarlı hale getirmiştik. Verdiğimiz değerlere göre oda sıcaklığını ayarlamak için kombi() fonksiyonu yazmıştık.

Bu, oda sıcaklığını diyelim 22 derecede tutmak için kombiyi çalıştırıp-durduruyordu. Bu fonksiyonu Hareket algılama içinde kullanınca; odada hareket yoksa, sıcaklığı 22 derecede tutmaya çalışmak yerine minimum değerde tutuyordu.

Buraya kadar her şey güzel. Fakat bi sorun var.

Herkes işte ya da okulda iken, odada hareket olmadığı için oda sıcaklığını minimumda tutacak bu iyi ama eve geldiğimizde 22 derecelik değil daha serin bir ev bizi karşılayacak demek.

Elimizde bir Gerçek Zaman Modülü olursa, Saat kaç? diye sorup, eve geliş saatinden yarım saat önce kombinin çalışmasını sağlayabiliriz 😉


Saat modülümüzün kütüphanesini ekledikten sonra. Pinleri belirterek Zaman nesnesi oluşturalım.

#include
DS3231 zaman(SDA, SCL);

Ve saatin kaç olduğunu öğrenelim:

getTimeStr() kullanarak Zaman’a ait Saat bilgisini aldık ve bunu saat değişkenine atadık.

Şimdi saat bizim belirttiğimiz vakte gelmiş mi buna bakalım. // sonra röleyi tetikleyelim ki, eve geldiğimizde sıcak bi karşılama ile karşılaşalım 

 

Zaman sadece birazcık zaman..

Advisable thermostat for Heat, Moving and Time = AHMT  ifadesindeki T‘ye geldik: Zaman.

Çok basit gibi dursa da özünde Mutlak Zaman‘ı ölçmek, alengirli bir mevzu. Zamanı ölçme işi boyunca da zaman geçtiği için konun içinden ucu Heisenberg’e giden ince bir yol geçebilir 🙂

Şükür bizimki o kadar derin bir mevzu değil ama bazı yerlerde dikkatli olmakta fayda var.


Görsel: Mathew Maher,
Evveliyat: #1, #2, #3#4#5#6#7, #8

Zamanlama sorunuyla, her dakikanın sekizinci saniyesinde işlem yapması gereken bir bot tasarlarken karşılaşmıştık. Pek çok detayı hesaplayıp buna göre tedbir aldığımızı düşünüyorduk. Ancak kim derdi ki; Windows’un saati saniye bazında doğru çalışmıyor. Maalesef böyle bir durum varmış. Ardından buna bir çözüm bulduk: Her dakika Windows’un saatini Atom Saati sunucularına göre güncelleyen programlar kurduk.

Fakat bir gün hesaplayamadığımız bir olay daha gerçekleşti. Yazdığımız botun üzerinde çalıştığı program da zamanlama derdinden muzdaripti ve güncellemelerden birisinde, kendi zamanlama sistemlerini 15 saniyede bir milisaniye bazına düzeltme yapmak için ayarlamışlardı. Fakat biz bunu anlayana kadar, bir haftalık kazancımızı kaybettik :((:

Bize, Windows’tan ve üzerinde çalıştığı sistem bağımsız bir şekilde, her dakikanın sekizinci saniyesinde tetiklenecek bir sistem lazımdı. İlk o zaman aklımıza Robot Kol yapma fikri düştü. Dokunmatik bir ekran alıp, kolu programlayacaktık ve söz konusu zamanlarda ekrana dokunacaktı.

Böylece Maker/Robotik/Arduino dünyasına Merhaba demiş olduk.

Ancak hareket ettirme olaylarına bakarken, Python‘un klavye ve fareyi de rahatlıkla kontrol edebildiğini gördüm. Robot kola gerek kalmadığı için Python ile muhabbetimizi Merhaba’nın ötesine taşıdık.

“Zamanlama Sorunu”, İKİ SÜPER OKYANUS için bize birer kapı aralamış oldu.

Önceden şerbetli olduğumuz için AHMT için, zamanlama olayını yazılımsal olarak nasıl çözeriz? şeklinde beyhude bir uğraşa girmeden, direk Gerçek Zaman Saati modülünü sisteme bağladım.

Popüler bir modül olduğu için çeşitli kütüphaneleri var. Ancak bazıları bi şekilde çalışmıyor. En azından bende çalışmadı. Çalışanı versiyonunu şu şekilde mevcut kodlarımıza adapte edebiliyoruz:

Kod kısmına bunları yazdıktan sonra indirdiğimiz kütüphane dosyalarının …\Arduino\libraries\ klasörü altında olduğundan emin oluyoruz.

Modül SDA ve SCL pinlerine bağlandığı için kullandığımız kartta bu pinlerin kaçıncı pine denk geldiğini bilmemiz gerekiyor.

Nano için durum şöyle:

yani A4 ve A5 pinlerine bağlıyoruz.

devam edecek..


Aylık 70+ TL değerinde “IF”

Kombiyi yönetecek olacak fonksiyonumuzu yazmıştık. Şimdilik sadece basit aç kapa olaylarını barındırıyor. Ve bunu ne zaman yapacağını söylemek için daha önce yazmış olduğumuz ISI() fonksiyonundan gelen değerleri argüman olarak kullanacağız. // Bkz: #1, #2, #3#4#5#6, #7

Yani şöyle;

  • Kullanıcı, istediği sıcaklığı ayarlamak için potansiyometreyi çevirecek
  • Analog pinlerden birisine bağlı olan bu potansiyometreden gelen değerleri okuyacağız
  • Doğal olarak o bacağa kaç volt geliyor gibi elektriksel bir değeri okumuş olacağız
  • Ne kadar çevirdiğimizde, voltajda ne kadar değişim olduğuna bakacağız.
  • Arduino analog pinlere gelen değerleri 0-1023 arasında gösterdiği için, olabilecek istenen ısı değerleri için oran orantı yapacağız. Yani ısı için belirlediğimiz değerler 12°C ila 28°C arasında ise şöyle bir mantık izleyeceğiz: 1024 şayet 28’e ve 0 da 12’ye eşitse.. düğme çevrilirken pinden okunan 512 değeriyle kaç dereceyi kast etmiş olacağız.. (20°C) Bunun için basit denklemler kurulabilir ancak hazır gelen MAP fonksiyonu tam da bu işi yapıyor 😉
  • Potansiyometre 21°C için ayarlanmışsa, kombi() fonksiyonumuza üst sıcaklık argümanı olarak 21+1=22°C göndereceğiz. Alt sıcaklık argümanı ise 21-3=18°C derece olacak.
  • kombi() fonksiyonumuz kendi içinde ISI() fonskisyonundan gelen bu değerleri, ortam sıcaklığını ölçtüğümüz derece() fonskiyonundan gelen değerlerle kıyaslayacak. Sonra şunu yapacak:
    IF/eğer, (derece, istenen ısı’dan büyükse) { röleyi kapat -dolayısı ise rölenin bağlı olduğu kombiyi durdur}
    else/değilse (derece, istenen ısı’dan küçükse) { röleyi aç – kombiyi çalıştır }

Bir kere kombi() fonksiyonumuzu oluşturduktan sonra

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); */}
}

Lazım olup kombiyi yönetmek istediğimiz kısımlar geldikçe, şu şekilde yazmamız yeterli olacak;

kombi(18, 22);

Böylece,
sıcaklık 18 derecenin altına düştüğüne kombinin yanmasını,
sıcaklık 22 derecenin üzerine çıktığında da kombinin sönmesini sağlayacağız.

AHMT’in sadece H‘sini kullanan, yukarıdaki fonksiyonun yüklü olduğu versiyon, hali hazırda Kombiye takılı ve şu anda çalışıyor 😉
Öyle keskin istatistikler henüz tutmadık ama getirisinin 60-70-80+ TL civarında olduğu söylenebilir.

M ve T eklendiğinde neler olacak göreceğiz 😉


görsel