42

ESP8266 ve STM32 ile MQTT Protokolünün Kullanımı

IOT

Bu yazıda IOT projelerinde sıklıkla kullanılan MQTT protokolüne ve  ESP8266 modülü ile nasıl kullanılabileceğine değineceğim. Öncelikle MQTT nedir ve nasıl çalışır bir bakalım.

MQTT (Message Queuing Telemetry Transport)

IOT uygulamaları için mükemmel bir çözüm olarak görülen MQTT basit bir haberleşme protokolüdür. MQTT internete bağlı olan bir cihazın çıkışlarını kontrol etmek için veri göndermeye veya sensor vb. girişlerden ölçülen  verileri diğer cihazlara göndermesine olanak sağlar. Bu nedenle birden fazla cihaz arasında iletişim kurmayı kolaylaştırır. Bu yüzden M2M(machine to machine) ve IOT(internet of things) uygulamaları için tercih sebebidir.

MQTT Kavramları

  • Publish/Subscribe
  • Message
  • Topic
  • Broker

İlk değineceğim kavramlar publish ve subscribe kavramlarıdır.

Publish; Bir cihazın yayın yapması yani veri göndermesidir.

Subscribe; Bir cihazın abone olması anlamına gelir. Cihazların veri alabilmesi için kullanılır. Kısaca bir cihaz mesaj gönderecek ise publish yani yayın yapar. Eğer komut alacak ise subscribe yani abone olur.

Mesaj; Cihazlar arasında gönderilen verilerdir.

Topic; Mesajların kimden geldiği veya hangi cihazlara iletileceği topiclere göre belirlenir.

Broker; Tüm bu haberleşmeyi yöneten birimdir. Öncelikle tüm mesajları almak ve bu mesajların hangi cihazları ilgilendirdiğini belirlemek ve ilgili cihazlara yayın(publish) yapmaktan sorumludur. Broker için mosquitto vb. belirli yazılımlar bulunmaktadır. Daha iyi anlayabilmek için aşağıdaki görselden yaralanabiliriz.

Yukarıdaki görselde görüldüğü gibi üç farklı cihaz brokera bağlanmıştır. Burada Broker bir bilgisayarda veya bulut sisteminde çalışan bir yazılım olabilir(örneğin;Mosquitto ve CloudMQTT). Görselde telefon ve bilgisayar “temperature” isimli topic’e abone olmuştur. Sensör ise “temperature” topic’ine yayın yapmaktadır. Burada sensörden kasıt içerisinde mikrodenetleyici barındıran ve internete bağlanabilen bir donanımdır. Sensör mesajı  “temperature” topic adı ile broker’a gönderir. Broker bu mesajı aldıktan sonra “temperature” topic’ine abone olan bir cihaz olup olmadığına bakar. Eğer “temperature” topic’ine abone olmuş cihazlar var ise bu cihazlara sensörden aldığı mesajı aynen iletir.

Broker Yazılımı ve Broker’a Bağlanma

Broker’ın bir bilgisayarda veya bulut sisteminde çalışan yazılımlar olduğunu söylemiştim. Ben ücretsiz olan Mosquitto yazılımı kullanacağım.  Mosquitto komut satırından çalıştırılan bir yazılım. Yani mosquitto ile broker açabilmek için cmd ekranından bir takım komutlar yazmamız gereklidir.

Komut Satırından Broker Açma

Komut Satırından Broker Açma

Bu komutlardan sonra Broker’ı açmış oluyoruz. Her seferinde tek tek bu komutları yazmamak için şöyle bir yöntem uyguluyorum. Yeni bir metin belgesi oluşturup içine yukarıdaki resimdeki komutların aynısını yazıyorum ve metin belgesinin uzantısını .bat olarak değiştiriyorum. Böylece oluşturduğum .bat uzantılı dosyaya tıklayınca broker otomatik olarak açılıyor.

.bat uzantılı dosyalar

Broker için yazdığım .bat uzantılı dosya(son satır enter karakteri ile bitiyor );

Publisher.bat dosyasının içeriği;

Burada dikkat edilmesi gereken bir kaç nokta var. publisher.bat dosyasının içerisindeki “192.168.1.103” benim brokerı çalıştırdığım bilgisayarın IP’si. “IOT” ise benim rastgele isim verdiğim bir topic adı. Bu Ahmet de olabilir Mehmet de size bağlı. En sondaki “LED_ON” ise IOT topic’ine gönderilecek mesajdır.

Subscriber.bat dosyasının içeriği;

