Yine bir yazı ile karşınızdayım. Bu sefer adını sık sık duymaya başladığım, yavaş yavaş merak ettiğim hatta kullanmam gerektiğini düşündüğüm MQTT ile ilgili bir şeyler paylaşacağım inşallah.

MQTT Nedir?

Bu sorunun cevabını öğrenmek için tabi ki kaynağını incelemek lazım. Yani http://mqtt.org/ adresinden mevzunun ne olduğu ile ilgili olduğu cevabı bulabilirsiniz. Tabi kaynak İngilizce olduğundan sıkıntılı arkadaşlar buradan Güray arkadaşımızın yazmış olduğu kaynağı inceleyebilir.

Ben MQTT’den ne anladım diye sorarsanız, şöyle derim; IoT ve M2M(Machine to Machine/Makineler arası) uygulamalar için günümüz gereksinimlerini de karşılayan biçilmiş kaftan bir mesajlaşma protokolüdür. Yani küçük elektronik cihazların aralarında ağ kurup konuşmasına olanak sağlar. Ağ kurmak deyince bildiğiniz gibi çeşitli wifi/ethernet/gsm vb. donanımlar ile elektronik devrelerimiz arasında ağ kurup haberleştirebiliriz. Ama bunlar IoT, M2M tarzı uygulamalar için pahalı, çok güç harcayan, birebir örtüşmeyen vs. teknolojiler olduğu için günümüzde benzer alternatif sistemler, protokoller vs. geliştirilmiştir. Örneğin ZigBee, 6LowPAN vs. MQTT’ye benzer yapılardır. Ancak TCP/IP üzerinde çalışabildiğinden, çok veri tüketimi gerektirmediğinden, iletişim şartlarının kötü olduğu ortamlarda güvenli çalışmasından dolayı gibi özelliklerinden ve IoT, M2M gibi terimlerin adının sık duyulmasından dolayı popüler hale gelmiştir/gelmektedir. Aynı zamanda internet üzerinde kısa bir araştırma ile Türkçe yada yabancı dillerde bir çok kaynak bulabilirsiniz.

Güncel bir örnekle konuyu toparlamak gerekirse; Elinizde 2 adet arduino(yada 1 arduino 1 NodeMCU) var ve bunların birisi bir sıcaklık değerini ölçüp diğerine kablosuz olarak göndersin diyelim. Bu işlemi yapmak için bildiğiniz gibi Arduino için RF, Wifi bir çok yardımcı kartlar mevcuttur. Bu yardımcı kartlardan birisini seçerken pek tabi maliyet, uygulanabilirlik, veri güvenliği, veri kullanımı, fiziksel şartlar vs. gibi bir çok kriteri göz önünde bulundurmak gerekir. Bu noktada güç tüketimi açışından olmasa da MQTT’yi seçebilirsiniz. Arduino kartlarınız ile birlikte WiFi, Ethernet, GSM vs. gibi yardımcı kartlar kullanarak TCP/IP üzerinden MQTT protokolü ile istediğiniz haberleşmeyi güvenli bir şekilde düşük veri tüketimi ile yapabilirsiniz. Hemde havalı olur! Mevzu özetle 3 aşağı 5 yukarı budur.

MQTT Yapısı

MQTT

Şekil-1

Verdiğim linklerden yada internetten araştırıp öğrendiyseniz bileceğiniz gibi MQTT yapısı temel olarak MQTT clients(İstemciler) ve MQTT Broker(Muhtar da diyebilirsiniz.) denen yapıdan oluşur. Burada istemciler aralarında haberleşmek isteyen birimlerdir. Örneğimizdeki gibi Arduino kartlar mesela. Broker ise bu haberleşmeyi sağlayan, veri gönderilmesini vs. garanti eden tabiri cahizse muhtar gibi bir şeydir. Sonuç olarak her ikisi de Belirli bir donanım üzerinde çalışan programlardır. Geçenki örnekte iki arduinoyu haberleştirmek için hiç Broker kullanmadık buda nereden çıktı diyebilirsiniz haklı olarak. Bende adamlar yapmış, bir yerden kazanırken bir yerden de kaybetmek gerekebilir derim. MQTT protokolünde, birbirine mesaj göndermek/almak isteyen istemciler gönderecekleri mesajları yada istekleri Broker’a gönderirler. Broker ise bu istekleri yerine getirip haberleşmeyi sağlar.

