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

 

Sevil(e)meyen NodeJs için Notlar

Daha ilk denediğimde; Python’u, Php‘yi, jQuey‘i ve Arduino‘yu çok sevmiştim. Elbette bazen kurulum esnasında, bazen de  dilin mantığına ve imlasına alışırken sorunlar çıkıyor ama bunları çözmek orta zorlukta bir bulmaca gibi çözmesi sıkıntıdan çok keyif bile veriyor denilebilir.

Ama Flappy Bird gibi ilerleme sürecini her dakika engelleyip, insanı germekten başka bir işe yaramayan ama bir şekilde bir süreliğine popüler olmuş şeyler oluyor. NodeJS de Flappy Bird’den ya da Rober Hatemo’dan farklı değil.


Görseller: nodejs, flappy bird


Sıfırdan NodeJS yazacak ne zamanım var ne ekibim. TAR niyetlenmesi dışında, tamama erişmiş bir tecrübem de yok. Ancak NodeJS’e İTİRAZ etmeye devam ediyorum 🙂

Bununla beraber, Pyhton3.7 ya da Nodejs gerektiriyor.
Python 3.7+ 32bit kabul etse de gerekli bazı kütüphaneler 64bit istiyor. Kullandığım pc’de çok fazla şey yüklü ve ayarlı olduğu için değiştiremiyorum da.. Bu yüzden Node’a mecbur kalıyorum..

 


Kendime ve bir şekilde Node’a bulaşmak zorunda olanlara notlar..

NodeJs Open SSL (32bit) Kurulumu denemeleri..

https://slproweb.com/products/Win32OpenSSL.html
adresinden

Win32 OpenSSL v1.1.1a Light MSI (experimental)
indir, kur

Kurarken yolu

C: \ OpenSSL-Win32

olarak ayarla

————-

Ortam değişkenlerinden PATH’a OpenSSL’in yolunu gir
(bilgisayarım > özellikler > gelişmiş sistem ayarları > gelişmiş > )

Sistem değişkenleri arasından PATH‘i seç
İkinci satırın sonuna, noktalı virgül ve ardından
C:\OpenSSL-Win32 
ekle

—-
yeni’ye tıkla

üste:
OPENSSL_CONF

alta:
C:\OpenSSL-Win32\bin\cnf\

ekle

——–

cmd aç

openssl

yazıp enter’a bas

Her eksik olarak söylediği .dll dosyasını google’da ara 32bit versiyonlarını indir

yeniden openssl

yazıp enter’a bas, eksik derse yine indir.. (17-20 tane olabilir)
https://www.dlldosyaindir.com/dllkategori/a-ile-baslayan-dll-dosyalari/?v_sortby=views&v_orderby=desc

nihayet şöyle olmalı

C:\Users\Arwen>openssl
OpenSSL>

sondaki
OpenSSL> ‘i görünce olmuştur

YEY! sonunda 😉

////***** başa dönmek gerekirse **
Windows 32 bit ve Windows 64 bit için CMD komut penceresine sfc /scannow komutunu girerseniz, bilgisayarınızda bulunan tüm DLL dosyalarını onarırsınız.
****///

———————–

Node kısmına geçelim

cmd/konsolda

npm install pem

yazıp, pem modülü kur

app.js içine şunları yazarak dene:

var https = require('https')
var pem = require('pem')
var express = require('express')
pem.createCertificate({ days: 1, selfSigned: true }, function (err, keys) {
if (err) {
throw err
}
var app = express()
app.get('/', function (req, res) {
res.send('o hai!')
})
https.createServer({ key: keys.serviceKey, cert: keys.certificate }, app).listen(443)
})

cms/consol’da
node app.js
yazınca openssl config failed: error:02001002:system library:fopen:No such file or directory

ya da

openssl config failed: error:02001003:system library:fopen:No such process

benzeri bir hata veriyorsa

CMD açıp
set OPENSSL_CONF=

yaz.

nodejs dinlemeye başlayacak.

———–

nodejs dinlemeye başlıyor ama
tarayıcı da ERR_CONNECTION_REFUSED hatası geliyorsa
httpS portu 443 olduğu için node’un dinlediği portu düzenle

—–
bağlantı reddetme aşıldı ise
ERR_SSL_PROTOCOL_ERROR
hatası verebilir.

Bu hataya kadar sevinmek lazım, zira güvenlik sertifikası kısmına geldik demektir. Şu aşamada olay çözülecek gibi duruyor ama “nasıl”ı hakkında henüz fikrim yok.

Flappy Bird gibi başa dönmem umarım 🙂

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

Hala NodeJS Sevmiyorum

Bazen bir şarkı, çoğu her yerde çalar. Sonra unutulur gider. Hatırlamaya çalışınca, tam olarak hatırlayamayız. Ancak denk geldiğinde “Aa evet.. asdf..” deriz.

 

 

 

 

