ESP32 und Arduino

Arduino UNO R4 WiFi MQTT Tutorial: Sensordaten mit ArduinoMqttClient senden

Verbinden Sie den Arduino UNO R4 WiFi mit WiFiS3 und ArduinoMqttClient mit einem MQTT-Broker, senden Sie Analogwerte, steuern Sie die LED-Matrix vom Laptop aus und steigen Sie auf TLS über Port 8883 um.

Arduino UNO R4 WiFi mit leuchtender LED-Matrix als Illustration einer Arduino-UNO-R4-WiFi-MQTT-Verbindung in die Cloud
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Der Arduino UNO R4 WiFi bringt WLAN in den vertrauten UNO-Formfaktor und ist damit ein ideales erstes Board für ein Arduino-UNO-R4-WiFi-MQTT-Projekt. In diesem Tutorial nutzen Sie die Bibliothek WiFiS3 und den offiziellen ArduinoMqttClient, um analoge Sensorwerte zu veröffentlichen, Befehle zu empfangen, die auf der eingebauten LED-Matrix angezeigt werden, und anschließend mit eigenen Zugangsdaten auf eine verschlüsselte TLS-Verbindung umzusteigen.

Wie der UNO R4 WiFi mit dem Netzwerk kommuniziert

Der UNO R4 WiFi hat zwei Chips. Der Hauptmikrocontroller ist ein Renesas RA4M1, auf dem Ihr Sketch läuft. Die Netzwerkkommunikation übernimmt ein ESP32-S3-Modul als WLAN-Coprozessor. Ihr Sketch spricht mit ihm über die Bibliothek WiFiS3, die mit dem Paket "Arduino UNO R4 Boards" geliefert wird.

Diese Aufteilung hat zwei praktische Folgen:

  1. Der TLS-Handshake läuft auf dem ESP32-S3-Modul, das ein Bündel gängiger Root-Zertifikate mitbringt. Verschlüsselte Verbindungen zu Brokern mit weithin vertrauenswürdigen Zertifikaten wie Let's Encrypt funktionieren mit WiFiSSLClient daher in der Regel, ohne dass Sie ein Zertifikat einfügen müssen.
  2. Der Coprozessor hat eine eigene Firmware. Verhalten sich Verbindungen merkwürdig, ist ein Update dieser Firmware eine der ersten Maßnahmen.

Für das MQTT-Protokoll selbst verwenden Sie ArduinoMqttClient, die offizielle, von Arduino gepflegte Bibliothek. Sie funktioniert mit jedem Client-Objekt, auch mit WiFiClient und WiFiSSLClient aus WiFiS3.

Was Sie brauchen

Komponente Hinweise
Arduino UNO R4 WiFi Nicht der UNO R4 Minima, der kein Funkmodul hat
Arduino IDE 2.x Mit "Arduino UNO R4 Boards", installiert über den Boardverwalter
ArduinoMqttClient Aus dem Bibliotheksverwalter installieren
Ein Potentiometer oder ein beliebiger Analogsensor An A0 angeschlossen (optional, der Code funktioniert auch mit offenem Pin)
Mosquitto-CLI-Tools Zum Testen von Ihrem Computer aus
Ein 2,4-GHz-WLAN Das Modul verbindet sich nicht mit 5-GHz-Netzen

Öffnen Sie vor dem Start Datei → Beispiele → WiFiS3 → CheckFirmwareVersion und laden Sie es hoch. Meldet der serielle Monitor eine veraltete Firmware, aktualisieren Sie sie mit dem Firmware-Updater der Arduino IDE (Werkzeuge → Firmware Updater) oder gemäß der offiziellen Anleitung auf docs.arduino.cc.

Schritt 1: An den öffentlichen MQTT-Broker senden

Die erste Version verbindet sich unverschlüsselt auf Port 1883 mit broker.connectmq.com, dem von ConnectMQ bereitgestellten öffentlichen MQTT-Broker. Anonyme Verbindungen werden akzeptiert, solange die Client ID nicht leer ist. Verwenden Sie ein eindeutiges Topic-Präfix und senden Sie keine privaten Daten, denn jeder kann die öffentlichen Topics abonnieren; der Broker ist für Tests und Prototypen gedacht, nicht für Produktionsdaten.

Legen Sie im Sketch einen zweiten Tab namens arduino_secrets.h an:

#define SECRET_SSID "YOUR_WIFI"
#define SECRET_PASS "YOUR_WIFI_PASSWORD"

Dann der Haupt-Sketch:

