ESP32 ve Arduino

ArduinoMqttClient Kütüphane Rehberi: API, Polling, QoS ve Will Mesajları

Resmi ArduinoMqttClient kütüphanesi için eksiksiz rehber: bağlantı API'si, poll() neden önemli, akış halinde yayınlama ve alma, QoS ve retain bayrakları, will mesajları ve tüm connectError() kodları.

MQTT mesajları yayınlayan bir Arduino kartının yanında ArduinoMqttClient sketch'ini gösteren kod editörü
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

ArduinoMqttClient, Arduino tarafından geliştirilen resmi MQTT kütüphanesidir ve UNO R4 WiFi ile Nano 33 IoT'den MKR kartlarına ve ESP32'ye kadar her şeyde çalışır. Bu rehber ArduinoMqttClient API'sini kullanacağınız sırayla anlatır: yapılandırma, bağlanma, poll, yayınlama, alma ve will mesajı ayarlama. Her örnek gerçek bir broker'a bağlanır, böylece okurken test edebilirsiniz.

Neden ArduinoMqttClient?

ArduinoMqttClient; WiFiClient, WiFiSSLClient, EthernetClient veya bir hücresel client gibi herhangi bir Arduino Client nesnesini sarmalar ve üzerine MQTT 3.1.1 ekler. En dikkat çekici tasarım tercihi, hem giden hem de gelen mesajların akış (stream) olarak işlenmesidir; böylece en büyük mesajınız boyutunda bir buffer'a asla ihtiyaç duymazsınız.

Yetenek ArduinoMqttClient
Protokol MQTT 3.1.1
Yayınlama QoS 0, 1 ve 2
Abonelik QoS 0, 1 ve 2
Retained message Evet
Will mesajı Evet, beginWill() / endWill() ile akış halinde
Payload işleme Akış (print() / read())
Olay modeli poll() ile yoklama, mesajda callback
Geliştirici Arduino

PubSubClient'ı zaten biliyorsanız PubSubClient Arduino eğitimi faydalı bir karşılaştırma noktasıdır; iki kütüphane aynı sorunu farklı ödünleşimlerle çözer.

Kütüphaneyi Kurmak

Arduino IDE'de Tools → Manage Libraries menüsünü açın, "ArduinoMqttClient" araması yapın ve kurun. Kartınız için ağ kütüphanesine de ihtiyacınız vardır:

Kart Ağ kütüphanesi Düz client TLS client
UNO R4 WiFi WiFiS3 WiFiClient WiFiSSLClient
Nano 33 IoT, MKR WiFi 1010 WiFiNINA WiFiClient WiFiSSLClient
ESP32 WiFi (core) WiFiClient WiFiClientSecure
Ethernet shield'lı kartlar Ethernet EthernetClient Yerleşik değil

Client'ı Yapılandırmak

Önce ağ client'ını oluşturun, ardından onu MqttClient nesnesine verin:

#include <WiFiNINA.h>          // veya WiFiS3.h, WiFi.h ...
#include <ArduinoMqttClient.h>

WiFiClient net;
MqttClient mqttClient(net);

connect() çağırmadan önce oturum parametrelerini ayarlayın:

mqttClient.setId("acm-51e09b");                       // client ID, asla boş olmamalı
mqttClient.setUsernamePassword("YOUR_USERNAME", "YOUR_PASSWORD"); // isteğe bağlı
mqttClient.setKeepAliveInterval(30 * 1000L);          // milisaniye!
mqttClient.setConnectionTimeout(10 * 1000L);          // milisaniye
mqttClient.setCleanSession(true);

Birimlere dikkat edin: PubSubClient'ın aksine keep alive ve zaman aşımı değerleri milisaniye cinsindendir. 30000 yerine 30 vermek, tam sayı bölmesinden sonra sıfır saniyelik bir keep alive'a dönüşür; bu da keep alive'ı tamamen devre dışı bırakır, böylece ölü bağlantılar broker tarafından fark edilmez ve will mesajınız asla tetiklenmez.

Bağlanmak ve connectError() Okumak