Şekil-1’de yapmış olduğum örnek uygulamanın çalışma görüntüsü görülmektedir. Kartlardan soldaki Arduino MKR1000 diğeri ise ESP8266 temelli NodeMCU kartıdır. Burada Arduino, devre üzerinde bulunan 3 tane LM35 sıcaklık sensörü bilgilerini yayınlamak sureti ile Brokere gönderir. Publish eder yani. Mesajların gönderildiği yayınlara topic adı verilir. Mesela Sensor1 topici, meselesi gibi, Meselenin adı budur. Meseleden haberdar olmak isteyen kartlar abone olurlar. Subscriber, yani üye olurlar. Sonrasında publisherlar yayınlar topiclerini, meselelerini, ilgilenen aboneler ile o topice abone olarak gelen bilgileri Broker üzerinden alırlar. Pek tabi ki bir yayınlayıcıyı aynı zamanda abonede olabilir.

Diğer kısımda ise abone olarak NodeMCU kartı bulunmaktadır. NodeMCU ise bu yayınlanan 3 tane topice abone olarak meseleden haberdar olur, sıcaklık değerini alır. Aldığı sıcaklık değerlerini görüntüleme amaçlı uart üzerinden bilgisayara gönderir. Yani özetle istemcilerde çok işlem yükü olmaz çok uğraşmazlar verinin gidip gitmediği ile uğraşmakla vs. Çünkü bu işleri yüklenen Broker vardır!

Broker Nedir?

Broker, benim bildiğim Türkçe anlamı ile Borsacı, simsar vs. gibi anlamlara gelmektedir. Sonuç olarak dediğim gibi Brokerda bir programdır. Peki hangi donanım üzerinden çalıştıracağız bu programı? Bildiğiniz gibi öncelikle donanımızın Broker olarak çalışabilmesi için TCP/IP protokolünü destekleyen Ethernet, WiFi, GSM gibi yardımcı birimleri olması gerekir. Özetle ben internette araştırıken gördüğüm kadarıyla genel olarak Broker olarak Raspberry Pi tarzı kartlar ve kişisel bilgisayarlar kullanılıyor. MQTT Broker programı olarak ise tek denk geldiğim(fazla araştırmadım.) program Mosquitto programıdır. Mosquitto ile istemcileriniz arasındaki haberleşmeyi sağlayabilirsiniz. Aynı zamanda Mosquitto paketi içerisinde deneme yapma amaçlı yayınlayıcı ve abone programlarıda bulunmaktadır. Yani sadece kendi bilgisayarınız üzerinde Mosquitto programlarını kullanarak MQTT uygulaması yapabilirsiniz. Ben bu uygulamada Mosquitto programını çalıştırmak için Ubuntu yüklü olan bilgisayarımı kullandım. Aynı zamanda internet üzerinde Arduino, NodeMCU gibi kartlar yada Android telefonları, tabletleri vs. Broker olarak kullanabilir miyim diye, bunu için mosquitto yada benzer bir program, kütüphane vs. var mı diye küçük bir arştırma yaptım. Fakat bir sonuç elde edemedim. Özetle şuanda en makül çözüm benim gördüğüm Wifi desteiği olan Raspberry pi tarzı bir kart kullanmaktır. Bu arada Mosquitto bir çok işletim sistemi üzerinde çalışabilmektedir. Yine internette küçük bir araştırmayla, Mosquitto ile ilgili bir çok kaynağa kısa sürede ulaşabilirsiniz.

Şekil-2

Şekil-2’de Mosquitto Broker programının Ubuntu yüklü bilgisayarımda çalışması görülmektedir. Bu arada Mosquitto konsol uygulamasıdır. Yani janjanlı, kullanıcı dostu bir ara yüzü yoktur. Şekil-3’ü detaylı incelerseniz Brokerın çalışmasına ait, yayınların, aboneliklerin nasıl yapıdlığı, gelen giden mesaj topicleri gibi detaylar hakkında bilgi sahibi olursunuz. Bu arada gerek kendi bilgisayarım gerekse istemci Arduino ve NodeMCU kartları WiFi donanımları sayesinde aynı WLAN ağına bağlıdır. Yani hepsi aynı lokal ağdadır. Bu aşamadan sonra Broker’ı Ubuntu üzerine çalıştırıp istemcilere yoğunlaşabiliriz.

MQTT İstemciler

Daha öncede bahsettiğim gibi istemciler ya topicler halinde mesaj yayınlarlar yada yayınlanan mesajlara abone olurlar. Ben uygulumanın kolay olması açısından Arduino’yu yayınlayıcı yaptım. NodeMCU’yu ise abone. Tam terside olabilir. Elimde bu iki kart olduğu için bunları kullandım. Yani Arduino 3 adet sıcaklık bilgisini okuyup yayınlar. NodeMCU ise bu yayınlara abone olarak sıcaklık bilgilerini alıp uart üzerinden gönderir. Senaryo çok basit. Çok tabi aynı işlem bir çok yöntemle yapılabilir.

