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:
- 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
WiFiSSLClientdaher in der Regel, ohne dass Sie ein Zertifikat einfügen müssen. - 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()undendMessage()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 rufenmessageTopic()auf und dannread(), bisavailable()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
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.- Unverschlüsselt auf 1883 klappt es, auf 8883 nicht: Aktualisieren Sie die Firmware des WLAN-Moduls und stellen Sie sicher, dass Sie
WiFiSSLClientstattWiFiClientverwenden. - 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.
- Verbindung bricht nach einer Weile ab: Ein blockierender Aufruf in
loop()hatpoll()ausgebremst, oder ein anderes Gerät verwendet dieselbe Client ID. - Keine eingehenden Nachrichten:
onMessage()wurde nicht registriert, oder Sie haben abonniert, bevorconnect()erfolgreich war. - 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.



