ArduinoMqttClient ist die offizielle, von Arduino gepflegte MQTT-Bibliothek und läuft auf allem vom UNO R4 WiFi und Nano 33 IoT bis zu MKR-Boards und dem ESP32. Dieser Leitfaden geht die ArduinoMqttClient-API in der Reihenfolge durch, in der Sie sie verwenden: konfigurieren, verbinden, pollen, veröffentlichen, empfangen und eine Will Message setzen. Jedes Beispiel verbindet sich mit einem echten Broker, sodass Sie beim Lesen direkt testen können.
Warum ArduinoMqttClient
ArduinoMqttClient umhüllt ein beliebiges Arduino-Client-Objekt, etwa WiFiClient, WiFiSSLClient, EthernetClient oder einen Mobilfunk-Client, und setzt MQTT 3.1.1 darauf. Die markanteste Designentscheidung: Ausgehende wie eingehende Nachrichten werden als Streams verarbeitet, sodass Sie nie einen Puffer in der Größe Ihrer größten Nachricht brauchen.
| Funktion | ArduinoMqttClient |
|---|---|
| Protokoll | MQTT 3.1.1 |
| Publish-QoS | 0, 1 und 2 |
| Subscribe-QoS | 0, 1 und 2 |
| Retained Messages | Ja |
| Will Message | Ja, gestreamt mit beginWill() / endWill() |
| Payload-Verarbeitung | Gestreamt (print() / read()) |
| Ereignismodell | Polling mit poll(), Callback bei Nachricht |
| Maintainer | Arduino |
Wenn Sie PubSubClient bereits kennen, ist das PubSubClient-Arduino-Tutorial ein nützlicher Vergleichspunkt; beide Bibliotheken lösen dasselbe Problem mit unterschiedlichen Kompromissen.
Die Bibliothek installieren
Öffnen Sie in der Arduino IDE Werkzeuge → Bibliotheken verwalten, suchen Sie nach "ArduinoMqttClient" und installieren Sie sie. Zusätzlich brauchen Sie die Netzwerkbibliothek Ihres Boards:
| Board | Netzwerkbibliothek | Unverschlüsselter Client | TLS-Client |
|---|---|---|---|
| UNO R4 WiFi | WiFiS3 | WiFiClient |
WiFiSSLClient |
| Nano 33 IoT, MKR WiFi 1010 | WiFiNINA | WiFiClient |
WiFiSSLClient |
| ESP32 | WiFi (Core) | WiFiClient |
WiFiClientSecure |
| Boards mit Ethernet-Shield | Ethernet | EthernetClient |
Nicht integriert |
Den Client konfigurieren
Erstellen Sie zuerst den Netzwerk-Client und übergeben Sie ihn dann an MqttClient:
#include <WiFiNINA.h> // oder WiFiS3.h, WiFi.h ...
#include <ArduinoMqttClient.h>
WiFiClient net;
MqttClient mqttClient(net);
Setzen Sie vor dem Aufruf von connect() die Session-Parameter:
mqttClient.setId("acm-51e09b"); // Client ID, niemals leer
mqttClient.setUsernamePassword("YOUR_USERNAME", "YOUR_PASSWORD"); // optional
mqttClient.setKeepAliveInterval(30 * 1000L); // Millisekunden!
mqttClient.setConnectionTimeout(10 * 1000L); // Millisekunden
mqttClient.setCleanSession(true);
Achten Sie auf die Einheiten: Anders als bei PubSubClient werden Keep-Alive- und Timeout-Werte in Millisekunden angegeben. Wer 30 statt 30000 übergibt, erhält nach der Ganzzahldivision ein Keep Alive von null Sekunden. Damit ist Keep Alive komplett deaktiviert, tote Verbindungen bleiben vom Broker unbemerkt, und Ihre Will Message wird nie ausgelöst.
Verbinden und connectError() auswerten
connect(host, port) liefert bei Erfolg 1 und bei einem Fehler 0. Schlägt der Aufruf fehl, verrät connectError() den Grund:
| connectError() | Konstante | Bedeutung und Lösung |
|---|---|---|
| -2 | MQTT_CONNECTION_REFUSED |
Socket konnte nicht geöffnet werden: Problem mit WLAN, DNS, Port oder TLS |
| -1 | MQTT_CONNECTION_TIMEOUT |
Kein CONNACK rechtzeitig: falscher Port-Typ oder schlechte Verbindung |
| 0 | MQTT_SUCCESS |
Verbunden |
| 1 | MQTT_UNACCEPTABLE_PROTOCOL_VERSION |
Broker hat MQTT 3.1.1 abgelehnt (selten) |
| 2 | MQTT_IDENTIFIER_REJECTED |
Leere oder unzulässige Client ID |
| 3 | MQTT_SERVER_UNAVAILABLE |
Broker nimmt derzeit keine Verbindungen an |
| 4 | MQTT_BAD_USER_NAME_OR_PASSWORD |
Zugangsdaten falsch |
| 5 | MQTT_NOT_AUTHORIZED |
Client nicht zugelassen, z. B. passt die Client ID nicht zu den Zugangsdaten |
Eine vollständige, wiederverwendbare Verbindungsfunktion:
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;
}
Zum Testen verwenden Sie broker.connectmq.com auf Port 1883, den öffentlichen MQTT-Broker. Er akzeptiert anonyme Verbindungen mit jeder eindeutigen, nicht leeren Client ID und ist für Tests und Prototypen gedacht, nicht für Produktionsdaten. Halten Sie Ihre Topics unter einem eindeutigen Präfix wie connectmq/demo/<your-id>/ und veröffentlichen Sie nichts Vertrauliches.
Warum poll() so wichtig ist
poll() ist der Herzschlag von ArduinoMqttClient. Jeder Aufruf:
- Liest eingehende Bytes vom Netzwerk-Client und parst vollständige Pakete.
- Ruft Ihren
onMessage-Callback auf (oder stellt die Nachricht fürparseMessage()bereit). - Beantwortet die QoS-1- und QoS-2-Handshakes eingehender Nachrichten.
- Sendet ein PINGREQ, wenn das Keep-Alive-Intervall kurz vor dem Ablauf steht.
Wird poll() länger als das Keep-Alive-Intervall nicht aufgerufen, schließt der Broker die Verbindung. Vermeiden Sie delay()-Aufrufe, die länger als ein Bruchteil Ihres Keep Alive sind, und ersetzen Sie sie durch millis()-basiertes Timing:
unsigned long lastSend = 0;
void loop() {
mqttClient.poll();
if (millis() - lastSend >= 10000) {
lastSend = millis();
// hier veröffentlichen
}
}
Nachrichten veröffentlichen
Das Veröffentlichen ist ein Stream in drei Schritten:
// Einfache QoS-0-Nachricht
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();
Die vollständige Signatur lautet beginMessage(topic, retain = false, qos = 0, dup = false). Es gibt außerdem eine Überladung, die die Payload-Größe vorab entgegennimmt: beginMessage(topic, size, retain, qos, dup). Kennen Sie die exakte Größe, nutzen Sie sie: Die Bibliothek kann die Daten dann direkt ins Netzwerk schreiben, statt erst die ganze Nachricht zu puffern. Das ist bei großen Payloads auf Boards mit wenig RAM entscheidend.
endMessage() liefert bei Erfolg 1. Bei QoS 1 und 2 verarbeitet die Bibliothek die Bestätigungspakete während der folgenden poll()-Aufrufe.
Da print() Zahlen, Strings und Floats akzeptiert, können Sie JSON ohne temporären Puffer aufbauen:
mqttClient.beginMessage(topicTelemetry);
mqttClient.print("{\"t\":");
mqttClient.print(temperature, 2);
mqttClient.print(",\"h\":");
mqttClient.print(humidity, 1);
mqttClient.print("}");
mqttClient.endMessage();
Nachrichten empfangen
Abonnieren Sie nach einem erfolgreichen Connect und bei Verwendung einer Clean Session erneut nach jedem Reconnect:
mqttClient.onMessage(onMqttMessage);
mqttClient.subscribe("connectmq/demo/acm-51e09b/cmd/#", 1);
Der Callback erhält nur die Nachrichtengröße. Sie lesen das Topic aus und streamen die Payload:
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);
}
Nicht gelesene Bytes werden verworfen, sobald die nächste Nachricht eintrifft. Damit sind übergroße Nachrichten unproblematisch: Sie hören einfach an Ihrer Puffergrenze auf zu lesen.
Alternativ zum Callback können Sie in loop() int size = mqttClient.parseMessage(); aufrufen und Nachrichten direkt verarbeiten, wenn size größer als null ist. Verwenden Sie den einen oder den anderen Stil, nicht beide.
Will Messages
Eine Will Message (Last Will and Testament) wird vom Broker veröffentlicht, wenn sich Ihr Gerät ohne Abmeldung trennt, zum Beispiel nach einem Stromausfall oder WLAN-Verlust. Konfigurieren Sie sie vor connect():
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();
}
Wer direkt nach dem Verbinden ein retained online auf demselben Topic veröffentlicht, liefert jedem Dashboard eine zuverlässige Anwesenheitsanzeige: online, solange das Gerät verbunden ist, und offline, sobald der Broker erkennt, dass es weg ist. Das geschieht nach etwa anderthalb Keep-Alive-Intervallen.
Ein vollständiges, reconnect-sicheres Muster
Setzen Sie die Bausteine mit dieser Checkliste zusammen:
- WLAN verbinden und auf eine gültige IP-Adresse warten.
- ID, Zugangsdaten, Keep Alive und Will setzen.
- Verbinden; bei einem Fehler
connectError()ausgeben und nach einer Pause erneut versuchen, die mit jedem Fehlschlag länger wird. - Bei Erfolg
onMessageregistrieren, abonnieren undonlineretained veröffentlichen. - In
loop()das WLAN prüfen,mqttClient.connected()prüfen,poll()aufrufen und über einenmillis()-Timer veröffentlichen.
Board-spezifische Versionen dieses Musters finden Sie im Arduino-UNO-R4-WiFi-MQTT-Tutorial und im Leitfaden zu Nano 33 IoT und MQTT mit WiFiNINA. Für ein umfassenderes Projekt zeigt das ESP32-IoT-Tutorial, wie die Geräteseite mit Dashboards und Alarmen zusammenspielt.
Häufige Fehler mit ArduinoMqttClient
beginWill()nachconnect()aufrufen. Der Will ist Teil des CONNECT-Pakets und muss daher vorher konfiguriert werden.- Nur in
setup()abonnieren. Nach einem Reconnect mit Clean Session hat der Broker Ihre Subscriptions vergessen. Abonnieren Sie stattdessen in Ihrer Connect-Funktion. - Eine Client ID auf mehreren Boards verwenden. Der Broker trennt jedes Mal die ältere Session, wenn sich ein anderes Board verbindet, und erzeugt so eine endlose Reconnect-Schleife.
- Aus
onMessageheraus veröffentlichen. Das funktioniert, aber lesen Sie zuerst die eingehende Payload zu Ende; sonst gehen die ungelesenen Bytes verloren. endMessage()vergessen. Ohne diesen Aufruf wird nichts gesendet, und der nächstebeginMessage()-Aufruf schlägt fehl.
Produktivbetrieb: TLS und Zugangsdaten
Für echte Einsätze wechseln Sie zu einem TLS-Client und Port 8883 und authentifizieren sich mit eigenen Zugangsdaten. Ein verwalteter MQTT-Broker wie ConnectMQ stellt für jeden im Portal angelegten Broker Benutzername, Passwort und Client ID aus; die Client ID ist an diese Zugangsdaten gebunden, setzen Sie sie also exakt mit setId(). Das Zertifikat von ConnectMQ stammt von Let's Encrypt, dem die WLAN-Module aktueller Arduino-Boards ab Werk vertrauen. Ersetzen Sie dabei das Demo-Präfix durch eine dauerhafte Topic-Struktur; in Industrie-4.0-Umgebungen folgt sie meist der ISA-95-Hierarchie eines Unified Namespace (UNS), etwa acme/werk-dresden/verpackung/linie-3/status. Lesen Sie vor der Auslieferung die Best Practices für MQTT-Sicherheit.
Starten Sie mit ConnectMQ
ConnectMQ ist ein Cloud-MQTT-Broker mit MQTT 3.1.1 und 5.0, TLS und WebSockets sowie einem Portal mit MQTT-Client im Browser, Live-Topic-Explorer und Schwellenwert-Alarmen. So sehen Sie am einfachsten, was Ihr ArduinoMqttClient-Sketch tatsächlich sendet. Erstellen Sie einen kostenlosen Serverless Broker unter app.connectmq.com, ohne Kreditkarte.
Häufig gestellte Fragen
Ist ArduinoMqttClient besser als PubSubClient?
Keine der beiden ist grundsätzlich besser. ArduinoMqttClient unterstützt Publishing mit QoS 1 und 2 und streamt Payloads, während PubSubClient kleiner ist und eine riesige Auswahl an Beispielen bietet. Wählen Sie ArduinoMqttClient für offizielle Arduino-Boards und wenn Sie QoS brauchen.
Unterstützt ArduinoMqttClient MQTT 5?
Nein, die Bibliothek implementiert MQTT 3.1.1. Moderne Broker bedienen 3.1.1- und 5.0-Clients parallel, sodass Ihr Gerät trotzdem Topics mit MQTT-5-Anwendungen teilen kann.
Warum bricht meine ArduinoMqttClient-Verbindung jede Minute ab?
Meist wird poll() nicht oft genug aufgerufen, das Keep Alive wurde in Sekunden statt in Millisekunden angegeben, oder ein anderer Client verwendet dieselbe Client ID.
Wie groß darf eine Nachricht maximal sein?
Die Bibliothek streamt Payloads, die Grenze setzt also vor allem Ihr Broker. Der öffentliche MQTT-Broker unter broker.connectmq.com akzeptiert bis zu 64 KB pro Nachricht; der kostenlose Serverless-Plan erlaubt 256 KB.