Arduino MQTT Kütüphanesi

Bildiğiniz gibi NodeMCU Arduino uyumlu olduğu için Arduino için hazırlanan kütüphaneler NodeMCU üzerinde de çalıştırılabilir. Arudino ile ilgili MQTT istemci kütüphanesi ararken bir kaç seçenekle karşılaştım. Bir kaç denemeden sonra elimdeki iki kart ile sorunsuz çalışan arduino-mqtt kütüphanesinde karar kıldım. Kütüphane dosyalarına github projesi halinde buradan ulaşabilirsiniz. Kütüphaneyi Arduino sketch üzerinde bulunan kütüphane yöneticisi ile otomatik yükleyemediğim için github üzerinden zip halinde indirip yükledim. Sonrasında içerisindeki örneklerden de faydalanarak örnek kodlarımı yazdım.

/****************************************************************************
* Author:      Erhan YILMAZ                                                 *
* Application: MQTT Test application(Publisher)                            *
* Date :       02.08.2016                                                   *
* Version :    1.0                                                          *
* Description: It is a publisher part of a mqtt test application            *
* which is works with arduino mkr1000.                                      *
* It gets 3 channels temp values with LM35 sensors then send values         *
* as topics to subscribers.                                                 *
* As broker mosquitto used on Ubuntu based pc.                              *
* MQTT deneme uygulaması                                                    *
* Gilberto Conti tarafından yazılan MQTT kütüphanesi kullanılmıştır.        *
* https://github.com/256dpi/arduino-mqtt buradan kütüphaneye erişilebilir.  *
* Uygulama MQTT client olarak çalışıp LM35 sıcaklık sensörlerinden ölçtüğü  *
* değerleri topicler halinde yayınlamaktadır(Publish).                      *
****************************************************************************/
 
// Libraries
#include <SPI.h>
#include <WiFi101.h>
#include <MQTTClient.h>
 
// Wifi info
char *ssid = "SSID_NAME";
char *pass = "SSID_PASS";
 
WiFiClient net;
MQTTClient client;
 
unsigned long lastMillis = 0;
 
// Setup for used modules/libraries(ADC,Uart,MQTT,WIFI)
void setup()
{
  Serial.begin(115200);
  analogReference(AR_INTERNAL1V0);
  analogReadResolution(12);
  WiFi.begin(ssid, pass);
  // Use your Broker ip address
  client.begin("192.168.1.8", net); // Begin client with broker Ip and wifi client
 
  connect();
}
 
void connect()
{
  // Connect to wifi
  Serial.print("checking wifi...");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(1000);
  }
 
  // Connect to broker
  Serial.print("\nconnecting...");
  while (!client.connect("arduinoPub", "try", "try"))
  {
    Serial.print(".");
    delay(1000);
  }
 
  Serial.println("\nconnected!");
 
  // client.subscribe("/example");    // No subscription for any topic
  // client.unsubscribe("/example");  // No unsubscription aswell
}
 
void loop() 
{
  char temp[50];
 
  client.loop();
 
  if(!client.connected()) 
  {
    connect();
  }
 
  // publish a messages roughly every 5 seconds.
  if(millis() - lastMillis > 5000) 
  {
    lastMillis = millis();
    int sensorValue = analogRead(A0);
    float temperature = sensorValue / 40.96;
    sprintf(temp,"%.2f°C", temperature);
 
    // /sensors/temp1 topic for temp sensor 1
    client.publish("/sensors/temp1", temp);
 
    sensorValue = analogRead(A1);
    temperature = sensorValue / 40.96;
    sprintf(temp,"%.2f°C", temperature);
    // /sensors/temp2 topic for temp sensor 2
    client.publish("/sensors/temp2", temp);
 
    sensorValue = analogRead(A2);
    temperature = sensorValue / 40.96;
    sprintf(temp,"%.2f°C", temperature);
    // /sensors/temp3 topic for temp sensor 3
    client.publish("/sensors/temp3", temp);
  }
}
 
void messageReceived(String topic, String payload, char * bytes, unsigned int length) 
{
  // Callback function for subscriptions
}
/****************************************************************************
* Author:      Erhan YILMAZ                                                 *
* Application: MQTT Test application(Subscriber)                            *
* Date :       02.08.2016                                                   *
* Version :    1.0                                                          *
* Description: It is a subscriber part of a mqtt test application           *
* which is works with NodeMCU(ESP8266).                                     *
* It subscribes to "/sensors/#" topic to get all messages under /sensors/   *
* As broker mosquitto used on Ubuntu based pc.                              *
* MQTT deneme uygulaması                                                    *
* Gilberto Conti tarafından yazılan MQTT kütüphanesi kullanılmıştır.        *
* https://github.com/256dpi/arduino-mqtt buradan kütüphaneye erişilebilir.  *
* Uygulama MQTT client olarak çalışıp /sensors/ altında gelen topiclerde ki *                    
* mesajları almaktadır(Subscribe). Alınan mesajları uarttan pcye gönderir.	*
****************************************************************************/
 
