Tests de brokers

Tester une connexion MQTT ESP32 étape par étape

L'ESP32 ne se connecte pas à MQTT ? Testez Wi-Fi, DNS, port TCP, client ID, identifiants et taille de buffer un par un avec un sketch de diagnostic.

Mis à jour · 8 min de lecture

Tester une connexion MQTT ESP32 étape par étape

Quand un ESP32 refuse de parler à un broker MQTT, le moniteur série n'affiche souvent qu'une ligne peu utile : failed, rc=-2 try again in 5 seconds. Le moyen le plus rapide d'en sortir est de tester la connexion couche par couche (Wi-Fi, DNS, port TCP, handshake MQTT, puis publication) et de s'arrêter à la première couche qui échoue.

Ce guide vous fournit un sketch de diagnostic pour le core Arduino (core ESP32 3.x avec PubSubClient 2.8) qui fait exactement cela, explique chaque résultat et montre comment confirmer côté broker que la carte est bien là.

La checklist en un coup d'œil

ÉtapeCe qui peut mal tournerComment cela se manifeste
1. Log sérieMauvais débit en bauds, aucun logCaractères illisibles ou silence dans le moniteur
2. Wi-FiMauvais SSID/mot de passe, réseau 5 GHz, signal faibleWiFi.status() n'atteint jamais WL_CONNECTED (3)
3. DNSPas de serveur DNS via DHCP, faute de frappe dans l'hôtehostByName échoue
4. Port TCPPare-feu, mauvais port, port TLS avec un client non TLSrc=-2 de PubSubClient
5. MQTT CONNECTClient ID en double, mauvais identifiants, ACLrc=2, rc=4, rc=5
6. PublicationPaquet plus grand que le bufferpublish() renvoie false
7. Rester connectéloop() non appelée, keep alive trop courtrc=-3 au bout d'un moment

Étape 1 : obtenir un log série lisible

Réglez le moniteur sur la même vitesse que Serial.begin() ; 115200 est la convention. Dans l'Arduino IDE, réglez aussi Tools → Core Debug Level sur Info ou Verbose : le core ESP32 affiche alors les événements Wi-Fi et les erreurs TLS que votre sketch ne voit jamais. Dans PlatformIO, utilisez monitor_speed = 115200 et build_flags = -DCORE_DEBUG_LEVEL=4.

Étapes 2 à 6 : le sketch de diagnostic

Flashez ce sketch avant de toucher à votre vrai firmware. Il vérifie chaque couche dans l'ordre et affiche exactement où il s'arrête.

esp32_mqtt_check.ino
#include <WiFi.h>
#include <PubSubClient.h>

const char* WIFI_SSID = "your-ssid";
const char* WIFI_PASS = "your-wifi-password";
const char* MQTT_HOST = "broker.connectmq.com";
const uint16_t MQTT_PORT = 1883;
const char* MQTT_USER = "username";   // nullptr si le broker autorise l'accès anonyme
const char* MQTT_PASS = "password";

WiFiClient net;
PubSubClient mqtt(net);
String clientId;

bool check() {
  Serial.println("\n[1] Wi-Fi");
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  unsigned long t0 = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - t0 < 20000) { delay(250); Serial.print('.'); }
  if (WiFi.status() != WL_CONNECTED) {
    Serial.printf("\nWi-Fi failed, status=%d\n", WiFi.status());
    return false;
  }
  Serial.printf("\nIP %s  gateway %s  RSSI %d dBm\n", WiFi.localIP().toString().c_str(),
                WiFi.gatewayIP().toString().c_str(), WiFi.RSSI());

  Serial.println("[2] DNS");
  IPAddress ip;
  if (!WiFi.hostByName(MQTT_HOST, ip)) { Serial.println("DNS lookup failed"); return false; }
  Serial.printf("%s -> %s\n", MQTT_HOST, ip.toString().c_str());

  Serial.println("[3] TCP port");
  if (!net.connect(ip, MQTT_PORT)) { Serial.println("TCP connect failed"); return false; }
  Serial.println("TCP OK");
  net.stop();

  Serial.println("[4] MQTT CONNECT");
  clientId = "esp32-" + WiFi.macAddress();
  clientId.replace(":", "");
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setBufferSize(1024);
  mqtt.setKeepAlive(30);
  if (!mqtt.connect(clientId.c_str(), MQTT_USER, MQTT_PASS)) {
    Serial.printf("MQTT failed, rc=%d\n", mqtt.state());
    return false;
  }
  Serial.printf("MQTT OK as %s\n", clientId.c_str());

  Serial.println("[5] PUBLISH");
  String topic = "testmqtt/esp32-check/" + clientId + "/hello";
  bool ok = mqtt.publish(topic.c_str(), "ESP32 connection test passed");
  Serial.printf("publish to %s: %s\n", topic.c_str(), ok ? "OK" : "FAILED");
  return ok;
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println(check() ? "\nALL CHECKS PASSED" : "\nCHECK FAILED - see the last step above");
}

void loop() {
  mqtt.loop();
}

Lire les résultats

Codes d'état du Wi-Fi

statusSignificationCorrection
1 WL_NO_SSID_AVAILRéseau introuvableVérifiez l'orthographe du SSID ; assurez-vous qu'il émet en 2,4 GHz
4 WL_CONNECT_FAILEDRefusé, généralement mauvais mot de passeRessaisissez le mot de passe ; les réseaux WPA3 seul peuvent nécessiter le mode mixte WPA2/WPA3
6 WL_DISCONNECTEDToujours en tentative ou coupéRapprochez-vous ; un RSSI inférieur à environ -80 dBm n'est pas fiable