#include <WiFiS3.h>
#include <ArduinoMqttClient.h>
#include "Arduino_LED_Matrix.h"
#include "arduino_secrets.h"

const char broker[] = "broker.connectmq.com";
const int  port     = 1883;

const char deviceId[]       = "unor4-8d21f0";   // eindeutig machen
const char topicTelemetry[] = "connectmq/demo/unor4-8d21f0/telemetry";
const char topicCommand[]   = "connectmq/demo/unor4-8d21f0/matrix/set";
const char topicStatus[]    = "connectmq/demo/unor4-8d21f0/status";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
ArduinoLEDMatrix matrix;

unsigned long lastPublish = 0;

// Zwei einfache Frames für die 12x8-Matrix
const uint32_t FRAME_ON[]  = { 0xffffffff, 0xffffffff, 0xffffffff };
const uint32_t FRAME_OFF[] = { 0x00000000, 0x00000000, 0x00000000 };

void connectWifi() {
  Serial.print("Connecting to ");
  Serial.println(SECRET_SSID);
  while (WiFi.begin(SECRET_SSID, SECRET_PASS) != WL_CONNECTED) {
    Serial.print(".");
    delay(3000);
  }
  // WiFiS3 meldet kurzzeitig 0.0.0.0, auf eine echte Adresse warten
  while (WiFi.localIP() == IPAddress(0, 0, 0, 0)) delay(200);
  Serial.print("\nIP address: ");
  Serial.println(WiFi.localIP());
}

void onMqttMessage(int messageSize) {
  String topic = mqttClient.messageTopic();
  String payload;
  while (mqttClient.available()) {
    payload += (char)mqttClient.read();
  }
  Serial.print("Received on ");
  Serial.print(topic);
  Serial.print(": ");
  Serial.println(payload);

  if (payload == "ON")  matrix.loadFrame(FRAME_ON);
  if (payload == "OFF") matrix.loadFrame(FRAME_OFF);
}

bool connectMqtt() {
  mqttClient.setId(deviceId);
  mqttClient.setKeepAliveInterval(30 * 1000L);   // Millisekunden

  // Der Last Will muss vor connect() gesetzt werden
  mqttClient.beginWill(topicStatus, true, 1);
  mqttClient.print("offline");
  mqttClient.endWill();

  Serial.print("Connecting to MQTT broker... ");
  if (!mqttClient.connect(broker, port)) {
    Serial.print("failed, error = ");
    Serial.println(mqttClient.connectError());
    return false;
  }
  Serial.println("connected");

  mqttClient.onMessage(onMqttMessage);
  mqttClient.subscribe(topicCommand, 1);

  mqttClient.beginMessage(topicStatus, true, 1);   // retained, QoS 1
  mqttClient.print("online");
  mqttClient.endMessage();
  return true;
}

void setup() {
  Serial.begin(115200);
  while (!Serial && millis() < 3000) {}
  matrix.begin();
  connectWifi();
  while (!connectMqtt()) delay(5000);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) connectWifi();
  if (!mqttClient.connected()) {
    delay(5000);
    connectMqtt();
    return;
  }

  mqttClient.poll();   // sendet Keep-Alive-Pings und liefert Nachrichten aus

  if (millis() - lastPublish > 5000) {
    lastPublish = millis();
    int raw = analogRead(A0);
    mqttClient.beginMessage(topicTelemetry);
    mqttClient.print("{\"a0\":");
    mqttClient.print(raw);
    mqttClient.print(",\"rssi\":");
    mqttClient.print(WiFi.RSSI());
    mqttClient.print(",\"uptime\":");
    mqttClient.print(millis() / 1000);
    mqttClient.print("}");
    mqttClient.endMessage();
  }
}

Beobachten Sie die Nachrichten und steuern Sie die Matrix von Ihrem Computer aus:

mosquitto_sub -h broker.connectmq.com -p 1883 -i pc-8d21f0 -t "connectmq/demo/unor4-8d21f0/#" -v
mosquitto_pub -h broker.connectmq.com -p 1883 -i ctl-8d21f0 -t "connectmq/demo/unor4-8d21f0/matrix/set" -m ON

Drehen Sie am Potentiometer, und der Wert a0 sollte innerhalb von fünf Sekunden folgen.

Was ArduinoMqttClient von PubSubClient unterscheidet