Burada da aynı bilgisayardan IOT topic’ine subscribe yani abone olduk. Bu komutlarda mosquitto programını nereye kurduysanız (C  veya D) ona göre düzenlemeniz gerekmektedir. Benim bilgisayarımda mosquitto C:\Program Files altında kurulu olduğu için .bat uzantılı dosyalar ona göre düzenlenmiştir.

MQTT Paket Formatı

ESP ile MQTT üzerinden bir broker’a TCP/IP ile belirli hexadecimal paketler gönderilerek bağlanılır ve veri alışverişi yapılır. Başlangıç olarak Broker’a bağlanma paketi , Subscribe paketi ve Publish paketinden bahsedeceğim. MQTT yalnızca bu üç paket ile sınırlı değildir. Unsubscribe,Pinqrequest gibi farklı paketler de vardır. Bu paketler hakkında daha fazla bilgi için mqtt.org adresini ziyaret edebilirsiniz.

Broker’a Bağlanma Paketi

Connect Packet

Broker’a bağlanabilmek için yukarıdaki paketi TCP/IP üzerinden servera göndermemiz gerekir. Burada her bir kutucuk 8 bitlik hexadecimal sayıya karşılık gelmektedir.

Gönderilecek ilk iki byte “Fixed Header” olarak isimlendirilmektedir. İlk byte kontrol paket tipidir. Connect için 0x10 ,Subscribe için 0x82, Publish için 0x30 olarak ayarlanmalıdır. İkinci byte ise bundan sonra kaç byte veri göndereceğimizi yazdığımız byte’dır ve “remaining length” olarak isimlendirilir. Yukarıdaki resimde dikkat edilirse remain length’ten sonra 17 byte’lık bir veri daha paket içerisinde bulunmaktadır. Decimal 17 sayısı hexadecimal 0x11 değerine eşit olduğu için Remain Length’e 0x11 yazdık. Bu byte sizin belirleyeceğiniz “Client ID” ye göre değişecektir.

Protocol Length(16bit) ve ardından gelen Protokol adı MQTT. Burada protokol ismi 4 karakter olduğu için “Protocol Length”   0x00 ve 0x04 oldu. MQTT kutucuğunun altında yazan değerler bu harflerin ASCII tablosuna karşılık gelen değerlerdir.

Level byte mqtt.org sitesinde 0x04 olmalı dediği için öyle yazdım. Bunun neden 4 olduğu ile ilgili bir açıklama bulamadım.

Flag byte ile bağlantının şifreli mi şifresiz mi yapılacağı vb. ayarlamalar yapılabilir.

MQTT Flag Byte

Şifreli bir bağlantı yapmak güvenlik açısından önemlidir. Ben şifresiz bağlanmayı deneyeceğim. O yüzden burada sadece “Clean Session” bitini aktif ediyorum. Bu yüzden Flag byte = 0x02 oldu.

Keep Alive ; Broker’a bağlandıktan sonra eğer publish veya farklı bir işlem yapılmaz ise broker bağlantınızı belli bir süre sonra otomatik olarak kesiyor. Bu süreyi ise 2 byte’lık “keep alive” ile ayarlıyoruz. Buraya yazdığımız değer saniye cinsindendir. Ben bunu 60 saniye olarak ayarladım araştırmalarıma göre de genellikle 60 saniye olarak ayarlanmış. Eğer brokera bağlandıktan sonra 30 saniye de bir publish yapıyorsanız broker sizin bağlantınızı kesmeyecektir. Publish  yapmadan broker bağlantınızın sürekli aktif kalmasını istiyorsanız 40 sn veya 50 saniye aralıklarla “Ping Request” paketini yollayabilirsiniz.Böylece her ping gönderdiğinizde broker sizin hala aktif olduğunuzu bilecektir.

Son olarak ise “Client ID” uzunluğunu ve adını göndermemiz gereklidir. Benim Client ID’im  “Topuz” olduğu için ve 5 byte olduğu için Client ID lenght = 0x05 oldu. Böylece broker’a bağlanmak için gönderilmesi gereken paketi bitirdik.

Şimdi gelelim STM32 kod tarafına. Ben bu uygulamada STM32F103 kullandım fakat yazdığım kodlar diğer STM serilerinde de sorunsuz çalışacaktır. Başlangıç olarak STM32 ile ESP yi haberleştirebilmek için USART çevrebirimini aktif ettim. Her bir işlem için ayrı ayrı kısa fonksiyonlar yazdım.

Öncelikle ESP8266’yı internete bağlayalım. Bunun için aşağıdaki gibi bir fonksiyon yazdım.

Bu fonskiyonun aldığı parametreler Wi-fi adınız ve şifreniz olacaktır. ESP sorunsuz bir şekilde internete bağlandıktan sonra Broker’a bağlanma işlemine geçebiliriz.

