ESP32 MQTT : tutoriel Mosquitto, Home Assistant et ESPHome
Tutoriel ESP32 MQTT : installer Mosquitto, publier des capteurs et piloter un relais avec PubSubClient, découverte Home Assistant, YAML ESPHome et QoS.
Le duo ESP32 et MQTT est la façon la plus répandue de faire dialoguer les capteurs et relais de ta maison entre eux et avec une box domotique comme Home Assistant. MQTT est un protocole de messagerie léger conçu pour les petits appareils : l'ESP32 dépose la température mesurée dans un topic comme "ev/salon/sicaklik", et chaque programme abonné à ce topic reçoit la valeur instantanément. De la même manière, quand tu appuies sur un bouton dans l'application Home Assistant de ton téléphone, la commande "ON" atteint l'ESP32 en bien moins d'une seconde et enclenche le relais. Contrairement à HTTP, il n'ouvre pas une nouvelle connexion à chaque requête ; il fonctionne sur une seule connexion ouverte avec des en-têtes de deux octets seulement, ce qui le rend rapide et économe pour le Wi-Fi comme pour le processeur.
Dans ce guide, tu vas construire de zéro un nœud domotique fonctionnel. Tu découvriras d'abord les notions MQTT de broker, topic, publish et subscribe, puis tu installeras le broker Mosquitto dans Home Assistant ou sur un Raspberry Pi. Ensuite, avec la bibliothèque PubSubClient, tu publieras depuis l'ESP32 la température et l'humidité d'un DHT22, tu écouteras les commandes d'un relais et tu ajouteras MQTT Discovery pour que l'appareil apparaisse tout seul dans Home Assistant. Nous verrons aussi QoS et retain, le message de dernière volonté (LWT) qui affiche l'appareil comme « indisponible » quand la connexion tombe, l'alternative ESPHome qui fait la même chose sans écrire de C++, les différences avec l'ESP8266 et le Raspberry Pi Pico W, ainsi que les erreurs les plus fréquentes une par une.

