ArduinoMqttClient est la bibliothèque MQTT officielle maintenue par Arduino, et elle fonctionne sur tout, de l'UNO R4 WiFi et du Nano 33 IoT aux cartes MKR et à l'ESP32. Ce guide parcourt l'API ArduinoMqttClient dans l'ordre où vous l'utiliserez : configurer, se connecter, appeler poll(), publier, recevoir et définir un message Will. Chaque exemple se connecte à un vrai broker pour que vous puissiez tester au fil de la lecture.
Pourquoi choisir ArduinoMqttClient
ArduinoMqttClient enveloppe n'importe quel objet Client Arduino, comme WiFiClient, WiFiSSLClient, EthernetClient ou un client cellulaire, et y ajoute MQTT 3.1.1. Son choix de conception le plus marquant est que les messages sortants comme entrants sont traités comme des flux : vous n'avez jamais besoin d'un buffer de la taille de votre plus gros message.
| Fonctionnalité | ArduinoMqttClient |
|---|---|
| Protocole | MQTT 3.1.1 |
| QoS en publication | 0, 1 et 2 |
| QoS en abonnement | 0, 1 et 2 |
| Retained messages | Oui |
| Message Will | Oui, en flux avec beginWill() / endWill() |
| Gestion du payload | En flux (print() / read()) |
| Modèle d'événements | Scrutation avec poll(), callback à la réception |
| Mainteneur | Arduino |
Si vous connaissez déjà PubSubClient, le tutoriel PubSubClient pour Arduino est un point de comparaison utile ; les deux bibliothèques résolvent le même problème avec des compromis différents.
Installer la bibliothèque
Ouvrez Outils → Gérer les bibliothèques dans l'Arduino IDE, recherchez « ArduinoMqttClient » et installez-la. Il vous faut aussi la bibliothèque réseau de votre carte :
| Carte | Bibliothèque réseau | Client en clair | Client TLS |
|---|---|---|---|
| UNO R4 WiFi | WiFiS3 | WiFiClient |
WiFiSSLClient |
| Nano 33 IoT, MKR WiFi 1010 | WiFiNINA | WiFiClient |
WiFiSSLClient |
| ESP32 | WiFi (core) | WiFiClient |
WiFiClientSecure |
| Cartes avec shield Ethernet | Ethernet | EthernetClient |
Non intégré |
Configurer le client
Créez d'abord le client réseau, puis passez-le à MqttClient :
#include <WiFiNINA.h> // ou WiFiS3.h, WiFi.h ...
#include <ArduinoMqttClient.h>
WiFiClient net;
MqttClient mqttClient(net);
Avant d'appeler connect(), définissez les paramètres de session :
mqttClient.setId("acm-51e09b"); // client ID, jamais vide
mqttClient.setUsernamePassword("YOUR_USERNAME", "YOUR_PASSWORD"); // facultatif
mqttClient.setKeepAliveInterval(30 * 1000L); // millisecondes !
mqttClient.setConnectionTimeout(10 * 1000L); // millisecondes
mqttClient.setCleanSession(true);
Attention aux unités : contrairement à PubSubClient, les valeurs de keep alive et de timeout sont en millisecondes. Passer 30 au lieu de 30000 donne un keep alive de zéro seconde après division entière, ce qui désactive complètement le keep alive : les connexions mortes passent alors inaperçues pour le broker et votre message Will n'est jamais déclenché.
Se connecter et lire connectError()
connect(host, port) renvoie 1 en cas de succès et 0 en cas d'échec. En cas d'échec, connectError() vous en donne la raison :
| connectError() | Constante | Signification et solution |
|---|---|---|
| -2 | MQTT_CONNECTION_REFUSED |
Impossible d'ouvrir le socket : problème de Wi-Fi, de DNS, de port ou de TLS |
| -1 | MQTT_CONNECTION_TIMEOUT |
Pas de CONNACK à temps : mauvais type de port ou liaison médiocre |
| 0 | MQTT_SUCCESS |
Connecté |
| 1 | MQTT_UNACCEPTABLE_PROTOCOL_VERSION |
Le broker a refusé MQTT 3.1.1 (rare) |
| 2 | MQTT_IDENTIFIER_REJECTED |
Client ID vide ou non autorisé |
| 3 | MQTT_SERVER_UNAVAILABLE |
Le broker n'accepte pas de connexions pour le moment |
| 4 | MQTT_BAD_USER_NAME_OR_PASSWORD |
Identifiants incorrects |
| 5 | MQTT_NOT_AUTHORIZED |
Client non autorisé, p. ex. client ID ne correspondant pas aux identifiants |
Une fonction de connexion complète et réutilisable :
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;
}
Pour les tests, utilisez broker.connectmq.com sur le port 1883, le serveur MQTT public gratuit, réservé aux tests et aux prototypes. Il accepte les connexions anonymes avec n'importe quel client ID unique et non vide. Gardez vos topics sous un préfixe unique comme connectmq/demo/<your-id>/ et ne publiez rien de sensible.
Pourquoi poll() est essentiel
poll() est le cœur battant d'ArduinoMqttClient. Chaque appel :
- Lit les octets entrants depuis le client réseau et analyse les paquets complets.
- Appelle votre callback
onMessage(ou rend le message disponible pourparseMessage()). - Répond aux échanges QoS 1 et QoS 2 des messages entrants.
- Envoie un PINGREQ lorsque l'intervalle de keep alive est sur le point d'expirer.
Si poll() n'est pas appelé pendant plus longtemps que l'intervalle de keep alive, le broker ferme la connexion. Évitez les appels à delay() dépassant une fraction de votre keep alive et remplacez-les par une temporisation basée sur millis() :
unsigned long lastSend = 0;
void loop() {
mqttClient.poll();
if (millis() - lastSend >= 10000) {
lastSend = millis();
// publier ici
}
}
Publier des messages
La publication est un flux en trois étapes :
// Message QoS 0 simple
mqttClient.beginMessage("connectmq/demo/acm-51e09b/temperature");
mqttClient.print(22.7);
mqttClient.endMessage();
// Retenu, QoS 1
mqttClient.beginMessage("connectmq/demo/acm-51e09b/status", true, 1);
mqttClient.print("online");
mqttClient.endMessage();
La signature complète est beginMessage(topic, retain = false, qos = 0, dup = false). Il existe aussi une surcharge qui prend la taille du payload à l'avance, beginMessage(topic, size, retain, qos, dup). Quand vous connaissez la taille exacte, utilisez-la : la bibliothèque peut alors écrire les données directement sur le réseau au lieu de mettre d'abord tout le message en mémoire tampon, ce qui compte pour les gros payloads sur les cartes disposant de peu de RAM.
endMessage() renvoie 1 en cas de succès. Pour les QoS 1 et 2, la bibliothèque gère les paquets d'acquittement lors des appels suivants à poll().
Comme print() accepte les nombres, les chaînes et les flottants, vous pouvez construire du JSON sans buffer temporaire :
mqttClient.beginMessage(topicTelemetry);
mqttClient.print("{\"t\":");
mqttClient.print(temperature, 2);
mqttClient.print(",\"h\":");
mqttClient.print(humidity, 1);
mqttClient.print("}");
mqttClient.endMessage();
Recevoir des messages
Abonnez-vous après une connexion réussie, puis à nouveau après chaque reconnexion si vous utilisez une session propre :
mqttClient.onMessage(onMqttMessage);
mqttClient.subscribe("connectmq/demo/acm-51e09b/cmd/#", 1);
Le callback ne reçoit que la taille du message. Vous lisez le topic et le payload en flux :
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);
}
Les octets que vous ne lisez pas sont abandonnés à l'arrivée du message suivant. Les messages trop volumineux sont donc sans danger : il suffit d'arrêter la lecture à la limite de votre buffer.
Au lieu du callback, vous pouvez appeler int size = mqttClient.parseMessage(); dans loop() et traiter les messages directement lorsque size est supérieur à zéro. Utilisez l'un ou l'autre style, pas les deux.
Messages Will
Un message Will (Last Will and Testament) est publié par le broker si votre appareil se déconnecte sans dire au revoir, par exemple après une coupure de courant ou une perte du Wi-Fi. Configurez-le avant connect() :
const char willTopic[] = "connectmq/demo/acm-51e09b/status";
mqttClient.beginWill(willTopic, true, 1); // retenu, QoS 1
mqttClient.print("offline");
mqttClient.endWill();
if (connectMqtt("broker.connectmq.com", 1883)) {
mqttClient.beginMessage(willTopic, true, 1);
mqttClient.print("online");
mqttClient.endMessage();
}
Publier un online retenu sur le même topic juste après la connexion fournit à chaque tableau de bord un indicateur de présence fiable : online tant que l'appareil est connecté, offline dès que le broker détecte sa disparition, ce qui se produit après environ une fois et demie l'intervalle de keep alive.
Un schéma complet résistant aux reconnexions
Assemblez les éléments avec cette liste :
- Connectez le Wi-Fi et attendez une adresse IP valide.
- Définissez l'ID, les identifiants, le keep alive et le Will.
- Connectez-vous ; en cas d'échec, affichez
connectError()et réessayez après un délai qui augmente à chaque échec. - En cas de succès, enregistrez
onMessage, abonnez-vous et publiezonlineen retenu. - Dans
loop(), vérifiez le Wi-Fi, vérifiezmqttClient.connected(), appelezpoll()et publiez selon un timer basé surmillis().
Des versions de ce schéma propres à chaque carte figurent dans le tutoriel Arduino UNO R4 WiFi MQTT et le guide Nano 33 IoT MQTT avec WiFiNINA. Pour un projet plus large, le tutoriel IoT ESP32 montre comment le côté appareil s'articule avec les tableaux de bord et les alertes.
Erreurs fréquentes avec ArduinoMqttClient
- Appeler
beginWill()aprèsconnect(). Le Will fait partie du paquet CONNECT : il doit donc être configuré avant. - S'abonner uniquement dans
setup(). Après une reconnexion avec une session propre, le broker a oublié vos abonnements. Abonnez-vous plutôt dans votre fonction de connexion. - Réutiliser un même client ID sur plusieurs cartes. Le broker déconnecte l'ancienne session chaque fois qu'une autre carte se connecte, ce qui produit une boucle de reconnexion sans fin.
- Publier depuis
onMessage. Cela fonctionne, mais terminez d'abord la lecture du payload entrant ; sinon les octets non lus sont perdus. - Oublier
endMessage(). Sans lui, rien n'est envoyé et l'appel suivant àbeginMessage()échoue.
Production : TLS et identifiants
Pour de vrais déploiements, passez à un client TLS sur le port 8883 et authentifiez-vous avec vos propres identifiants. Un broker MQTT managé comme ConnectMQ émet un nom d'utilisateur, un mot de passe et un client ID pour chaque broker créé dans le portail ; le client ID est lié à ces identifiants, définissez-le donc exactement avec setId(). Le certificat de ConnectMQ provient de Let's Encrypt, que les modules Wi-Fi des cartes Arduino actuelles reconnaissent d'emblée. Passez en revue les bonnes pratiques de sécurité MQTT avant la mise en production.
Démarrer avec ConnectMQ
ConnectMQ est un broker MQTT cloud compatible MQTT 3.1.1 et 5.0, avec TLS et WebSockets, ainsi qu'un portail comprenant un client MQTT dans le navigateur, un explorateur de topics en direct et des alertes de seuil. C'est le moyen le plus simple de voir ce que votre sketch ArduinoMqttClient envoie réellement. Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire.
Questions fréquentes
ArduinoMqttClient est-il meilleur que PubSubClient ?
Aucun n'est meilleur dans l'absolu. ArduinoMqttClient prend en charge la publication en QoS 1 et 2 et traite les payloads en flux, tandis que PubSubClient est plus léger et dispose d'une immense base d'exemples. Choisissez ArduinoMqttClient pour les cartes Arduino officielles et les besoins en QoS.
ArduinoMqttClient prend-il en charge MQTT 5 ?
Non, il implémente MQTT 3.1.1. Les brokers modernes servent côte à côte des clients 3.1.1 et 5.0 : votre appareil peut donc partager des topics avec des applications MQTT 5.
Pourquoi ma connexion ArduinoMqttClient tombe-t-elle toutes les minutes ?
Généralement, poll() n'est pas appelé assez souvent, le keep alive a été défini en secondes au lieu de millisecondes, ou un autre client utilise le même client ID.
Quelle est la taille maximale d'un message ?
La bibliothèque traite les payloads en flux : la limite est donc surtout celle de votre broker. Le serveur MQTT public gratuit broker.connectmq.com accepte jusqu'à 64 Ko par message ; l'offre Serverless (Free) autorise 256 Ko.