connect(host, port) başarıda 1, başarısızlıkta 0 döndürür. Başarısız olduğunda connectError() nedenini söyler:

connectError() Sabit Anlamı ve çözümü
-2 MQTT_CONNECTION_REFUSED Soket açılamadı: Wi-Fi, DNS, port veya TLS sorunu
-1 MQTT_CONNECTION_TIMEOUT Zamanında CONNACK gelmedi: yanlış port türü veya zayıf bağlantı
0 MQTT_SUCCESS Bağlandı
1 MQTT_UNACCEPTABLE_PROTOCOL_VERSION Broker MQTT 3.1.1'i reddetti (nadir)
2 MQTT_IDENTIFIER_REJECTED Boş veya izin verilmeyen client ID
3 MQTT_SERVER_UNAVAILABLE Broker şu anda bağlantı kabul etmiyor
4 MQTT_BAD_USER_NAME_OR_PASSWORD Kimlik bilgileri yanlış
5 MQTT_NOT_AUTHORIZED Client'a izin verilmiyor, ör. client ID kimlik bilgileriyle eşleşmiyor

Eksiksiz ve yeniden kullanılabilir bir bağlantı fonksiyonu:

bool connectMqtt(const char* host, int port) {
  Serial.print("Connecting to ");
  Serial.print(host);
  Serial.print(':');
  Serial.println(port);

  if (!mqttClient.connect(host, port)) {
    Serial.print("MQTT connect failed, connectError = ");
    Serial.println(mqttClient.connectError());
    return false;
  }
  Serial.println("MQTT connected");
  return true;
}

Test için herkese açık MQTT test broker'ı olan broker.connectmq.com adresini 1883 portunda kullanın. Benzersiz ve boş olmayan herhangi bir client ID ile anonim bağlantıları kabul eder. Topic'lerinizi connectmq/demo/<your-id>/ gibi benzersiz bir önek altında tutun ve hassas hiçbir şey yayınlamayın.

poll() Neden Önemli?

poll(), ArduinoMqttClient'ın kalp atışıdır. Her çağrı:

  1. Ağ client'ından gelen baytları okur ve tamamlanan paketleri ayrıştırır.
  2. onMessage callback'inizi çağırır (veya mesajı parseMessage() için kullanılabilir hale getirir).
  3. Gelen mesajlar için QoS 1 ve QoS 2 el sıkışmalarını yanıtlar.
  4. Keep alive aralığı dolmak üzereyken bir PINGREQ gönderir.

poll() keep alive aralığından daha uzun süre çağrılmazsa broker bağlantıyı kapatır. Keep alive süresinin küçük bir kesrinden uzun delay() çağrılarından kaçının ve bunları millis() tabanlı zamanlamayla değiştirin:

unsigned long lastSend = 0;

void loop() {
  mqttClient.poll();
  if (millis() - lastSend >= 10000) {
    lastSend = millis();
    // burada yayınlayın
  }
}

Mesaj Yayınlamak

Yayınlama üç adımlı bir akıştır:

// Düz QoS 0 mesajı
mqttClient.beginMessage("connectmq/demo/acm-51e09b/temperature");
mqttClient.print(22.7);
mqttClient.endMessage();

// Retained, QoS 1
mqttClient.beginMessage("connectmq/demo/acm-51e09b/status", true, 1);
mqttClient.print("online");
mqttClient.endMessage();

Tam imza beginMessage(topic, retain = false, qos = 0, dup = false) şeklindedir. Payload boyutunu baştan alan bir aşırı yükleme (overload) de vardır: beginMessage(topic, size, retain, qos, dup). Tam boyutu biliyorsanız bunu kullanın: kütüphane bu durumda mesajın tamamını önce buffer'a almak yerine veriyi doğrudan ağa yazabilir; bu da az RAM'li kartlarda büyük payload'lar için önemlidir.

endMessage() başarıda 1 döndürür. QoS 1 ve 2 için kütüphane, onay paketlerini sonraki poll() çağrıları sırasında işler.