Bi ara pilli network’ten ceviz.net  forumlarına çoğu yerde Ruby (on-rail) popüler olmuştu. Sonra saman alevi gibi söndü gitti.

Bir öngörüde bulunmak istiyorum:
Belli bir azınlık haricinde genel için, NodeJS de bu şarkılar ve Ruby gibi bir gün zor hatırlanacak, “dilimin ucunda” denilecek.

StakOverflow

 

@hakancelik ve @tolgahanuzun  ne der bilmiyorum ama bir de dilekte bulunmak istiyorum:
NodeJS de bu şarkılar ve Ruby gibi, kaybolup gitsin lütfen. Bir an evvel.

-Bir dilde RETURN’ün doğru zamanda çalışmama ihtimalinden bahsedilebilir mi arkadaş?
-Callback var ki ama
-Yav He he 🙂

 

Neymiş, hız için ikinci işlem, birinciden de önce çalışabilirmiş.
E ama herkes;  ikincisi normal bi şekilde birinciden sonra çalışsın diye taklalar atıyor, hem sistemi hem kendini zorlayıp duruyor.

Çok güzel bir projeye NodeJs ile başladığımız için en azından yayınlanabilir ilk beta ayağa kalkana kadar böyle devam ederiz sanırım.. Ama belli ki NodeJs ile olan ilişkimiz, önce kavga edip sonra aşık olanlara hiç benzemeyecek. İlk fırsatta yollarımızı ayıracağız.

 

Anyway…

İlk kısımlar DIY sunucular için bilindik ama yine de NodeJS ile Kendi PC’mizi Sunucu olarak kullanmak için, -farklı aşamaları da barındıran- “Türkçe notlar” tadına bir yazı nette bulunsun 😉

===========

Modem’den Port Yönlendirme yapıyoruz.

80 Nolu porta gelen istekleri
kendi PC’mizin Local IP adresine (Örn: 192.168.1.55) yönlendiriyoruz.

İsim: UzakToLocal
Lan yönetici: 192.168.1.55
Wan port: 80
Lan port: 80

modemin PC’ye otomatik olarak verdiği Yerel IP adresini öğrenmek için
Başlat > cmd > ipconfig

Local Ip’nin otomatik değişmemesi için
Ağ ayarlarından, şu IP’yi kullan denilebilir.

=================================

Herhangi bir web sitesine bağlanır gibi uzaktan bağlanmak için
Whatismyip.com benzeri bi yerden public IP adresimize bakıyoruz

diyelim 74.85.175.126

Chrome adres satırına bu ip’yi yazdığımızda
kendi PC’mizi server olarak kullanmış,
ve Sitemize [ ? ;)) ] webten ulaşmış olacağız.

=================================

Yerel IP adresimizin sabit olmasından bağımsız olarak bi şekilde Modem açılıp kapandığında Public IP adresimiz değişeceği için
ve 74.85.175.126 yerine okunabilir bir Domain girmek için

dynu.com gibi servis’e üye olup client Programını kuruyoruz.
Login oluyoruz
https://www.dynu.com/en-US/ControlPanel/DDNS
adresinden ADD’e tıklayarak
Yeni bir Dynamic DNS Service oluşturuyoruz.

örneğin:
sg.theworkpc veya gercekdomain.com

indiriğimiz program arka planda bizim her yeni ip’mizi servise bildirdiği için her seferinde IP adresi yazmak yerine

http://sg.theworkpc.com/ adresine girdiğimizde
kendi sunucumuza ulaşmış olacağız.

======

Genelde NodeJs ile localhost isteklerine cevap verirken şöyle bir dinleme yapıyoruz
.listen(3000,function(){})

//Her yer gereksiz yere gerekli kılınan callback’lerle dolu olduğu için takılmaya gerek yok.
//Müsait zamanda Node’a bilahare kızarız 🙂

Bu dinleme yerine şu şekilde dinliyoruz:

..
app.listen(80,"0.0.0.0",function(){
console.log("Dinliyorum");
});

80 nolu portu dinliyoruz ve bunun üzerinden yanıt gönderiyoruz
//ki default web/http portu bu port
// http”S” için 443

IP olarak “0.0.0.0” yazma sebebimiz ise; Node’un dışarıdan gelecek isteklere de yanıt verebilmesi için

=================================

NodeJS’nin A-senkron çalışma fanatizisi ve callback tripleri ile vakit kaybetmek istemiyorsanız // ki hiç uğraşmayın gerekirse makinaya RAM ilave edin, işinize bakın. Kaybettiğiniz zaman ya da vereceğiniz maaştan kat-kat hesaplıya gelecektir.
Ki Bottle, Flask (Django) gibi; Daha iyisini, Daha keyifli olarak sunan teknolojiler mevcut 😉


görsel

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

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 😉