Wenn Sie bereits mit PubSubClient gearbeitet haben, werden Ihnen drei Dinge anders vorkommen:

  • Nachrichten werden gestreamt. Mit beginMessage(), print() und endMessage() bauen Sie eine Payload Stück für Stück auf, ohne großen String-Puffer. Das passt gut zum RAM des UNO R4.
  • Eingehende Nachrichten werden wie ein Stream gelesen. Der onMessage-Callback erhält nur die Größe; Sie rufen messageTopic() auf und dann read(), bis available() null liefert.
  • Publishing mit QoS 1 und 2 wird unterstützt, ebenso Retained Messages und ein Last Will, der mit beginWill()/endWill() aufgebaut wird.

Sie müssen poll() trotzdem regelmäßig aufrufen, genau wie loop() bei PubSubClient. Lange delay()-Aufrufe in loop() verzögern Keep-Alive-Pings und eingehende Nachrichten. Unser Leitfaden zur ArduinoMqttClient-Bibliothek behandelt die gesamte API, einschließlich der Bedeutung jedes connectError()-Werts.

Schritt 2: Arduino UNO R4 WiFi MQTT über TLS

Für alles jenseits von Experimenten verwenden Sie einen privaten Broker mit Zugangsdaten und TLS. Bei einem verwalteten MQTT-Broker wie ConnectMQ legen Sie im Portal einen Broker an und erhalten Benutzername, Passwort und Client ID. Dank des Zertifikatsbündels auf dem WLAN-Modul müssen Sie für den Umstieg auf TLS nur wenige Zeilen ändern:

WiFiSSLClient wifiClient;            // vorher WiFiClient
MqttClient mqttClient(wifiClient);

const char broker[] = "broker.connectmq.com";
const int  port     = 8883;          // MQTT über TLS

bool connectMqtt() {
  mqttClient.setId("YOUR_CLIENT_ID");
  mqttClient.setUsernamePassword("YOUR_USERNAME", "YOUR_PASSWORD");
  mqttClient.setKeepAliveInterval(30 * 1000L);
  if (!mqttClient.connect(broker, port)) {
    Serial.print("TLS MQTT failed, error = ");
    Serial.println(mqttClient.connectError());
    return false;
  }
  // abonnieren und veröffentlichen wie bisher
  return true;
}

Bewahren Sie Zugangsdaten in arduino_secrets.h statt im Haupt-Sketch auf, damit Sie sie nicht versehentlich committen. ConnectMQ bindet Client IDs an die ausgestellten Zugangsdaten, kopieren Sie die Client ID also exakt. Auf einem privaten Broker können Sie außerdem das Präfix connectmq/demo/ weglassen und einen eigenen Topic-Baum für Ihr Projekt entwerfen. Der Artikel Best Practices für MQTT-Sicherheit nennt weitere Härtungsschritte.

Skalierbare Topics und Payloads entwerfen

Ein einzelnes Board auf dem öffentlichen MQTT-Broker kann jedes beliebige Schema verwenden, aber es lohnt sich, Topics so zu entwerfen, als hätten Sie nächsten Monat zehn Boards. Eine vorhersehbare Struktur erlaubt es Dashboards, mit Wildcards zu abonnieren, und hält Befehle sauber von Telemetrie getrennt. Landet das Board später etwa als Signalleuchte oder Zählstation in einer Fertigungshalle, ersetzen Sie <prefix> durch die ISA-95-Ebenen eines Unified Namespace (UNS), zum Beispiel acme/werk-nuernberg/montage/linie-1.

Topic Richtung QoS Retained Zweck
<prefix>/<deviceId>/telemetry Board veröffentlicht 0 Nein Regelmäßige Sensorwerte
<prefix>/<deviceId>/status Board veröffentlicht, Will 1 Ja Anwesenheit online / offline
<prefix>/<deviceId>/matrix/set Board abonniert 1 Nein Befehle von Apps oder Skripten
<prefix>/<deviceId>/config Board abonniert 1 Ja Einstellungen, die bei jedem Start angewendet werden

Das retained config-Topic ist ein praktischer Trick: Veröffentlichen Sie das gewünschte Sendeintervall oder einen Schwellenwert einmal mit Retain-Flag, und bei jedem Reconnect erhält das Board sofort die neuesten Einstellungen, ohne zusätzliche Abfragelogik in Ihrer Firmware.

Halten Sie Payloads kompakt. Der RA4M1 des UNO R4 hat 32 KB SRAM, was im Vergleich zum klassischen UNO großzügig, aber immer noch wenig ist. Vermeiden Sie daher in lange laufenden Sketches große String-Objekte. Streaming mit print(), wie im Beispiel, hält den Speicherverbrauch konstant. Bei verrauschten Analogeingängen mitteln Sie mehrere analogRead()-Messungen vor dem Senden und erwägen Sie, nur dann zu veröffentlichen, wenn sich der Wert um mehr als einen kleinen Schwellenwert ändert. Weniger, aber aussagekräftigere Nachrichten schonen das Netzwerk und sind auf einem Dashboard leichter zu lesen.