print() sayıları, string'leri ve float'ları kabul ettiği için geçici bir buffer olmadan JSON oluşturabilirsiniz:

mqttClient.beginMessage(topicTelemetry);
mqttClient.print("{\"t\":");
mqttClient.print(temperature, 2);
mqttClient.print(",\"h\":");
mqttClient.print(humidity, 1);
mqttClient.print("}");
mqttClient.endMessage();

Mesaj Almak

Başarılı bir bağlantıdan sonra abone olun; clean session kullanıyorsanız her yeniden bağlanmadan sonra da tekrar abone olun:

mqttClient.onMessage(onMqttMessage);
mqttClient.subscribe("connectmq/demo/acm-51e09b/cmd/#", 1);

Callback yalnızca mesaj boyutunu alır. Topic'i okursunuz ve payload'u akış halinde alırsınız:

void onMqttMessage(int messageSize) {
  String topic = mqttClient.messageTopic();
  Serial.print("Topic: ");
  Serial.print(topic);
  Serial.print(", QoS ");
  Serial.print(mqttClient.messageQoS());
  Serial.print(", retained ");
  Serial.println(mqttClient.messageRetain());

  char payload[128];
  int n = 0;
  while (mqttClient.available() && n < (int)sizeof(payload) - 1) {
    payload[n++] = (char)mqttClient.read();
  }
  payload[n] = '\0';
  Serial.println(payload);
}

Okumadığınız baytlar bir sonraki mesaj geldiğinde atılır. Bu, aşırı büyük mesajları güvenli kılar: buffer limitinize ulaştığınızda okumayı bırakmanız yeterlidir.

Callback'e alternatif olarak loop() içinde int size = mqttClient.parseMessage(); çağırabilir ve size sıfırdan büyük olduğunda mesajları satır içinde işleyebilirsiniz. İki tarzdan birini kullanın, ikisini birden değil.

Will Mesajları

Will mesajı (Last Will and Testament), cihazınız veda etmeden bağlantıyı kaybettiğinde, örneğin bir elektrik kesintisinden veya Wi-Fi kaybından sonra broker tarafından yayınlanır. Bunu connect() öncesinde yapılandırın:

const char willTopic[] = "connectmq/demo/acm-51e09b/status";

mqttClient.beginWill(willTopic, true, 1);   // retained, QoS 1
mqttClient.print("offline");
mqttClient.endWill();

if (connectMqtt("broker.connectmq.com", 1883)) {
  mqttClient.beginMessage(willTopic, true, 1);
  mqttClient.print("online");
  mqttClient.endMessage();
}

Bağlandıktan hemen sonra aynı topic'e retained bir online yayınlamak, her dashboard'a doğru bir varlık göstergesi sağlar: bağlıyken online, broker cihazın gittiğini fark eder etmez offline; bu da yaklaşık bir buçuk keep alive aralığı sonra gerçekleşir.

Yeniden Bağlanmaya Dayanıklı Eksiksiz Bir Desen

Parçaları bu kontrol listesiyle bir araya getirin:

  1. Wi-Fi'ye bağlanın ve geçerli bir IP adresi bekleyin.
  2. ID'yi, kimlik bilgilerini, keep alive'ı ve will'i ayarlayın.
  3. Bağlanın; başarısızlıkta connectError() yazdırın ve her başarısızlıkta artan bir gecikmeden sonra yeniden deneyin.
  4. Başarıda onMessage kaydedin, abone olun ve retained online yayınlayın.
  5. loop() içinde Wi-Fi'yi kontrol edin, mqttClient.connected() kontrol edin, poll() çağırın ve bir millis() zamanlayıcısıyla yayınlayın.

Bu desenin karta özel sürümleri Arduino UNO R4 WiFi MQTT eğitiminde ve WiFiNINA ile Nano 33 IoT MQTT rehberinde yer alır. Daha kapsamlı bir proje için ESP32 IoT eğitimi, cihaz tarafının dashboard'lar ve uyarılarla nasıl bütünleştiğini gösterir.

