ESP8266 ile Mongoose OS Kullanımı
|Merhabalar,
Bu konuda günümüz popüler elektronik cihazlarından olan ESP8266′ nın Mongoose OS isimli Gerçek Zamanlı İşletim Sistemi (RTOS) ile kullanımına değineceğiz. Peki bu gerçek zamanlı işletim sistemi bizim ne işimize yarayacak. Kendi sayfasında da belirtildiği üzere Mongoose OS daha stabil çalışan IOT uygulamalarının daha az zaman harcanarak geliştirilmesini sağlamak için oluşturulmuş bir platformdur. Bu platform sayesinde birden fazla cihazı bir cloud altında birleştirebilir, uzaktan firmware güncellemesi yapabilir, cihazınızın pinlerini görüntüleyebilir ve bunun gibi bir çok işlemi tek web sayfası altından yapabilirsiniz. Ancak bu framework tamamen ücretsiz değil. İki cihazdan daha fazla cihazın cloud bağlantısını yapmak istiyorsanız aylık 5$ lık bir ücret ödemelisiniz. Ancak cloud kullanmayacaksanız istediğiniz kadar cihazı birbirine bağlıyabilir ve haberleştirebilirsiniz. Mongoose OS resmi olarak esp8266, esp32 ve TI’ ın bazı kartlarını desteklemekte. Ancak third party olarak farklı platformlarda da kullanılabilmekte. Bunların hepsinin yanı sıra uygulama geliştirmek için C++ kullanmak zorunda değilsiniz. Javascript kullanarak da uygulama geliştirebilirsiniz. Biz de bu konu içerisinde Javascript kullanarak uygulamamızı oluşturacağız.
Mongoose OS’ nin bir diğer avantajı da donanımdaki yazılımı güncellemek için ESP8266 gibi cihazlar için gereken reset durumuna ihtiyaç duymaması. İlk firmware’ i yükledikten sonra yazılım güncellemesini seri port üzerinden yada wifi üzerinden yapabilmektesiniz.
Öncelikle Mongoose OS’ nin araçlarını kuralım. Windows için basit bir executable’ dan ibaret. Linux’ da yada mac da paket kurulumu yapmanız gerekmekte. Kurulum adımlarına bağlantıdan ulaşabilirsiniz. Burdan sonra bağlantıdaki github reposunu indirmeniz gerekli. Bu repoyu referans seçip ayarlamaları üzerinden yapacağız.
Ayarlamaları yapmaya “mos.yml” dosyasından başlayacağız. Bu dosyada kullanılacak olan kütüphaneleri ve işletim sisteminin kullanacağı bazı değişkenleri ayarlayacağız. Bu değişkenler wifi şifresi, mqtt bağlantı bilgileri gibi değişkenlerdir.
Kullanacağımız kütüphaneler Wifi, MQTT, UART, DHT ve Javascript kütüphaneleridir. Bu kütüphaneleri “mos.yml” dosyasının içerisindeki libs etiketi ile başlayan kısma eklemeliyiz. Konfigurasyon işlemlerini ise config_schema ile başlayan etiketten sonra eklemeliyiz. Kullanacağız bazı repolarda bu olmayabilir. Sayfanın diğer etiketleri ile çakışmayan boş bir yerine ekleyebilirsiniz. Ayarlamaları yapmaya başlayalım. İlk olarak eklenecek kütüphaneler:
- origin: https://github.com/mongoose-os-libs/rpc-mqtt # mqtt support - origin: https://github.com/mongoose-os-libs/dht # dht library support - origin: https://github.com/mongoose-os-libs/mjs # javascript library support - origin: https://github.com/mongoose-os-libs/wifi # wifi support
Görüldüğü üzere kütüphaneler Github üzerindeki bağlantılardan çekilmekte. Yani siz bağlantıdaki Github hesabına projeniz için ihtiyacınıza göre daha bir çok kütüphane bulabilirsiniz. Bizim uygulamamız için bunlar yeterli.
İkinci olarak konfigurasyon ayarları. Burda sizin kendinize göre değiştirmeniz gereken ayarlar bulunmakta. Lütfen onları güncelleyin. Ancak güncellemeyi unutursanız yada yanlış yaparsanız yükledikten sonra da değişiklik yapabilirsiniz.
- ["device.id", "my-esp8266"] - ["app", "o", {title: "My app custom settings"}] - ["app.dhtPin", "i", 5, {title: "GPIO pin a DHT11 is attached to"}] - ["app.ledPin1", "i", 2, {title: "GPIO pin a LED is attached to"}] - ["app.btn", "i", 15, {title: "GPIO pin a BUTTON is attached to"}] - ["mqtt.server", "broker.shiftr.io:1883"] # MQTT broker olarak shiftr.io kullandık - ["mqtt.enable", true] - ["rpc.mqtt.enable", true] - ["mqtt.user", "********MQTT USERNAME********"] - ["mqtt.pass", "********MQTT Pass********"] - ["wifi.ap.enable", false] - ["wifi.sta.enable", true] - ["wifi.sta.ssid", "********Wifi SSID********"] - ["wifi.sta.pass", "********Wifi Pass********"]
Bu kısımda WiFi ve MQTT ayarları dışında bazı GPIO’ ları belirledik. Bu tamamen yazılımın daha düzenli gözükmesi için yapılan bir şeydir. İsterseniz yazılım içerisinde normalde yaptığımız gibi kullanılacak GPIO’ ları belirleyebilirsiniz.
Şimdi sıra geldi yazılım dosyamızı oluşturmaya. Yazılım için Javascript kullanacağımızdan src klasörü ile işlem yapmayacağız. Onun yerine fs klasörü ile işlem yapacağız. Bu klasörde web sayfaları ve javascript dosyaları barındırılmakta. Ancak örnek projemiz boş olduğu için içerisinde sadece boş bir html dosyası mevcut. Bizim bunun yanına bir tane init.js isimli bir dosya oluşturmamız gerek. İsmin doğru olduğuna emin olmalısınız. Aksi taktirde yazılımınız çalışmayacaktır.
Uygulamamızda bir buton bir buton bir DHT11 ve bir led olsun. Her butona basılınca DHT11 sensörün verisini MQTT ile bilgisayardaki bir düğüme göndersin. Ayrıca ledi 2 saniye aralıklarla yakıp söndürsün. Bilgisayardan gelen veriye cevap olarak da sürekli olarak sıcaklık verisini göndersin.
Bağlantı şemamız aşağıdaki gibi olmalı…
Yazılım için ilk olarak kütüphanelerimizi ekleyelim.
load('api_config.js'); //cfg parametreleri load('api_rpc.js'); load('api_dht.js'); //dht kütüphanesi load('api_timer.js'); //timer kütüphanesi load('api_gpio.js'); //gpio kütüphanesi load('api_mqtt.js'); //mqtt kütüphanesi
Daha sonra kullanacağımız pinlerin tanımların yapalım. Bu kısımda hem Config dosyasından pinlerin nasıl çekildiğini hemde yazılım içerisinde pin nasıl tanımladığını görebilirsiniz.
let pin = Cfg.get('app.dhtPin'); //config dosyasından dhtPin i çek let led1 = Cfg.get('app.ledPin1'); //config dosyasından ledPin1 i çek let led2 = 13; //led2 yi 13 numaralı pinde kullan let btn = Cfg.get('app.btn'); //config dosyasından buton pinini çek let dht = DHT.create(pin, DHT.DHT11); //dht11 sınıfını oluştur GPIO.set_mode(led1, GPIO.MODE_OUTPUT); //led1 çıkış GPIO.set_mode(led2, GPIO.MODE_OUTPUT); //led2 çıkış GPIO.set_mode(btn, GPIO.MODE_INPUT); //buton giriş
Pinlerin ayarlamalarını yaptıktan sonra buton ayarını yapalım. Burada butonu kesme(interrupt) ile kullanacağız. Böylece yazılım içerisinde sürekli olarak kontrol etmemiz gerekmeyecek.
GPIO.set_button_handler(btn, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 50, function(x) { let topic = Cfg.get('device.id') + '/button_pressed'; //topic ismi let message = JSON.stringify({"temp": dht.getTemp(), "hum": dht.getHumidity()}); //gönderilecek mesaj GPIO.toggle(led2); //her butona basılınca ledin durumunu değiştir let ok = MQTT.pub(topic, message, 1); //mqtt ile veriyi gönder print('Published:', ok ? 'yes' : 'no', 'topic:', topic, 'message:', message); //konsola veriyi yazdır }, true);
Butonun kullanımı başta size biraz karmaşık gelebilir. Ancak oldukça basit. Fonksiyonda kullanılan parametreleri tek tek inceleyecek olursak:
-
GPIO.PULL_UP : Butonu bağlı olduğu pindeki iç direnci (PULL UP direnci) aktif et
-
GPIO.INT_EDGE_NEG : Kesmeyi düşen kenarda tetiklenecek şekilde ayarla
-
50 : butona basılınca oluşan bounce time olarak adlandırılan kararsız zaman geçene kadar yeni kesme alma( 50 ms boyunca)
Peki bu parametreleri değiştirmek isterseniz onları nereden bulabilirsiniz? Onun içinde GPIO kütüphanesinin bulunduğu github sayfası size yol gösterecektir. Ancak geniş bir dökümantasyon ile açıklamaması bulunmamakta. Yada ben henüz bulamadım.
Sıra geldi Timer’ ımıza. Mongoose OS kullanarak bir çok farklı zamanlı işlem gerçekleştirebilirsiniz. Bu yapı Javascript’ teki setInterval fonksiyonuna oldukça benzerdir. Ancak bunlar asenkron değillerdir. Yani ikinci Timer’ ın çalışması için ilkinin işini bitirmiş olması gerekir. Biz Timer’ ımızın içinde sıcaklık değerini iki saniyede bir yazdıralım ve dahili led olan GPIO2′ ye bağlı ledi 2 saniyede bir yakıp söndürelim.
Timer.set(2000, true, function() { print('Temperature:', dht.getTemp()); GPIO.toggle(led1); }, null);
Son olarak ta RPC (Remote Procedure Call) işlevini ekleyelim. Bu fonksiyonun kullanımı zorunlu değildir. Bu fonksiyon Mongoose OS üzerinden kullandığınız donanıma komutlar göndermenizi sağlar. Bu gönderdiğiniz komutlar ile donanımınızı yönetebilir yada donanım üzerindeki verileri görebilirsiniz. Aşağıda bu servisin seri port ile kullanımını görebilirsiniz.
mos --port /dev/ttyUSB0 call Sum '{"a":1, "b": 2}'
Bu servisin çalışması için cihaz içerisinde bulunması gereken örnek yazılım ise şu şekildedir.
RPC.addHandler('Sum', function(args) { return args.a + args.b; });
Peki bu ne işimize yarıyacak? Bu şekilde iken çok fazla işlevli değil elbet. Sadece bazı kontrolleri hızlandırmış olursunuz. Ancak bu sisteme cihaz IP’ si üzerinden de erişebilirsiniz. Bunun için mos executable ile çalıştıracağınız komutu aşağıdaki gibi değiştirmeniz gerekli
mos --port ws://192.168.0.206/rpc call Sum '{"a":1, "b": 2}'
Böylece local ağdan rahatlıkla RPC servis ile tanımlanmış verileri çekebilirsiniz. Biz uygulamamızda DHT’ nin okuduğu sıcaklık verisini çekmek istersek yazılımı şu şekilde düzenlememiz yeterlidir.
RPC.addHandler('Temp.Read', function(args) { return { value: dht.getTemp() }; });
Mongoose OS aslında bir çok özelliğe daha sahip. Ancak ben bazılarında anlam veremediğim sorunlar yaşadım. Bunun sebebinin ESP8266′ dan kaynaklı olduğunu düşünüyorum. ESP32, CC3220 gibi gelişmiş kartlarda bu sorunların yaşanacağını çok düşünmüyorum. Ancak o kartlarda henüz deneme yapmadım.
Son olarak bu MQTT üzerinden bilgisayardan alan bir nodejs uygulaması yazalım. Onun üzerinde çok fazla durmayacağım. Bir çok örneği önceki konularda bulunmakta…
var mqtt = require('mqtt'); var name = "***TOKEN NAME***"; var pwd = "****TOKEN PSWD***"; var client = mqtt.connect('mqtt://' + name + ':' + pwd + '@broker.shiftr.io', { clientId: 'home-pc-sub' }); client.on('connect', function(){ console.log('client has connected!'); client.subscribe('/my-esp8266/button_pressed'); //bağlanılan topic adı console.log("Connected!"); }); client.on('message', function(topic, message) { console.log('new message:', topic, message.toString()); });
Yazılımımızın sonuna geldik. Yazılımların tamamına bağlantıdan ulaşabilirsiniz.
Biraz hızlı yazılmış olduğu için çok fazla şeyden bahsedemedim, ancak Mongoose OS’ ye genel olarak bakışım olumlu ve ESP8266 gibi cihazlar için Arduino Ide’ si oluşturulacak yazılımlara göre çokca artısı var. Sadece ADC modülü kullanılırken dikkat edilmeli. Çünkü ESP8266 ile çok sağlıklı çalışmadığını gözlemledim.
İyi çalışmalar dilerim…