Qu'est-ce que MQTT et comment ça marche ?
MQTT (Message Queuing Telemetry Transport) repose sur un modèle publication/abonnement. Au centre se trouve un serveur appelé broker ; l'ESP32, Home Assistant, ton téléphone ou un programme sur ton ordinateur s'y connectent en tant que clients. Les clients ne se connaissent pas et ignorent les adresses IP des autres : l'un publie un message dans un topic, et le broker le transmet à tous ceux qui sont abonnés à ce topic. Vois-le comme un bureau de poste : l'ESP32 dépose une lettre dans la boîte "ev/salon/sicaklik", et Home Assistant, qui surveille cette boîte, la reçoit aussitôt. Comme c'est toujours le client qui ouvre la connexion, l'ESP32 n'a besoin ni d'une IP fixe ni d'un port ouvert sur la box ; il lui suffit de connaître l'adresse du broker.
| Notion | À quoi ça sert ? | Exemple |
|---|---|---|
| Broker | Serveur qui reçoit les messages et les distribue aux abonnés | Mosquitto, le broker Mosquitto de Home Assistant |
| Client | Tout appareil ou programme connecté au broker ; chacun a un identifiant unique (client ID) | ESP32, Home Assistant, MQTT Explorer |
| Topic (sujet) | Adresse du message, faite de niveaux séparés par des barres obliques | ev/salon/sicaklik |
| Publish (publier) | Envoyer un message dans un topic | Envoyer la valeur "23.4" dans ev/salon/sicaklik |
| Subscribe (s'abonner) | S'inscrire pour recevoir les messages d'un topic | L'ESP32 qui écoute ev/salon/role/komut |
| Payload (charge utile) | Contenu du message : texte, nombre ou JSON | ON, 23.4, {"sicaklik":23.4} |
| Retain | Le broker garde le dernier message d'un topic et le remet tout de suite aux nouveaux abonnés | État du relais : ON |
| LWT (dernière volonté) | Message que le broker publie au nom d'un client qui disparaît sans prévenir | ev/salon/baglanti : offline |
| QoS | Niveau de garantie de livraison du message (0, 1 ou 2) | QoS 1 pour les commandes du relais |
Pourquoi MQTT ? Comparaison avec un serveur web, Blynk et Telegram
| Méthode | Avantages | Inconvénients | Idéal pour |
|---|---|---|---|
| MQTT + Home Assistant | Local et rapide, bidirectionnel ; des centaines d'appareils sur un tableau de bord, automatisations | Il faut faire tourner un broker | Gérer toute la maison depuis un seul endroit |
| Serveur web sur l'ESP32 | Pas de serveur en plus, s'ouvre dans le navigateur | Chaque appareil a sa propre page, pas d'automatisations entre appareils | Panneau de contrôle d'un seul appareil |
| Blynk IoT | Tableau de bord mobile tout prêt, accès par internet | Dépend du cloud, limites dans l'offre gratuite | Prototypes mobiles rapides |
| Bot Telegram | Notifications instantanées gratuites, pas de port à ouvrir | Ni graphiques ni tableau de bord | Alarmes et commandes simples |
| ESP-NOW | Les cartes ESP communiquent sans box ni broker | Uniquement entre cartes ESP, n'atteint pas Home Assistant directement | Acheminer les données d'un capteur sur pile vers une passerelle |
En bref, MQTT prend tout son intérêt quand le nombre d'appareils grandit : quand tu ajoutes un capteur, tu ne touches à aucun code existant, tu commences simplement à publier dans un nouveau topic. Pour piloter un seul appareil depuis le navigateur, le guide ESP32 Async Web Server et WebSocket va plus vite ; pour des notifications sur le téléphone, vois Bot Telegram avec l'ESP32, et pour un tableau de bord mobile tout prêt, Blynk avec l'ESP32. Pour un capteur au fond du jardin, hors de portée de la box, une bonne solution consiste à envoyer les données par ESP-NOW vers un ESP32 passerelle connecté à MQTT.
Structure des topics MQTT et caractères génériques
Les topics ressemblent à des chemins de dossiers : "ev/salon/sicaklik" (en turc, maison/salon/température) compte trois niveaux et respecte la casse, donc "Ev/Salon" et "ev/salon" sont deux topics différents. Ne commence pas par une barre oblique ("/ev/salon" crée un premier niveau vide) et évite les espaces et les accents ; des lettres simples, des chiffres, des tirets et des tirets bas suffisent. À l'abonnement, tu peux utiliser deux caractères génériques : + remplace exactement un niveau ("ev/+/sicaklik" renvoie la température de toutes les pièces), tandis que # couvre tout ce qui suit et ne peut figurer qu'à la fin ("ev/#" renvoie tous les messages de la maison). Ces jokers ne valent que pour l'abonnement ; un message est toujours publié dans un topic précis. Les topics qui commencent par $ (comme $SYS) sont réservés aux statistiques du broker et ne sont pas couverts par un abonnement à #. Pour le projet de ce guide, nous utiliserons cette organisation :
| Topic | Publié par | Écouté par | Retain |
|---|---|---|---|
| ev/salon/sicaklik | ESP32 (toutes les 30 secondes) | Home Assistant | Oui |
| ev/salon/nem | ESP32 (toutes les 30 secondes) | Home Assistant | Oui |
| ev/salon/role/komut | Home Assistant, téléphone, automatisations | ESP32 | Non |
| ev/salon/role/durum | ESP32 (à chaque changement) | Home Assistant | Oui |
| ev/salon/baglanti | ESP32 (online), broker (offline) | Home Assistant | Oui |
| homeassistant/status | Home Assistant (online au démarrage) | ESP32 | Non |
Installer un broker MQTT : Mosquitto
Le broker MQTT gratuit le plus répandu est Eclipse Mosquitto ; même sur un Raspberry Pi, il traite sans peine des centaines de messages par seconde. Il existe trois façons simples de l'installer : l'application officielle Mosquitto broker si tu utilises Home Assistant OS, le paquet apt sur un Raspberry Pi ou un ordinateur Linux séparé, ou l'installateur Mosquitto sous Windows. Quel que soit ton choix, le broker utilise le port 1883 pour le MQTT non chiffré et le port 8883 pour le MQTT chiffré en TLS, et il doit simplement se trouver sur le même réseau domestique que l'ESP32. Dans Home Assistant, l'installation se déroule ainsi :
- Dans Home Assistant, ouvre Paramètres > Applications (cette section s'appelle Modules complémentaires ou Add-ons dans les anciennes versions), clique sur Installer une application et choisis Mosquitto broker dans la liste.
- Clique sur Installer ; une fois terminé, clique sur Démarrer et laisse activée l'option de démarrage automatique.
- Crée un utilisateur dédié à l'ESP32 : dans Paramètres > Personnes > Utilisateurs, ajoute un utilisateur "esp32" avec un mot de passe solide. Si tu ne vois pas cet onglet, active le mode avancé dans ton profil. Les noms "homeassistant" et "addons" sont réservés au broker, ne les utilise pas.
- Sur la page Paramètres > Appareils et services, l'intégration MQTT apparaît généralement toute seule comme « Découvert » ; clique sur Configurer et valide. Sinon, cherche MQTT via Ajouter une intégration et choisis l'option qui configure Mosquitto automatiquement.
- Dans le code de l'ESP32, tu indiqueras l'adresse IP de Home Assistant comme adresse du broker (par exemple 192.168.1.10), 1883 comme port et l'utilisateur que tu viens de créer.
Sur une machine Linux comme un Raspberry Pi ou Ubuntu, quelques commandes suffisent. Installe le broker et les outils de test avec sudo apt install mosquitto mosquitto-clients. Crée l'utilisateur "esp32" avec sudo mosquitto_passwd -c /etc/mosquitto/passwd esp32 et saisis le mot de passe deux fois ; l'option -c crée le fichier de zéro, alors ne la mets pas quand tu ajoutes un deuxième utilisateur, sinon les précédents seront effacés. Crée ensuite un fichier local.conf dans le dossier /etc/mosquitto/conf.d/, écris-y les trois lignes ci-dessous et redémarre le service avec sudo systemctl restart mosquitto. Sous Windows, ajoute les mêmes lignes au fichier mosquitto.conf du dossier d'installation et redémarre le service Mosquitto Broker.
| Ligne | Signification |
|---|---|
| listener 1883 | Écoute le port 1883 sur toutes les interfaces réseau ; sans cette ligne, Mosquitto 2.x n'accepte que les connexions venant du même ordinateur |
| allow_anonymous false | Refuse les connexions sans nom d'utilisateur ni mot de passe ; c'est déjà le défaut en 2.x, mais l'écrire est une bonne habitude |
| password_file /etc/mosquitto/passwd | Utilise le fichier de mots de passe créé avec mosquitto_passwd ; les mots de passe y sont stockés sous forme de hachage |
Avant de passer à l'ESP32, teste le broker depuis ton ordinateur ; séparer d'emblée les problèmes de broker et de code te fait gagner beaucoup de temps. Dans un terminal, écoute tous les topics de la maison avec mosquitto_sub -h 192.168.1.10 -u esp32 -P tonmotdepasse -t "ev/#" -v. Dans un second terminal, tape mosquitto_pub -h 192.168.1.10 -u esp32 -P tonmotdepasse -t ev/salon/test -m bonjour. Si la ligne "ev/salon/test bonjour" apparaît dans le premier terminal, le broker fonctionne et le mot de passe est bon. L'option -v affiche le topic devant chaque message, et l'option -r envoie le message en mode retain.
Matériel nécessaire et schéma de câblage
Pour ce projet, il te faut une carte de développement ESP32, un capteur de température et d'humidité DHT22, un module relais pilotable en 3,3 V, une breadboard et des fils de liaison. Le DHT22 est plus précis que le DHT11 : il mesure la température à ±0,5 °C et l'humidité à environ ±2–5 %, et fonctionne de -40 à 80 °C ; nous présentons cette famille de capteurs en détail dans Capteur de température et d'humidité DHT11. Si tu as un DHT11, remplace simplement DHT22 par DHT11 dans le code. Pour le premier test de connexion, un ESP32 et un câble USB suffisent ; tu pourras ajouter le capteur et le relais ensuite.



| Connexion | ESP32 | ESP8266 (NodeMCU) | Raspberry Pi Pico W |
|---|---|---|---|
| DHT22 VCC | 3V3 | 3V3 | 3V3(OUT) |
| DHT22 DATA | GPIO 4 | D2 (GPIO 4) | GP15 |
| DHT22 GND | GND | GND | GND |
| Relais VCC | VIN (5V) | VIN (5V) | VBUS (5V) |
| Relais IN | GPIO 26 | D1 (GPIO 5) | GP14 |
| Relais GND | GND | GND | GND |
Installer PubSubClient dans l'IDE Arduino
- Si le paquet de cartes ESP32 n'est pas encore installé dans l'IDE Arduino, installe-le d'abord ; les étapes sont dans Qu'est-ce que l'ESP32 ?.
- Ouvre Outils > Gérer les bibliothèques, tape PubSubClient dans le champ de recherche et installe la bibliothèque de Nick O'Leary. Le code de ce guide a été compilé avec la version 2.8.
- Dans la même fenêtre, cherche DHT sensor library et installe la bibliothèque d'Adafruit ; quand elle demande les dépendances, choisis Install all pour installer aussi Adafruit Unified Sensor.
- Si tu rencontres des problèmes pour installer les bibliothèques, consulte le guide Ajouter une bibliothèque Arduino.
Premier test : connecter l'ESP32 au broker MQTT
Avant d'ajouter les capteurs, vérifions avec le code le plus simple possible que les identifiants Wi-Fi, l'adresse du broker et le mot de passe sont corrects. Le code ci-dessous se connecte au broker, publie "merhaba" (bonjour) dans le topic "test/esp32/durum" et affiche dans le moniteur série chaque message reçu sur "test/esp32/komut". Remplace le nom du Wi-Fi, le mot de passe, l'IP du broker et l'utilisateur MQTT par les tiens, téléverse le code et ouvre le moniteur série à 115200 bauds :
1#include <WiFi.h>
2#include <PubSubClient.h>
3
4const char* WIFI_SSID = "AgAdi"; // Wi-Fi adın (yalnız 2,4 GHz) / your Wi-Fi name (2.4 GHz only)
5const char* WIFI_PASS = "Sifre123"; // Wi-Fi şifren / your Wi-Fi password
6const char* MQTT_SUNUCU = "192.168.1.10"; // broker'ın IP adresi / broker IP address
7const int MQTT_PORT = 1883; // şifresiz MQTT portu / unencrypted MQTT port
8const char* MQTT_KULLANICI = "esp32"; // broker kullanıcı adı / broker username
9const char* MQTT_SIFRE = "mqttSifre"; // broker şifresi / broker password
10
11WiFiClient wifiIstemci; // TCP bağlantısı / TCP connection
12PubSubClient mqtt(wifiIstemci); // MQTT istemcisi / MQTT client
13
14// Abone olunan konuya mesaj gelince çalışır / runs when a subscribed topic receives a message
15void mesajGeldi(char* topic, byte* payload, unsigned int length) {
16 Serial.print("Mesaj [");
17 Serial.print(topic);
18 Serial.print("] ");
19 for (unsigned int i = 0; i < length; i++) {
20 Serial.print((char)payload[i]); // payload sonunda \0 yoktur / payload is not null-terminated
21 }
22 Serial.println();
23}
24
25void setup() {
26 Serial.begin(115200);
27 WiFi.mode(WIFI_STA);
28 WiFi.begin(WIFI_SSID, WIFI_PASS);
29 while (WiFi.status() != WL_CONNECTED) {
30 delay(500);
31 Serial.print(".");
32 }
33 Serial.print("\nIP: ");
34 Serial.println(WiFi.localIP());
35
36 mqtt.setServer(MQTT_SUNUCU, MQTT_PORT); // broker adresi / broker address
37 mqtt.setCallback(mesajGeldi); // gelen mesaj fonksiyonu / incoming message handler
38}
39
40void loop() {
41 if (!mqtt.connected()) {
42 Serial.print("MQTT baglaniyor... ");
43 if (mqtt.connect("esp32-test", MQTT_KULLANICI, MQTT_SIFRE)) { // istemci kimliği benzersiz olmalı / client ID must be unique
44 Serial.println("baglandi");
45 mqtt.subscribe("test/esp32/komut"); // bu konuyu dinle / listen to this topic
46 mqtt.publish("test/esp32/durum", "merhaba"); // ilk mesaj / first message
47 } else {
48 Serial.print("hata, rc=");
49 Serial.println(mqtt.state()); // hata kodu / error code
50 delay(5000);
51 return;
52 }
53 }
54 mqtt.loop(); // mesajları işle, bağlantıyı canlı tut / process messages, keep the connection alive
55}Dès que tu vois "baglandi" (connecté) dans le moniteur série, envoie depuis un terminal de ton ordinateur mosquitto_pub -h 192.168.1.10 -u esp32 -P tonmotdepasse -t test/esp32/komut -m salut ; en quelques millisecondes, la ligne "Mesaj [test/esp32/komut] salut" apparaît dans le moniteur série. Si la connexion échoue, le code affiche un code d'erreur avec mqtt.state() et réessaie au bout de 5 secondes. Ces codes t'indiquent précisément où se trouve le problème :
| rc | Nom dans PubSubClient | Signification et solution |
|---|---|---|
| -4 | MQTT_CONNECTION_TIMEOUT | Le broker n'a pas répondu à temps ; réseau faible ou broker surchargé |
| -3 | MQTT_CONNECTION_LOST | Une connexion établie a été perdue ; le plus souvent parce que loop() n'a pas été appelée pendant longtemps ou que le Wi-Fi a disparu |
| -2 | MQTT_CONNECT_FAILED | La connexion TCP ne s'est jamais ouverte : IP ou port erronés, broker arrêté, Mosquitto en mode local uniquement ou pare-feu qui bloque le 1883 |
| -1 | MQTT_DISCONNECTED | La connexion a été fermée proprement (appel à disconnect) ou n'a jamais été établie |
| 2 | MQTT_CONNECT_BAD_CLIENT_ID | L'identifiant client a été refusé ; un client ID vide ou invalide a été utilisé |
| 4 | MQTT_CONNECT_BAD_CREDENTIALS | Nom d'utilisateur ou mot de passe incorrect (certains brokers renvoient ce code) |
| 5 | MQTT_CONNECT_UNAUTHORIZED | Non autorisé ; Mosquitto renvoie ce code aussi bien pour un mauvais mot de passe que pour une tentative de connexion sans identifiants |
Publier des données de capteur et écouter les commandes du relais avec l'ESP32
Passons maintenant au vrai projet. Le code ci-dessous lit le DHT22 toutes les 30 secondes et publie la température et l'humidité avec le drapeau retain, pilote le relais avec les commandes ON, OFF et TOGGLE reçues sur "ev/salon/role/komut" et publie le nouvel état du relais dans "ev/salon/role/durum". À la connexion, il laisse une dernière volonté au broker, se présente à Home Assistant grâce à MQTT Discovery et, si la connexion tombe, il réessaie toutes les 5 secondes sans bloquer loop(). Grâce au bloc #if defined(ESP8266) en tête, le même code compile aussi tel quel pour un NodeMCU.
1#if defined(ESP8266)
2#include <ESP8266WiFi.h>
3#else
4#include <WiFi.h>
5#endif
6#include <PubSubClient.h>
7#include <DHT.h>
8
9// ---- Ayarlar / Settings ----
10const char* WIFI_SSID = "AgAdi";
11const char* WIFI_PASS = "Sifre123";
12const char* MQTT_SUNUCU = "192.168.1.10"; // broker IP (Home Assistant ya da Raspberry Pi) / broker IP (Home Assistant or Raspberry Pi)
13const int MQTT_PORT = 1883;
14const char* MQTT_KULLANICI = "esp32";
15const char* MQTT_SIFRE = "mqttSifre";
16const char* ISTEMCI_ID = "esp32-salon"; // her cihazda farklı olmalı / must be different on every device
17
18#if defined(ESP8266)
19const int DHT_PIN = 4; // NodeMCU D2
20const int ROLE_PIN = 5; // NodeMCU D1
21#else
22const int DHT_PIN = 4; // ESP32 GPIO 4
23const int ROLE_PIN = 26; // ESP32 GPIO 26
24#endif
25const bool ROLE_AKTIF_LOW = true; // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
26const unsigned long OLCUM_ARALIGI = 30000; // 30 saniyede bir ölçüm / one reading every 30 s
27
28// ---- Konular (topic) / Topics ----
29const char* T_SICAKLIK = "ev/salon/sicaklik";
30const char* T_NEM = "ev/salon/nem";
31const char* T_KOMUT = "ev/salon/role/komut"; // ON, OFF ya da TOGGLE / ON, OFF or TOGGLE
32const char* T_DURUM = "ev/salon/role/durum";
33const char* T_BAGLANTI = "ev/salon/baglanti"; // online / offline (son vasiyet / last will)
34const char* T_HA_DURUM = "homeassistant/status"; // HA açılınca "online" yayınlar / HA publishes "online" when it starts
35
36WiFiClient wifiIstemci;
37PubSubClient mqtt(wifiIstemci);
38DHT dht(DHT_PIN, DHT22);
39
40bool roleAcik = false;
41unsigned long sonOlcum = 0;
42unsigned long sonDeneme = 0;
43
44// Röleyi sür ve yeni durumu kalıcı (retain) yayınla / drive the relay and publish the new state as retained
45void roleAyarla(bool acik) {
46 roleAcik = acik;
47 bool seviye = ROLE_AKTIF_LOW ? !acik : acik;
48 digitalWrite(ROLE_PIN, seviye ? HIGH : LOW);
49 mqtt.publish(T_DURUM, acik ? "ON" : "OFF", true);
50 Serial.println(acik ? "Role: ON" : "Role: OFF");
51}
52
53// Tek bir Home Assistant keşif mesajı gönder / send one Home Assistant discovery message
54void kesifYayinla(const char* tur, const char* nesne, const char* ad, const char* ekAlanlar) {
55 char konu[96];
56 snprintf(konu, sizeof(konu), "homeassistant/%s/%s/%s/config", tur, ISTEMCI_ID, nesne);
57 char json[600];
58 snprintf(json, sizeof(json),
59 "{\"name\":\"%s\",\"unique_id\":\"%s_%s\",%s,\"availability_topic\":\"%s\","
60 "\"device\":{\"identifiers\":[\"%s\"],\"name\":\"Salon ESP32\",\"model\":\"ESP32 + DHT22\"}}",
61 ad, ISTEMCI_ID, nesne, ekAlanlar, T_BAGLANTI, ISTEMCI_ID);
62 if (!mqtt.publish(konu, json, true)) { // false: tampon küçük ya da bağlantı yok / false: buffer too small or not connected
63 Serial.println("Kesif mesaji gonderilemedi");
64 }
65}
66
67// Sıcaklık, nem ve röleyi Home Assistant'a tanıt / announce temperature, humidity and relay to Home Assistant
68void haKesifGonder() {
69 char ek[200];
70 snprintf(ek, sizeof(ek), "\"state_topic\":\"%s\",\"device_class\":\"temperature\",\"unit_of_measurement\":\"°C\",\"state_class\":\"measurement\"", T_SICAKLIK);
71 kesifYayinla("sensor", "sicaklik", "Sıcaklık", ek);
72 snprintf(ek, sizeof(ek), "\"state_topic\":\"%s\",\"device_class\":\"humidity\",\"unit_of_measurement\":\"%%\",\"state_class\":\"measurement\"", T_NEM);
73 kesifYayinla("sensor", "nem", "Nem", ek);
74 snprintf(ek, sizeof(ek), "\"state_topic\":\"%s\",\"command_topic\":\"%s\"", T_DURUM, T_KOMUT);
75 kesifYayinla("switch", "role", "Röle", ek);
76}
77
78// DHT22'yi oku ve değerleri yayınla / read the DHT22 and publish the values
79void olcumGonder() {
80 float t = dht.readTemperature();
81 float h = dht.readHumidity();
82 if (isnan(t) || isnan(h)) {
83 Serial.println("DHT22 okunamadi");
84 return;
85 }
86 char deger[12];
87 snprintf(deger, sizeof(deger), "%.1f", t); // 23.4 gibi / like 23.4
88 mqtt.publish(T_SICAKLIK, deger, true);
89 snprintf(deger, sizeof(deger), "%.0f", h); // 45 gibi / like 45
90 mqtt.publish(T_NEM, deger, true);
91 Serial.printf("Sicaklik %.1f C, nem %.0f %%\n", t, h);
92}
93
94// Abone olunan konulara mesaj gelince çalışır / runs when a subscribed topic receives a message
95void mesajGeldi(char* topic, byte* payload, unsigned int length) {
96 // Önce kopyala: yayın yapınca kütüphane aynı tamponu kullanır / copy first: publishing reuses the same buffer
97 String konu = topic;
98 String mesaj;
99 for (unsigned int i = 0; i < length; i++) mesaj += (char)payload[i];
100 mesaj.trim();
101
102 if (konu == T_KOMUT) {
103 if (mesaj == "ON") roleAyarla(true);
104 else if (mesaj == "OFF") roleAyarla(false);
105 else if (mesaj == "TOGGLE") roleAyarla(!roleAcik);
106 } else if (konu == T_HA_DURUM && mesaj == "online") {
107 haKesifGonder(); // HA yeniden başladı, tanıtımı yenile / HA restarted, announce again
108 mqtt.publish(T_DURUM, roleAcik ? "ON" : "OFF", true);
109 }
110}
111
112bool mqttBaglan() {
113 Serial.print("MQTT baglaniyor... ");
114 // Bağlantı koparsa broker T_BAGLANTI'ya "offline" yazar / if we drop, the broker publishes "offline" to T_BAGLANTI
115 if (!mqtt.connect(ISTEMCI_ID, MQTT_KULLANICI, MQTT_SIFRE, T_BAGLANTI, 1, true, "offline")) {
116 Serial.print("hata, rc=");
117 Serial.println(mqtt.state());
118 return false;
119 }
120 Serial.println("baglandi");
121 mqtt.publish(T_BAGLANTI, "online", true);
122 mqtt.subscribe(T_KOMUT, 1); // komutları QoS 1 ile dinle / listen to commands with QoS 1
123 mqtt.subscribe(T_HA_DURUM);
124 haKesifGonder();
125 mqtt.publish(T_DURUM, roleAcik ? "ON" : "OFF", true);
126 return true;
127}
128
129void setup() {
130 Serial.begin(115200);
131 pinMode(ROLE_PIN, OUTPUT);
132 roleAyarla(false); // güvenli başlangıç: röle kapalı / safe start: relay off
133 dht.begin();
134
135 WiFi.mode(WIFI_STA);
136 WiFi.begin(WIFI_SSID, WIFI_PASS);
137 Serial.print("Wi-Fi");
138 while (WiFi.status() != WL_CONNECTED) {
139 delay(500);
140 Serial.print(".");
141 }
142 Serial.print(" IP: ");
143 Serial.println(WiFi.localIP());
144
145 mqtt.setServer(MQTT_SUNUCU, MQTT_PORT);
146 mqtt.setCallback(mesajGeldi);
147 mqtt.setBufferSize(1024); // keşif JSON'u varsayılan 256 bayta sığmaz / discovery JSON doesn't fit the default 256 bytes
148}
149
150void loop() {
151 if (!mqtt.connected()) {
152 unsigned long simdi = millis();
153 if (sonDeneme == 0 || simdi - sonDeneme >= 5000) { // 5 sn'de bir dene, loop'u kilitleme / retry every 5 s without blocking
154 sonDeneme = simdi;
155 if (mqttBaglan()) sonOlcum = simdi - OLCUM_ARALIGI; // bağlanınca hemen ölç / measure right after connecting
156 }
157 return;
158 }
159 mqtt.loop(); // gelen komutlar ve keep-alive / incoming commands and keep-alive
160
161 if (millis() - sonOlcum >= OLCUM_ARALIGI) {
162 sonOlcum = millis();
163 olcumGonder();
164 }
165}| Ligne | Rôle |
|---|---|
| mqtt.connect(ISTEMCI_ID, ..., T_BAGLANTI, 1, true, "offline") | Déclare la dernière volonté à la connexion : si l'ESP32 disparaît sans prévenir, le broker écrit un "offline" en retain dans ev/salon/baglanti |
| mqtt.publish(T_BAGLANTI, "online", true) | Passe l'état à "online" dès la connexion ; Home Assistant affiche de nouveau l'appareil comme disponible |
| mqtt.subscribe(T_KOMUT, 1) | Écoute les commandes du relais en QoS 1 ; PubSubClient ne prend en charge que les QoS 0 et 1 pour les abonnements |
| mqtt.setBufferSize(1024) | Agrandit le tampon de paquets au-delà des 256 octets par défaut ; le plus gros paquet de découverte fait environ 355 octets |
| mqtt.loop() | Lit les messages entrants et envoie les paquets keep-alive (PINGREQ) ; doit être appelée à chaque tour de loop |
| ROLE_AKTIF_LOW | La plupart des modules relais s'enclenchent sur un signal LOW ; si le tien s'enclenche sur HIGH, mets false |
| OLCUM_ARALIGI | Intervalle de mesure ; le DHT22 se lit au plus toutes les 2 secondes, et 30 à 60 secondes sont idéales pour la température d'une pièce |
Certains détails du code sont voulus. La fonction mesajGeldi() copie d'abord le topic et le payload dans des String, car PubSubClient utilise un seul tampon pour les messages entrants et sortants : dès que tu appelles publish() dans le callback, les données pointées par topic et payload sont écrasées. Le payload ne se termine pas non plus par un \0 comme une chaîne C, c'est pourquoi nous lisons exactement length caractères. Nous utilisons retain pour les mesures et l'état du relais afin que Home Assistant voie la dernière valeur juste après un redémarrage, sans attendre 30 secondes. Le minutage passe lui aussi par millis() : un long delay() dans loop() retarderait les paquets keep-alive et le broker couperait la connexion. Nous détaillons cette technique dans Arduino millis() ou delay().
L'affichage dans Home Assistant : MQTT Discovery
Home Assistant écoute en permanence les topics commençant par le préfixe homeassistant/. Quand un appareil publie une configuration JSON dans un topic de la forme homeassistant/[composant]/[nœud]/[objet]/config, Home Assistant crée automatiquement l'entité correspondante ; c'est ce qu'on appelle MQTT Discovery. Notre code envoie trois messages : deux pour les capteurs (température et humidité) sous homeassistant/sensor/esp32-salon/... et un pour le relais dans homeassistant/switch/esp32-salon/role/config. Comme ils sont en retain, ils survivent à un redémarrage de Home Assistant. Le code est aussi abonné à homeassistant/status : Home Assistant y écrit "online" au démarrage et l'ESP32 se présente de nouveau. Avec beaucoup d'appareils, la documentation de Home Assistant recommande d'ajouter un petit délai aléatoire avant cette nouvelle présentation.
| Champ JSON | Signification | Notre valeur |
|---|---|---|
| name | Nom affiché de l'entité ; le nom de l'appareil est ajouté devant | Sıcaklık (affiché Salon ESP32 Sıcaklık) |
| unique_id | Identifiant permanent de l'entité ; sans lui, son nom et sa pièce ne sont pas modifiables dans l'interface | esp32-salon_sicaklik |
| state_topic | Topic d'où la valeur est lue | ev/salon/sicaklik |
| command_topic | Topic où sont envoyées les commandes de l'interrupteur (switch) | ev/salon/role/komut |
| device_class | Détermine l'icône, les unités possibles et le type de graphique | temperature, humidity |
| unit_of_measurement | Unité de mesure | °C et % |
| state_class | La valeur measurement active les statistiques à long terme et les graphiques | measurement |
| availability_topic | Topic d'où l'état online/offline est lu ; les payloads par défaut sont online et offline | ev/salon/baglanti |
| device | Regroupe les entités sur une seule fiche d'appareil | identifiers, name, model |
Quelques secondes après le téléversement, un appareil nommé "Salon ESP32" apparaît dans Paramètres > Appareils et services > MQTT. Sa fiche contient les capteurs de température et d'humidité ainsi qu'un interrupteur pour le relais ; un clic sur la température ouvre son historique, un clic sur l'interrupteur fait coller le relais. Tu peux ajouter ces entités à un tableau de bord, les exposer aux assistants vocaux ou les utiliser dans des automatisations : par exemple, une règle comme « si le salon dépasse 27 °C, allume le relais du ventilateur et éteins-le sous 25 °C » se crée en quelques clics. Si tu débranches l'ESP32, les entités passent à « Indisponible » au bout de 22 secondes environ au maximum, preuve que la dernière volonté fonctionne. Si tu préfères te passer de la découverte, tu peux aussi déclarer les mêmes entités à la main dans configuration.yaml, en sensor et switch sous mqtt:.
QoS et retain : lequel utiliser et quand ?
La QoS (Quality of Service) définit à quel point tu veux être sûr qu'un message arrive à destination. Un détail important : la QoS s'applique séparément sur deux tronçons. Entre l'émetteur et le broker, c'est la QoS de la publication qui compte ; entre le broker et l'abonné, c'est celle de l'abonnement, et l'abonné obtient la plus faible des deux garanties. PubSubClient ne prend en charge que la QoS 0 en publication et les QoS 0 et 1 en abonnement. Sur le Wi-Fi de la maison, un message perdu en QoS 0 est très rare, mais passer l'abonnement aux commandes en QoS 1 reste une assurance peu coûteuse.
| QoS | Garantie | Fonctionnement | Quand l'utiliser ? |
|---|---|---|---|
| 0 | Au plus une fois | Le message part une seule fois sans accusé de réception ; il peut se perdre si la connexion tombe à ce moment-là | Mesures fréquentes des capteurs |
| 1 | Au moins une fois | Le destinataire confirme par PUBACK, sinon le message est renvoyé ; il peut arriver deux fois | Commandes du relais, alarmes |
| 2 | Exactement une fois | Échange en quatre étapes avec PUBREC, PUBREL et PUBCOMP ; le niveau le plus lent | Compteurs et cas où un doublon pose problème ; non pris en charge par PubSubClient |
Le drapeau retain concerne la mémoire plutôt que la livraison : le broker ne garde que le dernier message retain de chaque topic et l'envoie immédiatement à tout nouvel abonné. C'est idéal pour les messages d'« état actuel » comme les valeurs des capteurs, l'état du relais ou la présence en ligne, mais dangereux pour les commandes et les événements ponctuels. La dernière volonté (LWT) le complète : si le broker ne reçoit aucun paquet du client pendant 1,5 fois la période de keep-alive, il considère la connexion comme perdue et publie le message de dernière volonté. Le keep-alive par défaut de PubSubClient est de 15 secondes, donc un ESP32 débranché apparaît "offline" au bout de 22 secondes environ au maximum. Tu peux modifier cette valeur avec une ligne comme mqtt.setKeepAlive(30), mais plus elle est longue, plus tu remarques tard une coupure.
L'alternative sans code : ESPHome
ESPHome est un outil gratuit qui transforme un appareil décrit dans un fichier YAML en firmware prêt à flasher sur l'ESP32 ; tu n'écris pas une seule ligne de C++. Dans Home Assistant, installe ESPHome Device Builder depuis Paramètres > Applications, ouvre son interface et crée une configuration avec l'assistant Nouvel appareil. Le premier téléversement se fait une seule fois par USB : Chrome ou Edge peuvent programmer la carte directement, et si cela ne marche pas, tu peux flasher le fichier téléchargé par l'assistant avec la page ESPHome Web. Toutes les mises à jour suivantes passent par le Wi-Fi (OTA). La configuration ci-dessous reprend le projet Arduino précédent : elle lit le DHT22 sur le GPIO 4 toutes les 30 secondes et expose le relais actif à l'état bas du GPIO 26 comme interrupteur. Les identifiants Wi-Fi et les mots de passe sont lus avec !secret depuis un fichier secrets.yaml séparé :
1esphome:
2 name: salon-sensor # küçük harf, rakam ve tire / lowercase, digits and hyphens
3 friendly_name: Salon Sensör
4
5esp32:
6 board: esp32dev
7
8logger:
9
10api: # Home Assistant ile doğrudan bağlantı / direct link to Home Assistant
11 encryption:
12 key: !secret api_anahtari
13
14ota:
15 - platform: esphome
16 password: !secret ota_sifresi
17
18wifi:
19 ssid: !secret wifi_ssid
20 password: !secret wifi_sifresi
21 ap: # Wi-Fi yoksa kendi ağını açar / opens its own network if Wi-Fi fails
22 ssid: "Salon-Sensor"
23 password: "yedek1234"
24
25captive_portal:
26
27sensor:
28 - platform: dht
29 pin: GPIO4
30 model: DHT22
31 update_interval: 30s
32 temperature:
33 name: "Sıcaklık"
34 humidity:
35 name: "Nem"
36
37switch:
38 - platform: gpio
39 name: "Röle"
40 pin:
41 number: GPIO26
42 inverted: true # aktif LOW röle / active-LOW relay
43 restore_mode: ALWAYS_OFF # açılışta kapalı / off at boot
44
45# MQTT ile kullanmak için api: bloğunu sil, bunu aç / to use MQTT, delete api: and uncomment this
46# mqtt:
47# broker: 192.168.1.10
48# username: esp32
49# password: !secret mqtt_sifresiUne différence est à connaître : par défaut, ESPHome n'utilise pas MQTT mais sa propre API native chiffrée. Home Assistant trouve l'appareil tout seul sur le réseau et n'a besoin d'aucun broker. Ne choisis MQTT que si d'autres systèmes comme Node-RED doivent lire les mêmes données, ou si tu n'utilises pas Home Assistant. Pour cela, décommente les lignes mqtt: à la fin du fichier et supprime le bloc api: ; sinon, l'appareil redémarre dès que personne ne s'est connecté à l'API native pendant 15 minutes (c'est le réglage reboot_timeout). En mode MQTT, ESPHome envoie lui-même les messages de découverte pour Home Assistant et les messages online/offline sur salon-sensor/status ; il fait donc automatiquement tout ce que nous avons fait à la main dans le code Arduino.
| Critère | PubSubClient (code Arduino) | ESPHome (YAML) |
|---|---|---|
| Programmation | Tu écris tout toi-même en C++ | Uniquement du YAML ; le firmware est compilé automatiquement |
| Ajout dans Home Assistant | Tu envoies toi-même les JSON de découverte | Découvert automatiquement |
| Souplesse | Illimitée ; n'importe quelle bibliothèque ou logique | Limitée aux composants existants, mais des centaines de capteurs sont pris en charge ; du C++ peut être ajouté via des lambdas |
| Mise à jour sans fil | Tu dois ajouter ArduinoOTA toi-même | Intégrée |
| Broker nécessaire | Oui | Non avec l'API native |
| Intérêt pédagogique | Apprend le protocole MQTT et la programmation | Résultat rapide, cache ce qui se passe en dessous |
MQTT avec l'ESP8266 et le Raspberry Pi Pico W
Le code complet ci-dessus fonctionne tel quel sur les cartes ESP8266 NodeMCU et Wemos D1 Mini : quand tu choisis NodeMCU 1.0 dans Outils > Type de carte, le bloc #if defined(ESP8266) sélectionne automatiquement ESP8266WiFi.h au lieu de WiFi.h, ainsi que les broches D2 et D1. Côté Raspberry Pi Pico W, nous utilisons le module MicroPython umqtt.simple. Il n'est pas inclus dans le firmware MicroPython de la Pico W ; installe-le dans Thonny en cherchant umqtt.simple dans Outils > Gérer les paquets, ou tape import mip; mip.install("umqtt.simple") dans le REPL une fois connecté au Wi-Fi. Le module dht nécessaire au DHT22, lui, est fourni avec le firmware. Le code ci-dessous permet à une Pico W placée dans la cuisine d'assurer la même mesure et la même commande du relais. Pour rester court, il ne contient pas les messages de découverte ; pour voir la Pico W dans Home Assistant, publie les mêmes JSON de découverte que dans le code ESP32 avec les topics ev/mutfak, ou déclare les entités à la main sous mqtt: dans configuration.yaml. Enregistre le fichier sous main.py et il se lancera à chaque mise sous tension :
1import network, time, dht
2from machine import Pin
3from umqtt.simple import MQTTClient # önce mip ile kur / install with mip first
4
5WIFI_SSID = "AgAdi" # Wi-Fi adın / your Wi-Fi name
6WIFI_PASS = "Sifre123" # Wi-Fi şifren / your Wi-Fi password
7MQTT_SUNUCU = "192.168.1.10" # broker IP / broker IP
8ISTEMCI_ID = "pico-mutfak" # benzersiz olmalı / must be unique
9
10T_SICAKLIK = b"ev/mutfak/sicaklik"
11T_NEM = b"ev/mutfak/nem"
12T_KOMUT = b"ev/mutfak/role/komut"
13T_DURUM = b"ev/mutfak/role/durum"
14T_BAGLANTI = b"ev/mutfak/baglanti"
15
16sensor = dht.DHT22(Pin(15)) # DHT22 DATA -> GP15
17role = Pin(14, Pin.OUT, value=1) # aktif LOW röle kapalı başlar / active-LOW relay starts off
18led = Pin("LED", Pin.OUT) # Pico W dahili LED / Pico W onboard LED
19
20wlan = network.WLAN(network.STA_IF)
21wlan.active(True)
22wlan.connect(WIFI_SSID, WIFI_PASS)
23while not wlan.isconnected():
24 time.sleep(0.5)
25print("IP:", wlan.ifconfig()[0])
26
27def mesaj_geldi(konu, mesaj): # ikisi de bytes gelir / both arrive as bytes
28 if konu == T_KOMUT and mesaj in (b"ON", b"OFF"):
29 acik = mesaj == b"ON"
30 role.value(0 if acik else 1)
31 led.value(1 if acik else 0)
32 istemci.publish(T_DURUM, mesaj, retain=True)
33
34istemci = MQTTClient(ISTEMCI_ID, MQTT_SUNUCU, user="esp32", password="mqttSifre", keepalive=60) # Mosquitto kullanıcısı / Mosquitto user
35istemci.set_callback(mesaj_geldi)
36istemci.set_last_will(T_BAGLANTI, b"offline", retain=True) # son vasiyet / last will
37
38def baglan():
39 while True:
40 try:
41 if not wlan.isconnected(): # Wi-Fi koptuysa yeniden bağlan / reconnect Wi-Fi if it dropped
42 wlan.connect(WIFI_SSID, WIFI_PASS)
43 time.sleep(5)
44 istemci.connect()
45 istemci.publish(T_BAGLANTI, b"online", retain=True)
46 istemci.publish(T_DURUM, b"OFF" if role.value() else b"ON", retain=True)
47 istemci.subscribe(T_KOMUT)
48 print("MQTT baglandi")
49 return
50 except Exception as e: # MQTTException(5): yetki yok / not authorized
51 print("MQTT hatasi:", e)
52 time.sleep(5)
53
54baglan()
55son = time.ticks_add(time.ticks_ms(), -30000) # ilk ölçüm hemen / first reading right away
56while True:
57 try:
58 istemci.check_msg() # bekleyen komut var mı? / any pending command?
59 if time.ticks_diff(time.ticks_ms(), son) >= 30000:
60 son = time.ticks_ms()
61 try:
62 sensor.measure()
63 except OSError:
64 print("DHT22 okunamadi")
65 istemci.ping() # veri yoksa da bağlantıyı canlı tut / keep the link alive without data
66 else:
67 istemci.publish(T_SICAKLIK, "{:.1f}".format(sensor.temperature()).encode(), retain=True)
68 istemci.publish(T_NEM, "{:.0f}".format(sensor.humidity()).encode(), retain=True)
69 except OSError:
70 print("Baglanti koptu, yeniden baglaniliyor")
71 time.sleep(5)
72 baglan()
73 time.sleep_ms(100)Idées de projets ESP32 MQTT
- Carte des températures pièce par pièce : Place dans chaque pièce un ESP32 avec un DHT22 ou un BME280 et suis toute la maison sur un seul graphique grâce à un abonnement à ev/+/sicaklik.
- Lampe et prise connectées : Relie le relais à une automatisation Home Assistant qui l'allume au coucher du soleil et l'éteint à minuit.
- Capteur de porte et de fenêtre : Avec un interrupteur reed, envoie un message MQTT à l'ouverture de la porte et reçois une notification quand personne n'est à la maison.
- Éclairage de couloir sur détection : Laisse un capteur PIR publier les mouvements et une automatisation Home Assistant allumer la lumière.
- Station d'arrosage : Publie la valeur du capteur d'humidité du sol et lance la pompe par une commande MQTT quand la terre est sèche.
- Suivi de consommation : Mesure le courant d'un appareil avec un capteur de courant ACS712 et trace sa consommation quotidienne.
- Capteur sur pile : Construis un nœud qui mesure, envoie la valeur par MQTT puis se rendort ; les détails sont dans ESP32 Deep Sleep.
Erreurs ESP32 MQTT fréquentes et solutions
| Symptôme ou message | Cause | Solution |
|---|---|---|
| rc=-2 en permanence | IP ou port du broker erronés, broker arrêté ou Mosquitto en mode local uniquement | Vérifie l'IP, ajoute listener 1883 à la configuration, autorise le port 1883 dans le pare-feu |
| rc=5 | Nom d'utilisateur ou mot de passe incorrect, ou tentative de connexion sans identifiants | Teste le mot de passe depuis l'ordinateur avec mosquitto_sub ; recrée l'utilisateur si besoin |
| Se connecte, décroche au bout de quelques secondes, en boucle | Deux appareils utilisent le même client ID ; Mosquitto écrit "Client esp32-salon already connected, closing old connection." dans son journal | Donne à chaque appareil un ISTEMCI_ID unique |
| Les messages de découverte ne partent pas, publish() renvoie false | Le tampon de PubSubClient fait 256 octets par défaut et le JSON n'y tient pas | Appelle mqtt.setBufferSize(1024) dans setup() |
| rc=-3 fréquent | Un long delay() dans loop() empêche l'envoi des keep-alive, ou le signal Wi-Fi est faible | Gère le temps avec millis() et rapproche la carte de la box |
| Les commandes n'arrivent pas à l'ESP32 | Le nom du topic diffère par la casse ou l'orthographe, ou subscribe() n'est pas refait après reconnexion | Vérifie le topic avec mosquitto_sub ; place les lignes subscribe() dans la fonction de connexion |
| Le relais s'allume tout seul au démarrage | Un ancien message retain traîne sur le topic de commande | Efface-le avec mosquitto_pub -r -n -t ev/salon/role/komut |
| Entités « Indisponible » dans Home Assistant | Le topic de disponibilité indique offline ou online est écrit autrement | Écoute ev/salon/baglanti et vérifie que le code publie online après la connexion |
| Caractères bizarres à la place de la valeur | Le payload ne se termine pas par \0 et a été lu sans utiliser length | Copie le payload avec une boucle jusqu'à length |
| L'appareil ESPHome redémarre toutes les 15 minutes | En mode MQTT, le bloc api: est encore là mais Home Assistant ne s'y connecte jamais | Supprime le bloc api: ou ajoute reboot_timeout: 0s |
Avec un broker, quelques topics et PubSubClient, ton ESP32 est devenu un appareil domotique qui parle la même langue que le reste de la maison. Tu peux ajouter de nouveaux capteurs, d'autres pièces et d'autres cartes comme la Pico W, puis tout gérer depuis un seul tableau de bord Home Assistant. Dans l'application BlueGrays, tu trouveras des projets comme la connexion Wi-Fi de l'ESP32, la mesure de température et d'humidité avec le DHT22, l'éclairage intelligent avec PIR et relais, le contrôle en temps réel par WebSocket et l'arrosage intelligent des plantes, pas à pas avec schémas de câblage et code.
Questions fréquentes
Qu'est-ce que MQTT et à quoi ça sert ?
MQTT est un protocole de messagerie léger dans lequel les appareils envoient et reçoivent des messages via un broker en utilisant des noms de topics. Comme il consomme peu de bande passante et d'énergie, il est idéal pour que de petits appareils comme l'ESP32 envoient des données de capteurs et reçoivent des commandes. Home Assistant, Node-RED et la plupart des systèmes IoT industriels parlent MQTT.
Quel port utilise MQTT ?
Le MQTT non chiffré utilise par défaut le port 1883 et le MQTT chiffré en TLS le port 8883. Le port WebSocket utilisé pour les connexions depuis un navigateur dépend du broker ; sur le broker Mosquitto de Home Assistant, c'est le 1884. Sur un réseau domestique, l'ESP32 se connecte généralement au 1883.
MQTT a-t-il besoin d'internet ?
Non. Si le broker tourne chez toi, sur un Raspberry Pi ou dans Home Assistant, le trafic entre l'ESP32 et le broker reste entièrement sur ton réseau local ; capteurs et relais continuent de fonctionner même si internet est coupé. Internet n'est nécessaire que pour un accès depuis l'extérieur ou pour utiliser un broker dans le cloud.
Pourquoi mon ESP32 n'apparaît-il pas dans Home Assistant ?
Les causes les plus fréquentes sont un message de découverte qui ne tient pas dans le tampon de 256 octets de PubSubClient, un topic config mal écrit ou une erreur de guillemets dans le JSON. Écoute homeassistant/# avec mosquitto_sub pour vérifier que le message arrive au broker et assure-toi que le code contient la ligne mqtt.setBufferSize(1024). L'intégration MQTT de Home Assistant doit aussi être connectée au même broker.
Faut-il choisir ESPHome ou MQTT avec Arduino ?
Si ton but est d'obtenir vite un appareil domotique qui fonctionne, ESPHome demande moins d'efforts : tu écris du YAML, l'appareil apparaît tout seul dans Home Assistant et se met à jour sans fil. Si tu veux apprendre le protocole MQTT, écrire ta propre logique ou travailler avec d'autres systèmes que Home Assistant, Arduino avec PubSubClient est plus souple. Les deux cohabitent sans problème dans la même maison.
Quelle est la différence entre les QoS 0, 1 et 2 de MQTT ?
La QoS 0 envoie le message une fois sans attendre d'accusé de réception, la QoS 1 le renvoie jusqu'à confirmation mais il peut arriver deux fois, et la QoS 2 garantit par un échange en quatre étapes qu'il arrive exactement une fois. La QoS 0 suffit pour les mesures de capteurs et la QoS 1 pour les commandes. PubSubClient ne peut publier qu'en QoS 0 et s'abonner en QoS 0 ou 1.
Projets à réaliser après cet article
Voir tous les projets
Clignotement LED avec ESP32
Enseigne l'utilisation de base des sorties GPIO avec l'ESP32. Nous obtenons un effet de clignotement en allumant et éteignant une LED à partir de la broche numérique. Version ESP32 du projet blink classique sur Arduino UNO ; les commandes de base de blink dans l'environnement Arduino restent les mêmes, mais le brochage et les niveaux GPIO de 3,3 V de l'ESP32 diffèrent de ceux de l'Arduino UNO.

Connexion Wi-Fi STA ESP32 (avec écran LCD)
Dans ce projet, nous connectons l'ESP32 au réseau Wi-Fi domestique en mode Station (STA) de manière sécurisée et tolérante aux pannes. Nous isolons SSID/mot de passe dans un fichier secrets.h pour empêcher leur fuite sur Git, mettons en place une reconnexion automatique, et affichons le niveau RSSI et l'adresse IP sur un écran LCD I2C. La LED intégrée sert d'indicateur d'état.

ESP32 DHT22 Température et humidité (avec écran LCD)
Il s'agit d'un projet permettant de mesurer la température ambiante et le taux d'humidité à l'aide d'un capteur DHT22 et d'afficher ces données en temps réel sur un écran LCD I2C 16x2. Les données du capteur sont lues à l'aide du protocole one-wire grâce à la bibliothèque Adafruit DHT. Ce projet constitue la base des stations météo IoT, de la domotique ou des systèmes de surveillance de l'environnement dans les serres.

Éclairage Intelligent ESP32 (PIR + LDR + Relais + OLED)
Transformez votre couloir, votre salle de bain ou votre garde-manger en éclairage intelligent avec l'ESP32 ! En utilisant un capteur de mouvement PIR, un capteur de lumière LDR et un module relais, nous construisons le scénario classique "la lumière s'allume lorsqu'un mouvement est détecté dans l'obscurité" — si l'environnement est déjà lumineux, le mouvement N'ACTIVE PAS la lumière, économisant ainsi de l'énergie pendant la journée. La lumière reste allumée pendant 30 secondes ; si le mouvement

Compteur ESP32 WebSocket (2 boutons + écran LCD + affichage Web en temps réel)
Dans ce projet, deux boutons reliés à l'ESP32 (GPIO 5 incrémente, GPIO 4 décrémente) modifient un compteur. La valeur se met à jour instantanément sur un écran LCD I2C 16x2 et, grâce au support WebSocket d'ESPAsyncWebServer, dans tous les navigateurs connectés sans recharger la page. Au lieu du polling HTTP, une seule connexion persistante est utilisée et l'ESP32 envoie la nouvelle valeur à tous avec ws.textAll().

ESP32 mDNS : accès à l'appareil via bluegrays-esp.local (avec écran LCD)
Dans ce projet, en ajoutant un service mDNS (Multicast DNS) à l'ESP32, nous permettons d'accéder à l'appareil via un nom d'hôte lisible, tel que bluegrays-esp.local, plutôt qu'à l'aide d'une adresse IP. Même si l'adresse IP attribuée par le DHCP venait à changer, vous pourrez toujours accéder à l'appareil sous le même nom. En exécutant également un petit serveur web sur l'appareil, nous envoyons des commandes de contrôle des LED depuis un navigateur via l'adresse http://bluegrays-esp.local/.

Système d'Alarme de Mouvement ESP32 (PIR + Buzzer + LED + Telegram)
Un système d'alarme de sécurité intelligent qui active le buzzer et la LED lorsque le capteur PIR détecte un mouvement, tout en envoyant une notification instantanée au propriétaire via Telegram. Il intègre un délai d'attente de 30 secondes pour limiter la fréquence des alarmes répétées ; ce mécanisme ne vérifie pas la validité des détections du capteur PIR et n'élimine pas les faux déclenchements. Idéal pour la sécurité domestique, la surveillance de garage, d'entrepôts ou de bureaux. Avec l'ES
Autres articles
Application BlueGrays
Réalise ce montage pas à pas sur ton téléphone
Schéma, code et liste des composants sur un seul écran. Plus de 200 projets Arduino, ESP32 et Pico à réaliser.
Scanne avec ton téléphone
Pointe l’appareil photo vers le code : la boutique d’applications de ton téléphone s’ouvre.
ou ouvre la boutique