Broker’a bağlanmak için yazdığım kod aşağıdaki gibidir.

Bu fonksiyonu biraz inceleyelim. ESP modülünün AT komutları ile haberleştiğini biliyoruz. Kullanacağımız AT komutlarına bir bakalım.

AT+CIPCLOSE : Bu komutu fonksiyonun başında kullandım çünkü cihaz daha önceden bir server’a bağlı ise bağlantıyı kessin.

AT+CIPMUX=0 : Birden fazla bağlantı (TCP) yapılacaksa  1 , tek bağlantı yapılacaksa 0 olarak ayarlanmalı.

AT+CIFSR : ESP’ye atanan IP numarasını gösterir. Bağlanmak için gerekli bir fonksiyon değildir sadece ESP’nin IP numarasını öğrenmek için yazdım.

AT+CIPSTART = “TCP”,”192.168.1.103″,1883 : Server’a bağlanmak için gerekli olan komuttur. Burada bağlantı şekli TCP seçildi. IP olarak ise Broker’ın çalıştığı bilgisayarın IP’si yazıldı. Son parametre ise port parametresidir. Yukarıda cmd ekranından broker’ı çalıştırdığımızda hangi portu dinlediğini yazmaktadır. O yüzden port olarak 1883 portu girilmiştir ve genellikle bu kullanılır.

Buraya kadar her şey tamam AT+CIPSTART komutu gönderildikten sonra server’a bağlanmış olduk. Daha sonra AT+CIPSEND komutu ile MQTT paketimizi göndereceğiz.

AT+CIPSEND=%d yazmamdaki sebep kaç byte’lık veri göndereceğimi ESP’ye bildirmektir.

Bağlantı paketini bir diziye kaydetmek için “string.h” kütüphanesinin içerisindeki sprintf() fonksiyonunu kullanıyorum. Char tipinde oluşturduğum bir diziye(tx_buffer) sprintf fonksiyonunu kullanarak bütün paketi kaydediyorum.

sprintf fonksiyonu aynı zamanda size integer olarak diziye kaydedilen stringin uzunluğunu verir. Bu uzunluğu CIPSEND komutu ile gönderip ESP’ye diyorum ki sana bu kadar byte’lık bir veri göndereceğim.

Son olarak ise Broker bağlanmak için gerekli olan paketi UART üzerinden ESP8266‘ya gönderiyoruz.

Buradaki değişkenlerin bazılarını main fonksiyonun üzerinde tanımladım. Bunları  en altta paylaştığım STM32 kodlarının tamamında bulabilirsiniz.

Komut satırından broker’ı çalıştırıp STM’ e kodu yükledikten sonra ESP ile broker’a bağlantı sağlayabilirseniz komut satırı ekranınız aşağıdaki gibi olacaktır.

MQTT_Broker

ESP Broker’a Bağlandı

Bu aşamadan sonra eğer 60 saniye içerisinde publish veya herhangi bir işlem yapmazsak broker bizim server ile olan bağlantımızı kesecek.

Broker_disconnect

Broker Bağlantıyı Kesti

Broker bağlantıyı kestikten sonra tekrar bağlanmadan subcribe veya publish yapamazsınız. Siz farkında olmadan bağlantınız kopmuştur sonra neden mesajı publish edemiyorum diye kıvranırsınız. Buna dikkat etmekte fayda var.

Subscribe(Abone Olma) Paketi

Subscribe Packet

Subscribe olurken package Id belirlemek gerekiyor ve bu değer sıfır olamaz. O yüzden bu değeri 0x01 olarak yazdım.

Abone olunacak topic ismini “IOT” olarak seçiyorum.

Quality of Service(Qos) : Servis kalitesi olarak isimlendirilen bu bit 3 farklı değer alır. Bunlar 0, 1 ve 2’dir. Bu değerler verilerin karşı tarafa iletilip iletilmediğini garanti eden hizmet seviyeleridir.

  • QoS 0: Hizmet kalitesinin minimum seviyesidir.Bu seviyede verinin karşı tarafa iletildiğine dair bir garanti yoktur.
  • QoS 1: Bu seviyede mesajın alıcıya en az bir kez iletildiği garanti edilir. Gönderen alıcıdan PUBACK paketini alana kadar mesajı saklar.
  • QoS 2: En yüksek hizmet seviyesidir. Bu seviyede karşı tarafın mesajı sadece bir kez alacağı garanti edilir. En güvenli ve en yavaş olan seviyedir.

Ben burada QoS=0 olarak seçtim.

 

