L'Arduino UNO R4 WiFi apporte le Wi-Fi au format UNO bien connu, ce qui en fait une excellente première carte pour un projet Arduino UNO R4 WiFi MQTT. Dans ce tutoriel, vous utiliserez la bibliothèque WiFiS3 et la bibliothèque officielle ArduinoMqttClient pour publier des lectures de capteur analogique, recevoir des commandes qui dessinent sur la matrice LED intégrée, puis passer à une connexion TLS chiffrée avec vos propres identifiants.
Comment l'UNO R4 WiFi communique avec le réseau
L'UNO R4 WiFi possède deux puces. Le microcontrôleur principal est un Renesas RA4M1 qui exécute votre sketch. La partie réseau est assurée par un module ESP32-S3 qui joue le rôle de coprocesseur Wi-Fi. Votre sketch dialogue avec lui via la bibliothèque WiFiS3, fournie avec le paquet « Arduino UNO R4 Boards ».
Cette répartition a deux conséquences pratiques :
- La poignée de main TLS s'exécute sur le module ESP32-S3, qui embarque un ensemble de certificats racine courants. Les connexions chiffrées vers des brokers dotés de certificats largement reconnus, comme Let's Encrypt, fonctionnent généralement avec
WiFiSSLClientsans coller le moindre certificat. - Le coprocesseur possède son propre firmware. Si les connexions se comportent bizarrement, mettre ce firmware à jour est l'une des premières solutions à essayer.
Pour le protocole MQTT lui-même, vous utiliserez ArduinoMqttClient, la bibliothèque officielle maintenue par Arduino. Elle fonctionne avec n'importe quel objet Client, y compris WiFiClient et WiFiSSLClient de WiFiS3.
Ce dont vous avez besoin
| Élément | Remarques |
|---|---|
| Arduino UNO R4 WiFi | Pas l'UNO R4 Minima, qui n'a pas de radio |
| Arduino IDE 2.x | Avec « Arduino UNO R4 Boards » installé via le gestionnaire de cartes |
| ArduinoMqttClient | À installer depuis le gestionnaire de bibliothèques |
| Un potentiomètre ou n'importe quel capteur analogique | Relié à A0 (facultatif, le code fonctionne avec une broche flottante) |
| Outils en ligne de commande Mosquitto | Pour tester depuis votre ordinateur |
| Un réseau Wi-Fi 2,4 GHz | Le module ne rejoint pas les réseaux 5 GHz |
Avant de commencer, ouvrez Fichier → Exemples → WiFiS3 → CheckFirmwareVersion et téléversez-le. Si le moniteur série signale un firmware obsolète, mettez-le à jour avec l'outil de mise à jour du firmware de l'Arduino IDE (Outils → Firmware Updater) ou en suivant les instructions officielles sur docs.arduino.cc.
Étape 1 : publier sur le serveur MQTT public gratuit
La première version se connecte sans chiffrement à broker.connectmq.com sur le port 1883, le serveur MQTT public gratuit fourni par ConnectMQ pour les tests et les prototypes. Les connexions anonymes sont acceptées tant que le client ID n'est pas vide. Utilisez un préfixe de topic unique et n'envoyez pas de données privées, car n'importe qui peut s'abonner aux topics de ce serveur public.
Créez un second onglet dans le sketch, nommé arduino_secrets.h :
#define SECRET_SSID "YOUR_WIFI"
#define SECRET_PASS "YOUR_WIFI_PASSWORD"
Puis le sketch principal :
#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"; // rendez cet ID unique
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;
// Deux images simples pour la matrice 12x8
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 peut brièvement indiquer 0.0.0.0, attendre une vraie adresse
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); // millisecondes
// Le Last Will doit être défini avant connect()
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(); // envoie les pings keep alive et livre les messages
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();
}
}
Observez les messages et dessinez sur la matrice depuis votre ordinateur :
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
Tournez le potentiomètre : la valeur a0 devrait suivre en moins de cinq secondes.
En quoi ArduinoMqttClient diffère de PubSubClient
Si vous avez déjà utilisé PubSubClient, trois choses vous paraîtront différentes :
- Les messages sont envoyés en flux.
beginMessage(),print()etendMessage()vous permettent de construire un payload morceau par morceau, sans gros buffer de chaîne. Cela convient parfaitement à la RAM de l'UNO R4. - Les messages entrants se lisent comme un flux. Le callback
onMessagene reçoit que la taille ; vous appelezmessageTopic()puisread()jusqu'à ce queavailable()renvoie zéro. - La publication en QoS 1 et 2 est prise en charge, tout comme les retained messages et un Last Will construit avec
beginWill()/endWill().
Vous devez tout de même appeler poll() régulièrement, comme vous appelez loop() avec PubSubClient. De longs appels à delay() dans loop() retardent les pings keep alive et les messages entrants. Notre guide de la bibliothèque ArduinoMqttClient couvre toute l'API, y compris la signification de chaque valeur de connectError().
Étape 2 : Arduino UNO R4 WiFi MQTT sur TLS
Au-delà des expériences, utilisez un broker privé avec identifiants et TLS. Sur un broker MQTT managé comme ConnectMQ, vous créez un broker dans le portail et recevez un nom d'utilisateur, un mot de passe et un client ID. Grâce à l'ensemble de certificats du module Wi-Fi, passer au TLS ne demande de modifier que quelques lignes :
WiFiSSLClient wifiClient; // au lieu de WiFiClient
MqttClient mqttClient(wifiClient);
const char broker[] = "broker.connectmq.com";
const int port = 8883; // MQTT sur 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;
}
// s'abonner et publier comme avant
return true;
}
Gardez les identifiants dans arduino_secrets.h plutôt que dans le sketch principal pour ne pas les committer par accident. ConnectMQ lie les client ID aux identifiants émis : copiez donc le client ID à l'identique. Sur un broker privé, vous pouvez aussi abandonner le préfixe connectmq/demo/ et concevoir une arborescence de topics adaptée à votre projet. L'article sur les bonnes pratiques de sécurité MQTT liste d'autres mesures de durcissement.
Concevoir des topics et des payloads qui passent à l'échelle
Une carte seule sur le serveur MQTT public gratuit peut utiliser n'importe quelle organisation, mais il est payant de concevoir vos topics comme si vous deviez avoir dix cartes le mois prochain. Une structure prévisible permet aux tableaux de bord de s'abonner avec des wildcards et sépare clairement les commandes de la télémétrie.
| Topic | Sens | QoS | Retained | Rôle |
|---|---|---|---|---|
<prefix>/<deviceId>/telemetry |
La carte publie | 0 | Non | Mesures périodiques des capteurs |
<prefix>/<deviceId>/status |
La carte publie, Will | 1 | Oui | Présence online / offline |
<prefix>/<deviceId>/matrix/set |
La carte s'abonne | 1 | Non | Commandes venant d'applications ou de scripts |
<prefix>/<deviceId>/config |
La carte s'abonne | 1 | Oui | Paramètres appliqués à chaque démarrage |
Le topic config retenu est une astuce pratique : publiez une fois l'intervalle de publication ou le seuil souhaité avec le drapeau retain, et à chaque reconnexion la carte reçoit immédiatement les derniers réglages, sans aucune logique de requête supplémentaire dans votre firmware.
Gardez des payloads compacts. Le RA4M1 de l'UNO R4 dispose de 32 Ko de SRAM, ce qui est généreux comparé à l'UNO classique mais reste modeste : évitez donc de construire de gros objets String dans les sketches qui tournent longtemps. Le streaming avec print(), comme dans l'exemple, maintient une consommation mémoire stable. Pour des entrées analogiques bruitées, faites la moyenne de plusieurs échantillons analogRead() avant de publier, et envisagez de ne publier que lorsque la valeur varie au-delà d'un petit seuil. Des messages moins nombreux et plus significatifs ménagent le réseau et se lisent plus facilement sur un tableau de bord.
Liste de vérification pour le dépannage
connectError()renvoie -2 (connexion refusée) ou l'appel de connexion échoue immédiatement : mauvais hôte ou port, ou pas de Wi-Fi. Vérifiez que la carte a une vraie adresse IP, et non 0.0.0.0.- Le port 1883 en clair fonctionne mais 8883 échoue : mettez à jour le firmware du module Wi-Fi et vérifiez que vous utilisez
WiFiSSLClientet nonWiFiClient. - Erreur 4 (nom d'utilisateur ou mot de passe incorrect) ou 5 (non autorisé) : revérifiez les trois valeurs du portail, client ID compris.
- La connexion tombe au bout d'un moment : un appel bloquant dans
loop()a empêchépoll()de s'exécuter, ou un autre appareil utilise le même client ID. - Aucun message entrant :
onMessage()n'a pas été enregistré, ou vous vous êtes abonné avant queconnect()ne réussisse. - Le téléversement fonctionne mais le moniteur série reste vide : réglez le moniteur sur 115200 bauds ; le R4 utilise l'USB natif, ouvrez donc le moniteur une fois le téléversement terminé.
Pour aller plus loin
Une fois la connexion fiable, ajoutez un vrai capteur et construisez un tableau de bord. Si vous avez besoin de plus de GPIO, du Bluetooth ou de traitement local, un ESP32 pourrait mieux vous convenir ; le tutoriel IoT ESP32 présente un projet complet. Si vous possédez une autre carte Arduino, le guide Arduino Nano 33 IoT MQTT suit le même schéma de bibliothèque avec WiFiNINA.
Mettez votre UNO R4 en ligne avec ConnectMQ
ConnectMQ est un broker MQTT cloud qui prend en charge MQTT 3.1.1 et 5.0, le TLS sur 8883 et les WebSockets pour les tableaux de bord dans le navigateur. Le portail comprend un client MQTT dans le navigateur et un explorateur de topics en direct pour voir arriver les mesures de votre UNO. Créez un broker Serverless gratuit sur app.connectmq.com sans carte bancaire et passez votre sketch au TLS dès aujourd'hui.
Questions fréquentes
Dois-je téléverser un certificat racine sur l'UNO R4 WiFi ?
En général, non. Le module Wi-Fi ESP32-S3 embarque un ensemble de certificats racine courants, si bien que WiFiSSLClient peut vérifier les brokers qui utilisent des autorités largement reconnues comme Let's Encrypt. Si la vérification échoue, mettez d'abord à jour le firmware du module.
Puis-je utiliser PubSubClient sur l'UNO R4 WiFi ?
Oui, PubSubClient fonctionne avec n'importe quel Client Arduino, y compris les clients de WiFiS3. ArduinoMqttClient est l'option officiellement prise en charge et ajoute la publication en QoS 1 et 2.
L'UNO R4 WiFi prend-il en charge MQTT 5 ?
ArduinoMqttClient implémente MQTT 3.1.1, entièrement pris en charge par ConnectMQ aux côtés de MQTT 5. Vos tableaux de bord et backends MQTT 5 peuvent s'abonner aux mêmes topics.
Pourquoi mon UNO R4 WiFi affiche-t-il l'IP 0.0.0.0 ?
WiFiS3 peut indiquer un état connecté avant la fin du DHCP. Attendez que WiFi.localIP() renvoie une vraie adresse avant de vous connecter au broker, comme le fait l'exemple.