Checkliste zur Fehlerbehebung

  1. connectError() liefert -2 (Verbindung abgelehnt) oder der Connect-Aufruf scheitert sofort: falscher Host oder Port oder kein WLAN. Prüfen Sie, ob das Board eine echte IP-Adresse hat und nicht 0.0.0.0.
  2. Unverschlüsselt auf 1883 klappt es, auf 8883 nicht: Aktualisieren Sie die Firmware des WLAN-Moduls und stellen Sie sicher, dass Sie WiFiSSLClient statt WiFiClient verwenden.
  3. Fehler 4 (falscher Benutzername oder falsches Passwort) oder 5 (nicht autorisiert): Prüfen Sie alle drei Werte aus dem Portal erneut, einschließlich der Client ID.
  4. Verbindung bricht nach einer Weile ab: Ein blockierender Aufruf in loop() hat poll() ausgebremst, oder ein anderes Gerät verwendet dieselbe Client ID.
  5. Keine eingehenden Nachrichten: onMessage() wurde nicht registriert, oder Sie haben abonniert, bevor connect() erfolgreich war.
  6. Upload klappt, aber der serielle Monitor bleibt leer: Stellen Sie den Monitor auf 115200 Baud; der R4 nutzt natives USB, öffnen Sie den Monitor also erst nach Abschluss des Uploads.

Wie es weitergeht

Sobald die Verbindung zuverlässig steht, fügen Sie einen echten Sensor hinzu und bauen ein Dashboard. Brauchen Sie mehr GPIOs, Bluetooth oder lokale Verarbeitung, ist ein ESP32 vielleicht die bessere Wahl; das ESP32-IoT-Tutorial führt durch ein komplettes Projekt. Besitzen Sie einen anderen Arduino, folgt der Leitfaden zu Arduino Nano 33 IoT und MQTT demselben Bibliotheksmuster mit WiFiNINA.

Bringen Sie Ihren UNO R4 mit ConnectMQ online

ConnectMQ ist ein Cloud-MQTT-Broker mit Unterstützung für MQTT 3.1.1 und 5.0, TLS auf 8883 und WebSockets für Browser-Dashboards. Das Portal enthält einen MQTT-Client im Browser und einen Live-Topic-Explorer, mit dem Sie die Messwerte Ihres UNO eintreffen sehen. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless Broker ohne Kreditkarte und stellen Sie Ihren Sketch noch heute auf TLS um.

Häufig gestellte Fragen

Muss ich ein Root-Zertifikat auf den UNO R4 WiFi hochladen?

Normalerweise nicht. Das ESP32-S3-WLAN-Modul enthält ein Bündel gängiger Root-Zertifikate, sodass WiFiSSLClient Broker prüfen kann, die weithin vertrauenswürdige Zertifizierungsstellen wie Let's Encrypt nutzen. Schlägt die Prüfung fehl, aktualisieren Sie zuerst die Firmware des Moduls.

Kann ich PubSubClient auf dem UNO R4 WiFi verwenden?

Ja, PubSubClient funktioniert mit jedem Arduino-Client, auch mit den Clients von WiFiS3. ArduinoMqttClient ist die offiziell unterstützte Option und bietet zusätzlich Publishing mit QoS 1 und 2.

Unterstützt der UNO R4 WiFi MQTT 5?

ArduinoMqttClient implementiert MQTT 3.1.1, das ConnectMQ neben MQTT 5 vollständig unterstützt. Ihre MQTT-5-Dashboards und -Backends können dieselben Topics abonnieren.

Warum zeigt mein UNO R4 WiFi die IP 0.0.0.0?

WiFiS3 kann eine bestehende Verbindung melden, bevor DHCP abgeschlossen ist. Warten Sie, bis WiFi.localIP() eine echte Adresse liefert, bevor Sie sich mit dem Broker verbinden, wie im Beispiel gezeigt.

Verwandte Artikel

ESP32 NTP MQTT Zeitstempel: genaue Uhrzeit in jeder Nachricht

Synchronisieren Sie die ESP32-Uhr per NTP, formatieren Sie Zeitstempel in ISO 8601 und Epoch-Millisekunden und hängen Sie sie an MQTT-Payloads, damit Messwerte ihren echten Erfassungszeitpunkt behalten, auch wenn sie verspätet veröffentlicht werden.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.