Subscribe için yazdığım fonksiyon yukarıdaki gibidir. Connect_broker() fonksiyonuna göre daha küçük bir fonksiyon. Parametre olarak sadece topic ismini alıyor. STM32 bu fonksiyonu çağırdıktan sonra cmd ekranında aşağıdaki gibi değişiklikler olması gerekmektedir.

Subscribe Sonrası Konsol

Subscribe olduktan sonra farklı bir cihaz IOT topic’ine bir mesaj gönderdiğinde ESP UART üzerinden STM32’ye bir paket göndermektedir. Bu paket çözümlenerek gönderilen mesaj çekilebilir ve STM’de bir karar mekanizması ile gelen mesaja göre istenilen işlemler yapılabilir.

Publish(yayın) Paketi

Mqtt Publish

Publish Packet

Publish için gerekli olan paket formatı yukarıdaki gibidir. Diğer paketlerdeki benzer değişkenler olduğu için tekrar etmek istemiyorum. Burada ekstradan “message” değişkenimiz var. Yani göndereceğimiz string mesajı paketin sonuna eklememiz gerekir. Publish yapacağım topic adını subscribe topic’inden  farklı seçtim çünkü bir cihazın aynı topic’e hem abone olup hemde yayın yapması mantıklı bir hareket değil. Eğer aynı olursa yayın yapar yapmaz aynı topic’e abone olduğu için gönderdiği mesajı kendisi de alacaktır. Böyle  bir durumu istemediğim için yayın yaptığım topic’i ESP8266 olarak seçtim.

*** Önemli Ekleme: Yukarıda publish paketi için de Qos seviyesi belirlenebilmektedir. Bu gözümden kaçmış. Bu yüzden sanki yayın yaparken Qos seçilmiyormuş gibi anlaşılabilir. Aşağıda görüldüğü gibi publish paket formatının “fixed header” olarak isimlendirilen baytının 1. ve 2. biti ile servis kalitesi seçilebilir. Qos sıfırdan farklı seçildiğinde server ile client arasında bir doğrulama mekanizması kurmak gerekir. Örneğin; Qos 1 iken server’a bir mesaj gönderdiğinizde eğer mesaj alınmış ise server PUBACK(Publish Acknowledgement) paketini client’a geri göndermelidir. Böylece bu paket client tarafından alınarak mesajın servera ulaşıp ulaşmadığı kontrol edilebilir ve veri kaybı önlenebilir. Eğer servis kalitesini sıfırdan farklı seçecek iseniz bu bitlere dikkat etmeniz gerekir. Bu paketler hakkında daha fazla bilgi için buraya tıklayabilirsiniz.

***

Publish için yazdığım fonksiyon ise yukarıdaki gibidir. Parametre olarak ise yayın yapılacak topic adı ve mesaj değişkenlerini alır. Stm32 de  bu fonksiyonu  iki saniyede bir publish edecek şekilde sonsuz döngünün içerisinde kullandım. STM32 , ESP  üzerinden publish yaptığı zaman konsol ekranı aşağıdaki gibi olur.

Publish Sonrası

Resimde görüldüğü gibi broker konsol ekranında yayınlanan mesajı göremiyoruz. Peki publish ettiğimiz bu mesajı nereden izleyebiliriz. Bunun için yukarıda verdiğim subscribe.bat uzantılı dosyayı kendinize göre yazarak yine konsol ekranından izleyebilirsiniz. Ayrıca MQTT için ücretsiz mobil uygulamalar bulunmaktadır. Bunlardan birini de kullanabilirsiniz. Ben MyMQTT isimli ücretsiz uygulamayı kullandım. Arayüzü gayet basit ve başlangıç için kullanışlı bir uygulama.

MyMQTT app

Projenin dosyalarına Github üzerinden ulaşmak için buraya tıklayın.

STM32 Kodlarının Tamamı

Bu yazıda ESP8266 ile ilgili bir kütüphane kullanmadan MQTT protokolü ile haberleşmeyi dilim döndüğünce anlatmaya çalıştım. Yazıda eksik veya hatalı bir kısım görürseniz yorumlarda belirtebilirsiniz.

Aynı uygulamayı GSM modülü ile de yapıp paylaşmayı düşünüyorum. GSM modüllerinin çoğu AT komutları ile haberleştiği için kodlar aşağı yukarı aynı olacaktır. Fakat Broker tarafında port yönlendirme gibi birkaç işlem yapmak gerekecektir.

