ESP-NOW ile Haberleşme

Merhabalar,

Bu konuda Espressif firması tarafından kendi cihazları için üretilen bir haberleşme protokolü olan ESP-NOW’ u inceleyeceğiz. Öncelikle ESP-NOW’ un ne olduğu ile başlayalım. ESP-NOW, ESP cihazlarının Wi-Fi’ den bağımsız olarak haberleşmesini sağlayan bir haberleşme protokolüdür. Protokol düşük güçte çalışan 2.4Ghz cihazlara benzerlik gösterir. Haberleşme gerçekleşebilmesi için eşleşme gereklidir. Eşleşme sağlandıktan sonra eşler arası güvenli ve handshake gerektirmeyen haberleşme gerçekleştirilebilir. Eşler arasının yanı sıra çok cihaz arası haberleşmeyi de destekler. Hem tek yönlü hem çift yönlü iletişim ESP-NOW ile mümkündür. Espressif tarafından hazırlanan ESP-NOW’ u daha detaylı anlatan bir anlatım videosuna bağlantıdan ulaşabilirsiniz. Burada anlatılanları kısaca şu şekilde özetleyebiliriz:

  • Eşler arası ya da çoklu haberleşmeyi destekler
  • Hem tek yönlü hem çift yönlü haberleşme gerçekleştirebilir
  • Gönderilen her veri paketi 250 Byte’ a kadar veri taışyabilir
  • Şifreli ve şifresiz haberleşmeyi destekler
  • Protokol onay(acknowledgment) destekler
  • ESP-NOW ağında en fazla 20 cihaz olabilir
  • ESP-NOW ağında en fazla 10 şifreli haberleşme gerçekleştiren cihaz olabilir

Yukarıda verilen özelliklerden de anlaşılacağı üzere bir çok uygulamanızda ESP-NOW kullanarak ESP cihazları ile az maliyetli kablosuz haberleşen bir sistem oluşturabilirsiniz. Bu konuda anlatılan içerikde referans olarak bağlantıdaki site kullanılmıştır. Daha önceki konularda da belirttiğim üzere referans site içerisinde ESP32 ve ESP8266 hakkında bir çok içerik paylaşılmış. İncelemenizi tavsiye ederim. Biz bu konu içeriğini biraz değiştirerek gerçekleştireceğiz.

Yukarıdaki videoda verilen ESP-NOW’ da anlatılan tüm özellikler Arduino kütüphanesi tarafından sağlanamasa da Arduino ile yapılabileceklerde oldukça geniş. Bu konu içerisinde basit bir eşler arası iletişim örneği gerçekleştireceğiz. Sonraki konularda 2′ den fazla cihaz bulunması durumundaki haberleşmeyi gerçekleştireceğiz. Arduino ile ESP-NOW kullanırken kullanabileceğiniz fonksiyonlara bağlantıdaki sayfadan ulaşabilirsiniz. Bu fonksiyonlardan kullanacağımız bazı önemli fonksiyonlar aşağıdaki gibidir:

  • esp_now_init() => ESP-NOW için temel kurulumu gerçekleştirir. Bu fonksiyon çağrılmadan önce Wi-Fi kurulumu gerçekleştirilmiş olmalıdır.
  • esp_now_add_peer(MAC) => Parametre olarak aldığı MAC adresindeki cihaz ile eşleşir.
  • esp_now_send(MAC, data, len) => Parametre olarak MAC adresine sahip cihaza len uzunluğundaki data’ yı gönderir. Fonksiyonun dönüş değerine bakılarak veri alıcıya ulaşdı mı kontrolü gerçekleştirilebilir.
  • esp_now_register_send_cb(callback) => Parametre olarak aldığı fonksiyonu gönderme işleminden sonra çağırır. Callback fonksiyonun parametre olarak aldığı değere bakarak verinin alıcıya ulaşıp ulşamadığı kontrol edilebilir.
  • esp_now_register_rcv_cb(callback) => Veri alındığı zaman parametre olarak atanan callback fonksiyonu çağrılır.
  • esp_now_is_peer_exist(MAC) => parametre olarak aldığı cihaz adresi ile eşleşmiş mi kontrolü yapar. Zaten eşleşmiş ise true değer döndürür.

Bunların dışındaki diğer fonksiyonları yapacağımız uygulamada kullanmayacağız. O sebeple açıklama gereği duymadım. Merak ederseniz yukarıdaki bağlantıdan ulaşabilirsiniz.

Şimdi yapacağımız uygulamaya gelelim. Yapacağımız uygulamada iki adet ESP32 kullanarak haberleşme gereçekleştireceğiz. Master cihaz, Slave ile eşleşince Slave cihaz kendisine bağlı olan DHT11′ dn okuduğu sıcaklık ve nem bilgilerini Master cihaza gönderecek. Master cihaz da belirli aralıklar ile Slave cihaza LED yakıp söndürme komutu gönderecek. Yapacağımız uygulamada cihazlar eşleşmeyi otomatik olarak yapacaklar ve veriler bir kuyruk yardımıyla gönderilecek. Yapacağımız uygulamanın bağlantı şemasına bakalım.

Bağlantı şemasında Master ve Slave cihaz ayrı ayrı verilmiştir. Master ya da Slave cihazları olarak kendi ağ topolojinize göre şekillendirebilirsiniz. Eğer 2 cihazımız olacaksa bunları Master ya da Slave diye isimlendirmemize gerek yok. Birbinin MAC adreslerini elle yazarak, bu bu MAC adresine sahip cihaza veri gönder diyebiliriz. Benim oluşturduğum senaryoda Master etrafındaki cihazları tarayıp onlara otomatik olarak bağlanabilecek. Bu sebeple Master ve Slave diye ayrım yapma gereksinimi duydum.

Master Yazılımı

İki cihaz arasında haberleşme gerçekleşebilmesi için, olması gereken önemli bir nokta mevcut. ESP32 cihazlarının ESPNOW ile veri iletebilmesi için “station” modda olması gerekir. Aksi taktide station modda olmayan cihazdan veri göndermeye çalıştığınızda send komutu “ESP_ERR_ESPNOW_IF ” hatası döndürecektir. Ancak Slave cihazın taranarak bulunabilmesi için “access point” olması gerekecektir. Bu yine ESPNOW tarafından gerekmemektedir. Sadece Master etrafını taradığında çevresindeki cihazları ve cihazların MAC adresini görebilmesi için gereklidir. Yine elle veri gönderilecek MAC adresi girilirse herhangi bir ESP’ yi access point olarak ayarlamaya gerek kalmaz. Sonuç olarak Master cihaz sadece access point olması gerekirken, Slave cihaz hem access point hem de station olması gerekecektir. Master etrafı tarayıp Slave’ lere veri göndermeyi başlayacağı için station olması yeterlidir. Çünkü eşleşip veri gönderdiğinde Slave onun MAC adresini öğrenecektir. Bu kısmı anlaması ilk başta zor olabiliyor. Ancak uygulmayı yaparken daha net anlaşılacağını düşünüyorum. Başta benimde oturtmam çok kolay olmadı.

Şimdi gelelim yazılım kısmına. Öncelikle Master’ ın yazılımının setup kısmından başlayalım. İlk olarak ESP32′ yi ESPNOW ile veri gönderebilmesi için station mod’ a alıyoruz.

Daha sonra ESPNOW kurulumunu yapmalı ve çevredeki cihazları taramalıyız. Tarama işleminin en az 1 slave bulunana kadar yapmalıyız ki eğer Slave cihaz ilk taramada bulunumazsa tekrar tarasın. Bu yüzden bu işlemi bir döngü içerisinde yapmalıyız.