Yaygın ArduinoMqttClient Hataları

  • beginWill() fonksiyonunu connect() sonrasında çağırmak. Will, CONNECT paketinin bir parçasıdır, bu yüzden önce yapılandırılmalıdır.
  • Yalnızca setup() içinde abone olmak. Clean session ile yeniden bağlandıktan sonra broker aboneliklerinizi unutmuştur. Bunun yerine bağlantı fonksiyonunuzda abone olun.
  • Tek bir client ID'yi birkaç kartta kullanmak. Başka bir kart her bağlandığında broker eski oturumu düşürür ve sonsuz bir yeniden bağlanma döngüsü oluşur.
  • onMessage içinden yayınlamak. Çalışır, ancak önce gelen payload'u okumayı bitirin; aksi halde okunmamış baytlar kaybolur.
  • endMessage() çağrısını unutmak. Onsuz hiçbir şey gönderilmez ve sonraki beginMessage() çağrısı başarısız olur.

Production: TLS ve Kimlik Bilgileri

Gerçek dağıtımlar için bir TLS client'ına ve 8883 portuna geçin ve kendi kimlik bilgilerinizle kimlik doğrulayın. ConnectMQ gibi yönetilen bir MQTT broker, portalda oluşturduğunuz her broker için bir kullanıcı adı, parola ve client ID verir; client ID bu kimlik bilgilerine bağlıdır, bu yüzden onu setId() ile birebir ayarlayın. ConnectMQ'nun sertifikası, güncel Arduino kartlarındaki Wi-Fi modüllerinin kutudan çıktığı haliyle güvendiği Let's Encrypt'ten gelir. Yayına almadan önce MQTT güvenliği en iyi uygulamalarını gözden geçirin.

ConnectMQ ile Başlayın

ConnectMQ; MQTT 3.1.1 ve 5.0, TLS ve WebSocket desteğinin yanı sıra tarayıcı içi bir MQTT client'ı, canlı topic gezgini ve eşik uyarıları içeren bir portal sunan bir bulut MQTT broker'dır. ArduinoMqttClient sketch'inizin gerçekte ne gönderdiğini görmenin en kolay yoludur. app.connectmq.com adresinde ücretsiz bir Serverless broker oluşturun, kredi kartı gerekmez.

Sık Sorulan Sorular

ArduinoMqttClient, PubSubClient'tan daha mı iyi?

Hiçbiri her durumda daha iyi değildir. ArduinoMqttClient QoS 1 ve 2 ile yayınlamayı destekler ve payload'ları akış halinde işler; PubSubClient ise daha küçüktür ve çok geniş bir örnek tabanına sahiptir. Resmi Arduino kartları ve QoS ihtiyaçları için ArduinoMqttClient'ı seçin.

ArduinoMqttClient MQTT 5'i destekler mi?

Hayır, MQTT 3.1.1'i uygular. Modern broker'lar 3.1.1 ve 5.0 client'larına yan yana hizmet verir; böylece cihazınız MQTT 5 uygulamalarıyla yine de topic paylaşabilir.

ArduinoMqttClient bağlantım neden her dakika kopuyor?

Genellikle poll() yeterince sık çağrılmıyordur, keep alive milisaniye yerine saniye olarak ayarlanmıştır ya da başka bir client aynı client ID'yi kullanıyordur.

Maksimum mesaj boyutu nedir?

Kütüphane payload'ları akış halinde işler, bu yüzden limit çoğunlukla broker'ınıza bağlıdır. broker.connectmq.com adresindeki herkese açık broker mesaj başına 64 KB'a kadar kabul eder; ücretsiz Serverless plan ise 256 KB'a izin verir.

İlgili yazılar

ESP32 NTP MQTT Zaman Damgası: Her Mesaja Doğru Zaman Ekleyin

ESP32 saatini NTP ile eşitleyin, ISO 8601 ve epoch milisaniye zaman damgalarını biçimlendirin ve bunları MQTT payload'larına ekleyin; böylece ölçümler geç yayınlansa bile gerçek alınma zamanlarını korur.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.