Un bon RSSI se situe à peu près entre -50 et -70 dBm. Si le Wi-Fi se connecte mais décroche ensuite, consultez déconnexions Wi-Fi et MQTT sur ESP32.

DNS et TCP

DNS lookup failed signifie que la carte n'a pas reçu de serveur DNS utilisable via DHCP ou que le nom d'hôte est faux. Vérifiez le même nom depuis un portable sur le même réseau avec nslookup broker.connectmq.com. Pour un test temporaire, vous pouvez vous connecter par IP, mais ne livrez pas cela.

TCP connect failed (et rc=-2 dans votre propre firmware) signifie que rien n'a répondu sur cet hôte et ce port. Causes fréquentes : réseau invité ou pare-feu d'entreprise qui bloque le 1883, faute de frappe dans le port, ou port 8883 utilisé avec un WiFiClient classique ; les ports TLS exigent WiFiClientSecure et un certificat de CA, comme le montre MQTT sur TLS avec l'ESP32. Confirmez depuis un portable sur le même Wi-Fi avec nc -vz broker.connectmq.com 1883.

Codes de retour de PubSubClient

rcConstanteCause habituelle
-4MQTT_CONNECTION_TIMEOUTPas de CONNACK à temps, ou keep alive expiré
-3MQTT_CONNECTION_LOSTConnexion perdue ; loop() n'est pas appelée assez souvent
-2MQTT_CONNECT_FAILEDÉchec de la connexion TCP (voir ci-dessus)
-1MQTT_DISCONNECTEDDéconnexion propre / jamais connecté
1MQTT_CONNECT_BAD_PROTOCOLLe broker n'accepte pas MQTT 3.1.1
2MQTT_CONNECT_BAD_CLIENT_IDClient ID refusé (vide, trop long, caractères invalides)
3MQTT_CONNECT_UNAVAILABLEBroker indisponible
4MQTT_CONNECT_BAD_CREDENTIALSNom d'utilisateur ou mot de passe incorrect
5MQTT_CONNECT_UNAUTHORIZEDNon autorisé : identifiants absents ou client non autorisé

Les valeurs positives sont la réponse CONNACK du broker lui-même : le réseau fonctionne, il ne reste que la configuration. La référence des reason codes liste les codes MQTT correspondants, et PubSubClient ne se connecte pas détaille chacun d'eux.

publish() renvoie false

Le buffer par défaut de PubSubClient fait 256 octets et doit contenir le paquet entier : en-tête, topic et payload. Un payload JSON de 200 octets sur un topic long le dépasse déjà, et publish() renvoie simplement false sans que rien n'arrive au broker. Appelez setBufferSize() avant la connexion ; le calculateur de taille de paquet vous indique la taille réelle d'un paquet.

Étape 7 : rester connecté

mqtt.loop() doit s'exécuter souvent, au moins plusieurs fois par intervalle de keep alive. Un delay(60000) dans loop() ou une lecture de capteur bloquante garantit un rc=-3 au bout d'environ une période et demie de keep alive, car le broker ne reçoit jamais de PINGREQ. Remplacez les longs délais par des minuteries basées sur millis() et reconnectez-vous avec un backoff au lieu de bloquer dans une boucle while (!mqtt.connected()).

Confirmer côté broker

Une ligne série qui affiche « OK » n'est que l'avis de l'appareil. Vérifiez de façon indépendante : ouvrez le client MQTT en ligne, connectez-vous au même broker et abonnez-vous à testmqtt/esp32-check/#. Redémarrez la carte : le message hello doit arriver en quelques secondes. Depuis un terminal, la même vérification donne :

Guetter le message de test de l'ESP32
mosquitto_sub -h broker.connectmq.com -p 1883 \
  -u "$MQTT_USER" -P "$MQTT_PASS" \
  -t 'testmqtt/esp32-check/#' -v

Guetter votre ESP32 dans le navigateur

La plupart des problèmes MQTT sur ESP32 ne sont pas des problèmes MQTT : ce sont des soucis de Wi-Fi, de DNS ou de port cachés derrière un seul code de retour. Testez une couche à la fois, lisez la valeur exacte de status ou de rc, et confirmez côté broker avant de passer à votre vrai firmware. Pour la configuration Arduino complète, poursuivez avec MQTT sur ESP32 avec Arduino.

Questions fréquentes

Que signifie "failed, rc=-2" sur un ESP32 ?

C'est MQTT_CONNECT_FAILED de PubSubClient : la connexion TCP vers le broker n'a pas pu s'ouvrir. La cause se situe sous MQTT : pas de Wi-Fi, mauvais hôte ou port, échec DNS, pare-feu, ou port TLS utilisé avec un WiFiClient classique.

Pourquoi mon ESP32 se connecte mais publish() renvoie false ?

Le plus souvent, le message dépasse le buffer de PubSubClient, de 256 octets par défaut en comptant le topic et l'en-tête. Appelez setBufferSize(1024) ou plus avant la connexion et vérifiez la valeur de retour de chaque publish.

L'ESP32 prend-il en charge le Wi-Fi 5 GHz pour MQTT ?

L'ESP32 classique, le S2, le S3 et le C3 n'ont qu'une radio 2,4 GHz et ne peuvent donc pas rejoindre un réseau uniquement 5 GHz. Des puces plus récentes comme l'ESP32-C5 sont bi-bande. Vérifiez votre module exact avant de déboguer MQTT.