// Libraries
#include <ESP8266WiFi.h>
#include <MQTTClient.h>
 
// Wifi info
const char *ssid = "SSID_NAME";
const char *pass = "SSID_PASS";
 
WiFiClient net;
MQTTClient client;
 
unsigned long lastMillis = 0;
 
// Setup for used modules/libraries(Uart,MQTT,WIFI)
void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, pass);
  // Use your Broker ip address
  client.begin("192.168.1.8", net); // Begin client with broker Ip and wifi client
 
  connect();
}
 
void connect()
{
  // Connect to wifi
  Serial.print("checking wifi...");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }
 
  // Connect to broker
  Serial.print("\nconnecting...");
  while (!client.connect("ESP8266Sub", "try", "try")) {
    Serial.print(".");
    delay(1000);
  }
 
  Serial.println("\nconnected!");
 
  client.subscribe("/sensors/#");   // Subscription for sensors
  // client.unsubscribe("/example");
}
 
// Main loop
void loop() {
  client.loop();
  delay(10); // <- fixes some issues with WiFi stability
}
 
// Send incoming topic messages over uart
void messageReceived(String topic, String payload, char * bytes, unsigned int length) {
  Serial.print("incoming: ");
  Serial.print(topic);
  Serial.print(" - ");
  Serial.print(payload);
  Serial.println();
}

Yukarıda gördüğünüzü gibi uygulama ile ilgili iki adet program bulunmaktadır. Her iki programda da arduino-mqtt kütüphanesi kullanılmıştır. Uygulamada dikkat edilmesi gereken Broker’ın kullandığı ip ve kullanılan port numarasıdır. Port numarası olarak genel geçer herkes 1883 protunu kullanmaktadır. Eğer herhangi bir ayar yapmadıysanız varsayılan port numarası 1883’tür. Keza arduino-mqtt kütüphanesindede varsayılan port 1883’tür. Bir kaç heryerde 1884 portununda kullanılabildiğine denk geldim. Aklınızda bulunsun. Diğer önemli husus ise ip adresi. Eğer istemciler borker’ın ip adresini doğru bilmezlerse farklı ip adresine bağlanmaya çalışırlarsa sorun yaşayabilir, saç baş yolabilirsiniz. Bu konulardan emin olmak lazım. Broker ip adresi Brokerin üzerinde çalıştığı donanımın ağdaki lokal adresidir. Yani benim Ubuntu yüklü bilgisayarımın WLAN üzerindeki Router/Modem tarafından verilmiş aotomatik adresi. Muhtemelen 192.168.x.x gibi bir adrestir.

Şekil-3

Şekil-3’te uygulamaya ait çalışmayı görebilirsiniz. Gördüğünüz gibi konsol üzerinde Brokerımız çalışmaktadır ve gelen giden trafikle ilgili logları konsol ekranına çıktı olarak göndermektedir. Açık olan uart terminalde ise abone NodeMCU tarafından alınan mesajlar görülmektedir. Sırasıyla /sensors/temp1, /sensors/temp2 ve /sensors/temp3 üç adında 3 adet topic yayınlamaktadır. Topiclere abone olmayı kolaylaştırmak için MQTT’de belirli bir notasyon kullanılmaktadır. Yani NodeMCU uygulama kodlarında da görebileceğiniz gibi, tek tek üç yayınada üyüe olmak yerine daha basit bir notasyonla /sensors/# notasyonu kullanılmıştır. Burada # diyez işareti ile /sensors/ yayını adı altında bulunan bütün topiclere abone olanulacağı belirtilmektedir. Benzer şekilde bir kaç ufak notasyon daha vardır. İnternette araştırarak kolayca öğrenebilirsiniz. Bizim uygulamamız için bu kadarı kafidir.

Özetle uygulamamız bundan ibarettir. Umut ediyorumki MQTT ile ilgili bazı sorulara cevap veren faydalı bir uygulama olmuştur. Uygulama ile ilgili dosyalara vs. buradan github projesi halinde ulaşabilirsiniz.

Böylelikle bir yazının daha sonuna gelmiş bulunuyoruz elhamdülillah. Gözümden kaçan herhangi bir hata varsa, öneri, görüş vs. yada bildirirseniz sevinirim. Faydalı olması dileğiyle, bir sonraki yazıda görüşmek üzere inşaallah…