NOT: Yeri gelmişken belirteyim. Broker’a mobil uygulama üzerinden bağlanabilmek için broker’ın çalıştığı bilgisayar ile aynı wifi ağına bağlı olmanız gerekmektedir. Aynı şekilde ESP modülü de aynı ağa bağlı olmak zorundadır. Farklı ağa bağlı cihazlar arasında da MQTT ile veri alışverişi yapılabilir fakat bunun için port yönlendirme ayarları yapılmalıdır.

Bir sonraki yazıda görüşmek üzere …

Github

Proje dosyalarına github üzerinden erişmek için buraya tıklayabilirsiniz.

Kaynaklar:

Mehmet Topuz

42 Comments

  1. Merhaba,
    Elinize sağlık. ESP8266’ya ait bir modül mü kullandınız yoksa direkt chip’in kendisini mi kullandınız. Tüm ESP8266’lar AT komutları ile haberleşebilecek diye bir durum söz konusu değil diye biliyorum. Bunun için gerekli firmware’in ESP8266 yüklenmiş olması gerekir diye düşünüyorum.

  2. Merhaba,
    Konyu çok güzel anlatmışsınız. Siz broker’ı kendi bilgisayarınıza kurmuşsunuz bulut sistemde olanlara nasıl bağlanabilinir?

    • Merhaba,
      Bulut sistemi için deneme fırsatım olmadı ama nasıl bağlanılacağı ile ilgili bir fikrim var. Öncelikle CloudMQTT için konuşacağım. Siteye üye olduktan sonra size “m11.cloudmqtt.com” şeklinde bir server adresi veriyor. Bunu benim yazdığım koddaki ip değişkeni yerine yazabilirsin. Ayrıca CloudMQTT servera bağlanabilmeniz için sizden kullanıcı adı ve şifre oluşturmanızı istiyor. Bu aşamadan sonra benim yazdığım kodda biraz değişiklik yapmak gerekiyor çünkü yukarıdaki kodlar servera şifresiz bağlanıyor. Şifreli bağlanabilmek için flag isimli değişkenin 0xC2 olması gerekir. Daha sonra “Connect packet” içerisine kullanıcı adı ve şifreyi eklemelisin. Bunu da şöyle yapmalısın; “Connect packet”in sonuna
      (16bitlik kullanıcı adı uzunluğu)+(string olarak kullanıcı adı) + (16 bitlik şifre uzunluğu)+(string olarak şifre)
      şeklinde gönderilmesi gerekir.Şifreli bağlanmayı kendi bilgisayarıma bağlanırken bu şekilde yapmıştım. CloudMQTT için de çalışır diye umuyorum.

  3. Hello, I was very happy to find your tutorial when I was learning AT commands to MQTT. But like the other commented, I have difficulty connecting MQTT hivemq with ID and password. Have you tried it with the AT + MQTT commands of Espressif?
    Look forward to hearing from you!

    • Hello,
      I have never tried AT+MQTT commands. I didn’t even know the existence of this commands. But i connected to Mqtt broker with ID and Password using AT+CIPSTART and AT+CIPSEND commands. If you want to connect like this you must change the flag variable to 0xC2 and you must add the ID and password at the end of the connect packet. For example
      …+IDlength(2 bytes)+ID(string)+passworLength(2 bytes)+password(string)

      • Thank you very much for answering my question. Your tutorials are great, but I’m a bit bad at using bit and flag…. Here is a tutorial from Espressif about AT + MQTT commands. It seems simpler to me. However, I have tried and failed to connect with broker with username and password. I have a deadline to submit my homework and I’m still struggling. I look forward to your help. Thank you very much

      • I don’t think you answered that quickly
        Saygılarımla teşekkür ederim, sağlık!
        Thank you very much dear!

  4. Merhaba rehberiniz için çok teşekkürler. Anlamadığım bir kısım var. Stm32 ile bir topice subscribe olunca gelen mesajlar hangi değişkende kaydedilecek ve mesaj gelip gelmediğini nasıl kontrol edebilirim?

    • Rica ederim. Topice gelen mesajlar UART üzerinden gelecek. Gelen mesaj da publish paketinin içinde gelecek. Yani publish paketinin içinden mesajı çekmeniz gerekmetedir. Bununla ilgili bir örnek bir sonraki yazıda var incelemenizi tavsiye ederim.

  5. In case the message is a variable value, for example type int, how to fix the publish code?
    Looking forward to hearing from you
    Thank you!

    • The package structure type is already a byte array. Therefore, you can put your int variables inside the package without using the sprintf function. if you want to use sprintf function. you can use like this.

      uint8_t msg_value=10;

      sprintf(tx_buffer,"%c%c%c%c%s%c",
      (char)publishCon,(char)remainlength,
      (char)(topiclength << 8),(char)topiclength,
      topic,(char)msg_value);

  6. merhaba benim bir projem var. Bunda esp modülü kullanacağım. Stm32f401re kartına sahibim Burada esp modülü üzerinden 4 kontrol yapmak istiyorum ve bunları da bir web server oluşturup oradan kontrol etmek istiyorum burada bunu sadece at komutları ve html kodları kullanarak yapabilir miyim. Arduinoda örnekleri var ama stm32 için örneklerini bulamadım. Bana yardımcı olup yol gösterirseniz sevinirim

    • Merhaba,
      Ben daha önce esp ile webserver üzerine bir çalışma yapmadım ama dediğiniz şey yapılabilir. At komutları ve basit html komutları ile dediğiniz gibi bir kontrol uygulaması yapılabilir. Linkteki videoda buna benzer bir örnek var incelemenizi tavsiye ederim.
      https://youtu.be/MG-5Ct_rCZQ

  7. Paylaştığınız videoyu izledim sanırım bana yardımcı olacak bunun için teşekkür ederim bir sorunla karşılaşırsam sizi tekrar rahatsız edeceğim 🙂

    • Rica ederim. Herhangi bir sorunla karşılaşırsanız benimle iletişime geçebilirsiniz. Elimden geldiğince yardım ederim. Mail adresim iletişim sayfasına bulunmaktadır.
      iyi çalışmalar.

  8. To stay connected, as you said, Ping Request, what is the Ping packet structure? Have you tried it?
    I hope your answer! Thank you so much.

    • You’re welcome,
      Ping request packet format is very simple. it only has 2 bytes. The first byte is the type of control that should be 0xC0. The second byte is the remaining length. Since the packet size is 2 bytes, the remaining length should be 0x00. I’ve tried it before. I sent the ping request packet to the server every 50 seconds (because keep alive = 60).
      For more information about ping request packet you can visit this link-> https://docs.solace.com/MQTT-311-Prtl-Conformance-Spec/MQTT%20Control%20Packets.htm#_Toc430864945

      • uint8_t Ping_control = 0xC0;
        uint8_t Ping_load = 0x00;
        void Ping_connect (){
        HAL_UART_Transmit(&huart1, (uint8_t*)tx_buf,
        sprintf (tx_buf, “%c%c”, (char) Ping_control, (char) Ping_load ), 1000);
        }
        I did like this, but it doesn’t work. It looks stupid 🙁 Can u help me fix it

  9. Thanks for your help. And I tried it like that:
    uint8_t Ping_control = 0xC0;
    uint8_t Ping_load = 0x00;
    void Ping_connect (){
    HAL_UART_Transmit(&huart1, (uint8_t*)tx_buf,
    sprintf (tx_buf, “%c%c”, (char) Ping_control, (char) Ping_load ), 1000);
    }

    but it doesn’t work. It looks stupid 🙁 Can u help me fix it

  10. I fixed a bit. If I do it right then this is no different from publishing, it will take 2 turns 🙁 Are u there?
    void Ping_connect (){
    int length = sprintf (tx_buf, “%c%c”, (char) Ping_control, (char) Ping_load );

    HAL_UART_Transmit(&huart1,(uint8_t *)tx_buf,sprintf(tx_buf,”AT+CIPSEND=%d\r\n”,length),100);
    while (!Wait(“OK\r\n”));
    HAL_UART_Transmit(&huart1, (uint8_t *)tx_buf,
    sprintf (tx_buf, “%c%c”, (char) Ping_control, (char) Ping_load ), 1000);
    while (!Wait (“\320”));
    }

    • After sending the pingrequest packet, the server will send the ping response packet. Not “\ 320”. The ping response packet is 2 bytes (0xD0 and 0x00) just like the ping request. You can use the wait () function like this.

      char response[2] = {0xD0,0x00};
      while(!wait(response));

  11. Merhaba, bu kodlar üzerinde ufak değişiklikler yaptık ve dakikada bir veri gönderiyoruz. Fakat bazen veri kaybı yaşıyoruz, mesela 10. dk’daki veriler web sunucuya gelmiyor, sizce neden kaynaklanmış olabilir?Qos=0 olarak kullanıyoruz, bundan kaynaklı olabilir mi?

    • Merhaba,
      Bu sorun dediğiniz gibi Qos 0 olmasından kaynaklanıyor olabilir. Servis kalitesi(Qos) sıfır olduğunda publish yapan cihaz serverdan mesajın alındığına dair bir onaylama(acknowledge) beklemez. Qos 1 seçildiğinde her yayın yaptığınızda server size PUBACK paketini gönderir. Eğer Qos 1 seçerseniz bu PUBACK paketinin gelip gelmediğini kontrol etmeniz gerekir. Eğer gelmediyse mesajı tekrar gönderebilirsiniz. Bu durumda mesaj servera iki kere veya daha fazla gitmiş olabilir. Qos 1 mesajın servera en az 1 kere gittiğini doğrular. Qos 2 seçildiğinde server ile client arasında 4 aşamalı bir doğrulama yapılır. Bu en gecikmeli yöntemdir ama mesajın kesin olarak gittiğini garanti eder. Qos parametresini kullandığınız sistemin isterlerine göre seçmeniz gerekir. Olmazsa olmaz dediğiniz, mutlaka veri kaçırmamam gerekiyor dediğiniz bir veriyi gönderiyorsanız servis kalitesini en yüksek seçebilirsiniz. Atıyorum pil ile çalışan bir sisteminiz var ve pil voltaj seviyesini her saniyede bir gönderiyorsunuz. Bu gibi durumlarda Qos 0 seçebilirsiniz çünkü o bir saniyelik veri kaybı sizin için çok önemli değildir. Kaldı ki pil voltajı o bir saniyede değişmemiş bile olabilir. Uzun lafın kısası Qos ile oynayarak ve stm32 tarafındaki implementasyonu iyi yaparak veri kaybını önleyebilirsiniz.
      Ayrıca bu yorum için teşekkür ederim yazıdaki bir eksiği farketmeme sebep oldu. Normalde publish paketinin “fixed header” bitlerinden ikisi Qos belirlemeye yarıyor. Yazıda sanki publish yaparken Qos belirlenmiyormuş gibi anlaşılıyor. Bu kısım gözümden kaçmış. Bunu da en kısa zamanda ekleyeceğim. Eğer Qos ile oynayacak iseniz bu dediklerime dikkat edin. Publish paketinin “fixed header” bitlerini incelemek için linke tıklayabilirsin. https://docs.solace.com/MQTT-311-Prtl-Conformance-Spec/MQTT%20Control%20Packets.htm#_Toc430864901

  12. iyi akşamlar esp8266 üzerinde çalışmalar yapıyorum arduino üzerinde yaptığım zaman hiç bir hata almadan hem at komutlarına cevap alabiliyorum hem de sunucu kurabiliyorum fakat bunu stm32f401re kartımla yapmaya çalıştığım zaman hep hiç bir hareket olmamakla beraber esp8266 modülümde aşırı bir ısınma oluyor bağlantıları çok kontrol ettim fakat bir sıkıntı göremedim bunun nedeni ne olabilir acaba ?

    • Bu sorunun neyden kaynaklandığını bilmiyorum malesef. Ben doğrudan stm32f103C8T6 ya bağlamıştım sorun çıkarmamıştı.

  13. Merhaba hocam, projeyi çalıştırdım,publish oluyor fakat board üzerine gelen publishleri bir türlü alamadım(sizin kodunuzu direk copy paste yapmama rağmen olmuyor).Mqtt lens veya my mqtt programları ile birbiri arasında veri gönderip alabildim ama karta mesajı alamadım(usart irq handlere kesme koymama rağmen kesmeye gitmiyor).Sorun ne olabilir? Teşekkürler

    • Merhaba, huart->ErrorCode değişkenini debug ekranından kontrol edin. Kesmeye gitmiyorsa Uarttan kaynaklı bir hata olabilir. Eğer uarttan kaynaklı bir hata ise ErrorCode değişkenine bir değer atanır. Daha sonra bu değerin karşılığı olan hata koduna bakmak lazım.

      • Sorunu buldum,read_messaje fonksiyonunu gsm-mqtt programında var ama bu sayfada yok. Bende kendi read fonksiyonumu oluşturdum.teşekkürler.

  14. Hocam merhaba. Teşekkürler öncelikle bu güzel tutorial için. Yukarıdaki örneği kullanarak ESP ile bağlanmaya çalıştığımda Mosquitto tarafında şöyle bir hata alıyorum >> Client disconnected due to protocol error.
    Bir türlü çözemedim. ESP önce bağlanıyor mesajı fakat Connect_Broker fonk çalıştığında bağlantı kesiliyor. Mqtt explorer uygulaması ile bağlanabiliyorum fakat gömülüden bir türlü bağlanamıyorum. Siz acaba bu hata ile karşılaştınız mı veya ne gibi ayarlar yaptınız Mosquitto server tarafında?

    • Merhaba, Bu hata bağlantı paketinin yanlış gönderilmesinden kaynaklanıyor. Bu hatayı daha önce bende almıştım. Pakete eklediğiniz baytları kontrol etmenizi tavsiye ederim. Elinizde USB-TTl dönüştürücü falan varsa UART üzerinden gönderdiğiniz paketleri seri port yazılımları ile izlemenizi tavsiye ederim. Paket içerisindeki verilerin sırası yukarıdaki “connect packet” içindeki baytların sırası ile aynı olmalı.

      • Aynen dediğiniz gibi çıktı. Oluşturulan datanın içindeki bazı karakterler bir noktada kullandığım strcpy fonk. unu bozmus. Düzgün kopyalayamadığım içinde verileri yanlış gönderiyormuşum. Yazmış olayım benzer problem problem yaşayan arkadaşlarda görmüş olsunlar. Teşekkürler

  15. Merhaba, iyi çalışmalar Mehmet bey. ESP kodunun brokera bağlanma kısmında gerekli olan paketi gönderiyorum fakat geri dönüş olarak ‘link is not valid’ hatası alıyorum, sebebi ne olabilir acaba?

    • Merhaba, Bunun sebebini bilmiyorum açıkcası fakat birkaç tahminim var. Birincisi AT komut versiyonundan olabilir bunun için ESP firmware’i güncellemeniz gerekebilir. İkincisi ise besleme ile ilgili sorun olabilir. Bu tarz modüller bazı komutları yerine getirirken gereğinden fazla akım çekebilir ve beslediğiniz kaynak bunu sağlayamıyorsa bu tarz sorunlar olabilir. Ayrıca beslemeden kaynaklı olsa sürekli açılıp kapanması gerekir modülün. Sonu “ready” ile biten bir mesaj geldiğini hatırlıyorum böyle durumlarda. Bunların haricinde bir fikrim yok malesef. Bu arada MQTT için güzel bir kütüphane hazırlıyorum bu aralar. Umarım bir an önce bitirip paylaşabilirim.

      • Teşekkürler, sıkıntı beslemedeymiş, espnin bozuk olduğunu fark ettim şu an çalışan bir tane kullanıyorum fakat şimdi de brokera bağlandıktan sonra “Client disconnected due to protocol error.” hatası alıyorum. Bunun sebebinin bağlantı için gönderilen paketten olduğunu düşündüm fakat sizin kodunuzdaki formatı kullanıyorum. Mqtt’nin sayfasından da ayrıca kontrol ettim acaba pakette değişmesi gereken bir şey var mı diye ama bulamadım. Publish’i ve Subscribe’ı mosquitto_pub ve sub ile yapınca bir sıkıntı olmuyor.

        • Bu hata dediğiniz gibi paketin yanlış gönderilmesi ile ilgili olması lazım. MQTT nin versiyonları var bu yüzden kullandığınız broker programı farklı bir versiyona göre paket bekliyor olabilir. Ayrıca gönderdiğiniz paketi debug ekranından byte byte inceleyip karşılaştırmanızı tavsiye ederim. Paketi yanlış oluşturuyor da olabilirsiniz. Geçen gün başıma gelen birşey; Mosquitto broker’ı kullanmak için son versiyonunu indirdim fakat ne ESP’den ne de bilgisayardan bağlanamadım. Daha sonra 1.6 versiyona geri döndüm sorunsuz çalıştı. Sebebini hala tam olarak anlayamadım. Forumlarda ise Windowsta çalışmıyor demişler anlamadım yani. Neyse böyle yani Mert. Paketi tekrar bir kontrol et eğer hata yok ise farklı bir broker dene. Hatta online bir broker dene HiveMQ gibi.

  16. Merhaba, yazınız çok bilgilendirici bunun için teşekkür ederim, fakat bir sorun yaşıyorum. Esp8266’yı stm32 ile modeme bağlantım gerçekleşmiyor. TTL uart haberleşme ile at komutlarını yazdığımda modeme bağlanabiliyorum. Fakat sizin kodlarınızla bağlantıyı bir türlü gerçekleştiremedim. Bunun sebebini çok düşünsem de bulamadım. Bu konu hakkında bir fikriniz var mı?

    • Merhaba, Bu sorunu bulmak için tavsiyem STM32 ile ESP arasındaki UART hattına USB-TTL bağlayıp izleyin. Eğer bir hata var ise orada görünecektir. Bazen gözden kaçan ufak hatalar olabilir. STM32 komutları doğru gönderiyor mu? ESP bu komuta nasıl bir cevap dönüyor? Bazen bir komutu işlemeden bir daha komut gönderince “busy” mesajını dönebiliyor. O yüzden dediğim gibi UART hattını bir dinleyin derim.

Mehmet Kaan Yılmaz için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak.