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ı:
- Ağ client'ından gelen baytları okur ve tamamlanan paketleri ayrıştırır.
onMessagecallback'inizi çağırır (veya mesajıparseMessage()için kullanılabilir hale getirir).- Gelen mesajlar için QoS 1 ve QoS 2 el sıkışmalarını yanıtlar.
- 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:
- Wi-Fi'ye bağlanın ve geçerli bir IP adresi bekleyin.
- ID'yi, kimlik bilgilerini, keep alive'ı ve will'i ayarlayın.
- 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. - Başarıda
onMessagekaydedin, abone olun ve retainedonlineyayınlayın. loop()içinde Wi-Fi'yi kontrol edin,mqttClient.connected()kontrol edin,poll()çağırın ve birmillis()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()fonksiyonunuconnect()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.
onMessageiç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 sonrakibeginMessage()ç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.