Daha sonrasında bulduğumuz slave cihaz ile eşleşmeliyiz. Böylece Master cihaz veri göndermeye hazır hale gelecektir. Eşleşmediğiniz cihazlara veri gönderemezsiniz. Bu sebeple burası da yazılımda önemli bir noktadır.

Genel ayarlama işlemlerimiz bu kadar. Şimdi yukarıda kullandığımız ScanForSlave fonksiyonun içerisine bakalım. Bu fonksiyon çevredeki Slave cihazları tarıyor demiştik. Peki ya bunu nasıl yapıyor. Aslında etrafdaki tüm Wi-Fi cihazlarını tarıyor. Sadece bizim ismini Slave ile başlayan bir şey koyduğumuz cihazlar ile eşleşebilmek için onların MAC adresini kayıt ediyor. Fonksiyonun içerisine bakalım.

Yukarıda verilen fonksiyonda da görüldüğü üzere öncelikle yakındaki WiFi cihazları tarıyoruz. Daha sonra da taranan cihazların SSID’ lerine bakarak “Slave” ile başlıyor mu diye kontrol ediyoruz. SSID içerisinde Slave olup olmadığı kontrolü “if (SSID.indexOf(“Slave”) == 0)” satırında gerçekleştirilmektedir. Eğer SSID’ si Slave ile başlıyorsa MAC adresini kayıt ediyoruz. Böylece bir sonraki aşamada bu MAC adresi ile eşleşeceğiz.

Bu fonksiyonun dışında 2 adet de Callback fonksiyonu mevcut. Bunlardan bir tanesi veri gönderildiği zaman çalışan, diğeri ise veri alındığı zaman çalışan callback fonksiyonlarıdır. Bu fonksiyonları içeriği oldukça basit. Veri geldiği zaman çalışan “OnDataRecv” fonksiyonu, gelen verileri Seri portta yazdırıyor. Veri gönderildiği zaman çalışan “OnDataSent” fonksiyonu ise veri alıcı adrese ulaşıp ulaşmadığını kontrolünü yapıp Seri portta bildirimini yapmaktadır. Konunun fazla uzamaması için bu fonksiyonları daha fazla açmayacağım.

Son olarak master yazılımında veri gönderme işlemine bakalım. Veri gönderimi referans konudaki gibi struct olarak yapacağız. Veriyi struct olarak tanımlayıp göndermek ile dizi şeklinde göndermek aslında aynı şeyler. Sadece Struct olarak gönderirken farklı veri tiplerini göndermek daha kolay oluyor. Ben Struct içerisinde biraz değiştirip aşağıdaki gibi yaptım.

Struct içerisinde bulunana led_state bool değişkeni her veri gönderilmesinden sonra değeri değiştirilecek. Böylece slave tarafta bu değere bakılarak bir LED’ i yakıp söndüreceğiz. İkinci değişken olan message dizisi ise tamamen keyfi oluşturulmuş bir string’ dir. Bu değişkeni kullanarak Slave cihaza string veri göndereceğiz. Veri gönderme işlemi aşağıdaki şekilde yapılacaktır.

Eğer siz struct yerine tek bir değişken göndermek isterseniz bu ifadeyi şu şekilde değiştirebilirsiniz. ESP NOW ile veri göndermek için göndermek istediğiniz değişkeni uint8_t dizisi şeklinde ifade etmeniz yeterli olacaktır. Ancak verinin toplam boyutunun 250 byte’ ı geçmemesi gerektiğini unutmayın.

Master cihazın yazılımının tamamına bağlantıdan ulaşabilirsiniz.

Slave Yazılımı

Master tarafı bitirdiğimize göre sıra geldi Slave tarafa. Bu tarafta işler yine aynı karmaşıklı olacaktır. Eğer Master tarafını anladı iseniz burada da zorlanmayacaksınızdır diye düşünüyorum. Yine setup fonksiyonu içerisinden başlayalım.

