ESP32 et Arduino

Tutoriel Arduino UNO R4 WiFi MQTT : publier des données de capteur avec ArduinoMqttClient

Connectez l'Arduino UNO R4 WiFi à un broker MQTT avec WiFiS3 et ArduinoMqttClient, publiez des lectures analogiques, pilotez la matrice LED depuis votre ordinateur et passez au TLS sur le port 8883.

Carte Arduino UNO R4 WiFi avec sa matrice LED allumée, illustrant une connexion Arduino UNO R4 WiFi MQTT vers le cloud
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

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 :

  1. 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 WiFiSSLClient sans coller le moindre certificat.
  2. 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() et endMessage() 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 onMessage ne reçoit que la taille ; vous appelez messageTopic() puis read() jusqu'à ce que available() 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

  1. 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.
  2. Le port 1883 en clair fonctionne mais 8883 échoue : mettez à jour le firmware du module Wi-Fi et vérifiez que vous utilisez WiFiSSLClient et non WiFiClient.
  3. Erreur 4 (nom d'utilisateur ou mot de passe incorrect) ou 5 (non autorisé) : revérifiez les trois valeurs du portail, client ID compris.
  4. 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.
  5. Aucun message entrant : onMessage() n'a pas été enregistré, ou vous vous êtes abonné avant que connect() ne réussisse.
  6. 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.

Articles liés

Exemple MQTT ESP-IDF : construire un client esp-mqtt à partir de zéro

Construisez un projet ESP-IDF à partir d'un dossier vide avec le composant esp-mqtt : configuration du Wi-Fi en mode station, gestionnaire d'événements MQTT, publication et abonnement, propriétés MQTT 5 et TLS avec le bundle de certificats.

9 min de lecture

Horodatage NTP ESP32 MQTT : ajouter une heure précise à chaque message

Synchronisez l'horloge de l'ESP32 avec NTP, formatez des horodatages ISO 8601 et epoch en millisecondes, et joignez-les aux payloads MQTT pour que les mesures conservent leur véritable heure de capture même lorsqu'elles sont publiées en retard.

8 min de lecture

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.