Verilen yazılımda da görüldüğü üzere öncelikle ESP cihazı hem access point hem station moduna alıyoruz. Daha sonrasında Acces point SSID’ sini “Slave_1” olarak değiştiriyoruz. Bu tam olarak Master cihazda arayacağımız SSID kuralına uygun bir SSID’ dir. Daha sonrasında ESP NOW kurulumunu yapıp veri geldiğinde çalışması için callback fonksiyonunu ayarlıyoruz.

Slave tarafında veri gönderebilmek için öncelikle Master ile eşleşmemiş gerekir. Slave cihaz, Master ile eşleşebilmesi için Master’ ın MAC adresini biliyor olması gerekir. Master cihazın MAC adresini elle Slave cihaza girmemişsek, Slave cihaz aldığı veri paketinde, gönderen MAC adresine bakarak Master cihazın MAC adresini kayıt edebilir. Biz bu yöntemi kullanarak veri gönderme işlemini gerçekleştireceğiz. Bu işlemi “OnDataRecv” fonksiyonunun içerisinde aşağıdaki gibi gerçekleştireceğiz.

Verilen yazılımda da görüldüğü üzere veri alınan cihazın MAC adresi ile eşleşildimi sorgusu yapılıp, eğer eşleşilmedi ise peer info struct’ ı içerisine kayıt edilyor. Daha sonrasında kayıtlı peer sayısına bakarak, eğer 0′ dan büyükse kayıtlı peer’ lere veri göndereceğiz. Bu uygulamada 1 Master 1′ de Slave cihaz olduğu için eşleşen peer sayısı en fazla 1 olabilecektir. Ancak daha fazla olduğu durumlar için yazılımda değişiklik yapılabilir.

Yazılımın loop kısmında ilk olarak Slave cihaz eşleşdi mi kontrolü anlamak için peer sayısına bakıyoruz. Eğer peer sayısı 0′ dan büyükse peer listesinin en üstündeki cihaz bilgilerini çekip peerInfo struct’ ına atıyoruz. Aslında bunu yapmamıza gerek yok. Çünkü veriyi aldığımız callback içerisinde veri geldiği zaman zaten veriyi aldığımız cihazın bilgilerini peer struct’ ına atadık. Ancak 1′ den fazla veri gönderen cihaz olması durumunda işlemler bu şekilde gerçekleştirilmelidir. Bunun dışında son olarak Slave cihazdan Master’ a göndereceğimiz struct yapısına bakalım.

Slave cihaza bağladığımız DHT11 verisini ve potansiyometred okduğumuz gerilim verisini Master cihaza göndereceğiz. Bunun için yukarıdaki gibi bir struct oluşturduk. Master’ da olduğu gibi buradaki struct’ ın amacı farklı veri tiplerindeki veriyi tek seferde kolayca göndermektedir. Tek veri tipinde veri gönderecekseniz struct kullanmak zorunda değilsiniz. Yazılımın tamamında, Master ve Slave’ de ayrı ayrı verilen struct’ ların ikiside kullanılıyor. Bunun sebebi veriyi gönderen ve alan tarafta doğru şekilde veriyi ayırabilmek için bu veri yapılarını bilmesi gerekmesidir.

Uzun bir konunun daha sonuna geldik. İçerik çok detaylı olduğu için konu içeriği de uzun oldu. Başlangıç için referans kaynağı kullanmanızı tavsiye ederim. Burada anlatılanlar onun bir kademe sonrası için daha uygun. Ancak çok zor şeyler değiller mantığı anlayınca. İlerleyen zamanlarda ESP cihazlarındaki bir diğer haberleşme teknolojisi olan ESP-MESH hakkında da konu içeriği oluşturmaya çalışacağım.

Master cihazın yazılımının tamamına bağlantıdan ulaşabilirsiniz.

Projenin github sayfasına bağlantıdan ulaşabilirsiniz.

İyi çalışmalar dilerim…

Add a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir