ESP32 MQTT: guida con Mosquitto, Home Assistant ed ESPHome
Guida ESP32 MQTT: installa Mosquitto, pubblica dati dei sensori e comanda un relè con PubSubClient, discovery in Home Assistant, YAML di ESPHome e QoS.
La coppia ESP32 e MQTT è il modo più diffuso per far dialogare i sensori e i relè di casa tra loro e con un sistema domotico come Home Assistant. MQTT è un protocollo di messaggistica leggero pensato per i piccoli dispositivi: l'ESP32 deposita la temperatura misurata in un topic come "ev/salon/sicaklik" e ogni programma che ascolta quel topic riceve il valore all'istante. Allo stesso modo, quando premi un pulsante nell'app di Home Assistant sul telefono, il comando "ON" raggiunge l'ESP32 in molto meno di un secondo e fa scattare il relè. A differenza di HTTP non apre una nuova connessione a ogni richiesta; lavora su un'unica connessione aperta con intestazioni di appena due byte, quindi è veloce e pesa poco sia sul Wi-Fi sia sul processore.
In questa guida costruirai da zero un nodo domotico funzionante. Prima imparerai i concetti MQTT di broker, topic, publish e subscribe, poi installerai il broker Mosquitto in Home Assistant o su un Raspberry Pi. Quindi userai la libreria PubSubClient per pubblicare dall'ESP32 temperatura e umidità di un DHT22, ascoltare i comandi per un relè e aggiungere MQTT Discovery, così il dispositivo comparirà da solo in Home Assistant. Vedremo anche QoS e retain, il messaggio di ultime volontà (LWT) che segna il dispositivo come "non disponibile" quando cade la connessione, l'alternativa ESPHome che fa lo stesso senza scrivere C++, le differenze con ESP8266 e Raspberry Pi Pico W e gli errori più comuni uno per uno.

Cos'è MQTT e come funziona?
MQTT (Message Queuing Telemetry Transport) si basa sul modello pubblicazione/sottoscrizione. Al centro c'è un server chiamato broker; l'ESP32, Home Assistant, il tuo telefono o un programma sul computer si collegano a lui come client. I client non si conoscono e non sanno gli indirizzi IP degli altri: uno pubblica un messaggio in un topic e il broker lo inoltra a tutti quelli iscritti a quel topic. Immaginalo come un ufficio postale: l'ESP32 imbuca una lettera nella casella "ev/salon/sicaklik" e Home Assistant, che tiene d'occhio quella casella, la riceve subito. Poiché è sempre il client ad aprire la connessione, l'ESP32 non ha bisogno di un IP fisso né di porte aperte sul router; deve solo conoscere l'indirizzo del broker.
| Concetto | A cosa serve | Esempio |
|---|---|---|
| Broker | Server che riceve i messaggi e li distribuisce agli iscritti | Mosquitto, il broker Mosquitto di Home Assistant |
| Client | Qualsiasi dispositivo o programma collegato al broker; ognuno ha un identificativo univoco (client ID) | ESP32, Home Assistant, MQTT Explorer |
| Topic (argomento) | Indirizzo del messaggio, fatto di livelli separati da barre | ev/salon/sicaklik |
| Publish (pubblicare) | Inviare un messaggio a un topic | Mandare il valore "23.4" a ev/salon/sicaklik |
| Subscribe (iscriversi) | Registrarsi per ricevere i messaggi di un topic | L'ESP32 che ascolta ev/salon/role/komut |
| Payload (contenuto) | Contenuto del messaggio: testo, numero o JSON | ON, 23.4, {"sicaklik":23.4} |
| Retain | Il broker conserva l'ultimo messaggio di un topic e lo consegna subito ai nuovi iscritti | Stato del relè: ON |
| LWT (ultime volontà) | Messaggio che il broker pubblica a nome di un client che si scollega senza preavviso | ev/salon/baglanti: offline |
| QoS | Livello di garanzia di consegna del messaggio (0, 1 o 2) | QoS 1 per i comandi del relè |
Perché MQTT? Confronto con web server, Blynk e Telegram
| Metodo | Vantaggi | Svantaggi | Ideale per |
|---|---|---|---|
| MQTT + Home Assistant | Locale e veloce, bidirezionale; centinaia di dispositivi in un'unica dashboard, automazioni | Serve un broker | Gestire tutta la casa da un unico punto |
| Web server sull'ESP32 | Nessun server aggiuntivo, si apre nel browser | Ogni dispositivo ha la sua pagina, niente automazioni tra dispositivi | Pannello di controllo di un solo dispositivo |
| Blynk IoT | Dashboard per telefono già pronta, accesso via internet | Dipende dal cloud, limiti nel piano gratuito | Prototipi mobili rapidi |
| Bot Telegram | Notifiche istantanee gratuite, nessuna porta da aprire | Niente grafici né dashboard | Allarmi e comandi semplici |
| ESP-NOW | Le schede ESP comunicano senza router né broker | Solo tra schede ESP, non arriva direttamente a Home Assistant | Portare i dati di un sensore a batteria fino a un gateway |
In breve, MQTT dà il meglio quando i dispositivi aumentano: quando aggiungi un nuovo sensore non tocchi nessun codice esistente, inizi semplicemente a pubblicare in un nuovo topic. Se vuoi comandare un solo dispositivo dal browser, la guida ESP32 Async Web Server e WebSocket ti porta al risultato prima; per le notifiche sul telefono c'è Bot Telegram con ESP32 e per una dashboard mobile già pronta Blynk con ESP32. Per un sensore in giardino fuori dalla portata del router, una buona soluzione è portare i dati con ESP-NOW a un ESP32 gateway collegato a MQTT.
Struttura dei topic MQTT e caratteri jolly
I topic somigliano a percorsi di cartelle: "ev/salon/sicaklik" (in turco casa/soggiorno/temperatura) ha tre livelli e distingue maiuscole e minuscole, quindi "Ev/Salon" ed "ev/salon" sono due topic diversi. Non iniziare con una barra ("/ev/salon" crea un primo livello vuoto) ed evita spazi e lettere accentate; bastano lettere semplici, cifre, trattini e trattini bassi. Quando ti iscrivi puoi usare due caratteri jolly: + sostituisce esattamente un livello ("ev/+/sicaklik" restituisce la temperatura di tutte le stanze), mentre # copre tutto ciò che segue e può stare solo alla fine ("ev/#" restituisce tutti i messaggi della casa). I jolly valgono solo per le iscrizioni; un messaggio si pubblica sempre in un topic preciso. I topic che iniziano con $ (come $SYS) sono riservati alle statistiche del broker e non rientrano in un'iscrizione a #. Per il progetto di questa guida useremo questa struttura:
| Topic | Pubblicato da | Ascoltato da | Retain |
|---|---|---|---|
| ev/salon/sicaklik | ESP32 (ogni 30 secondi) | Home Assistant | Sì |
| ev/salon/nem | ESP32 (ogni 30 secondi) | Home Assistant | Sì |
| ev/salon/role/komut | Home Assistant, telefono, automazioni | ESP32 | No |
| ev/salon/role/durum | ESP32 (a ogni cambiamento) | Home Assistant | Sì |
| ev/salon/baglanti | ESP32 (online), broker (offline) | Home Assistant | Sì |
| homeassistant/status | Home Assistant (online all'avvio) | ESP32 | No |
Installare un broker MQTT: Mosquitto
Il broker MQTT gratuito più diffuso è Eclipse Mosquitto; anche su un Raspberry Pi gestisce senza fatica centinaia di messaggi al secondo. Ci sono tre modi semplici per installarlo: l'app ufficiale Mosquitto broker se usi Home Assistant OS, il pacchetto apt su un Raspberry Pi o un computer Linux separato, oppure l'installer di Mosquitto su Windows. Qualunque strada scegli, il broker usa la porta 1883 per MQTT non cifrato e la 8883 per MQTT cifrato con TLS, e deve solo trovarsi nella stessa rete di casa dell'ESP32. In Home Assistant l'installazione funziona così:
- In Home Assistant apri Impostazioni > App (nelle versioni precedenti questa sezione si chiama Componenti aggiuntivi o Add-on), premi Installa app e scegli Mosquitto broker dall'elenco.
- Premi Installa; al termine premi Avvia e lascia attiva l'opzione di avvio automatico.
- Crea un utente apposito per l'ESP32: in Impostazioni > Persone > Utenti aggiungi un utente "esp32" con una password robusta. Se non vedi questa scheda, attiva la modalità avanzata nel tuo profilo. I nomi "homeassistant" e "addons" sono riservati al broker, non usarli.
- Nella pagina Impostazioni > Dispositivi e servizi l'integrazione MQTT di solito compare da sola come "Rilevata"; premi Configura e conferma. Se non compare, cerca MQTT con Aggiungi integrazione e scegli l'opzione che configura Mosquitto automaticamente.
- Nel codice dell'ESP32 inserirai come indirizzo del broker l'IP di Home Assistant (per esempio 192.168.1.10), come porta 1883 e l'utente appena creato.
Su una macchina Linux come un Raspberry Pi o Ubuntu bastano pochi comandi. Installa il broker e gli strumenti di test con sudo apt install mosquitto mosquitto-clients. Crea l'utente "esp32" con sudo mosquitto_passwd -c /etc/mosquitto/passwd esp32 e digita la password due volte; l'opzione -c crea il file da zero, quindi non usarla quando aggiungi un secondo utente, altrimenti quelli precedenti vengono cancellati. Poi crea un file locale.conf nella cartella /etc/mosquitto/conf.d/, scrivi le tre righe qui sotto e riavvia il servizio con sudo systemctl restart mosquitto. Su Windows basta aggiungere le stesse righe al file mosquitto.conf nella cartella di installazione e riavviare il servizio Mosquitto Broker.
| Riga | Significato |
|---|---|
| listener 1883 | Ascolta sulla porta 1883 su tutte le interfacce di rete; senza questa riga Mosquitto 2.x accetta solo connessioni dallo stesso computer |
| allow_anonymous false | Rifiuta le connessioni senza nome utente e password; nella 2.x è già il valore predefinito, ma scriverlo è una buona abitudine |
| password_file /etc/mosquitto/passwd | Usa il file di password creato con mosquitto_passwd; le password vi sono salvate come hash |
Prima di passare all'ESP32, prova il broker dal computer; separare subito i problemi del broker da quelli del codice ti fa risparmiare molto tempo. In un terminale inizia ad ascoltare tutti i topic della casa con mosquitto_sub -h 192.168.1.10 -u esp32 -P latuapassword -t "ev/#" -v. In un secondo terminale scrivi mosquitto_pub -h 192.168.1.10 -u esp32 -P latuapassword -t ev/salon/test -m ciao. Se nel primo terminale compare la riga "ev/salon/test ciao", il broker funziona e la password è giusta. L'opzione -v stampa il topic davanti a ogni messaggio, mentre l'opzione -r invia il messaggio come retain.
Materiale necessario e schema di collegamento
Per il progetto ti servono una scheda di sviluppo ESP32, un sensore di temperatura e umidità DHT22, un modulo relè che si possa comandare a 3,3 V, una breadboard e dei cavetti jumper. Il DHT22 è più preciso del DHT11: misura la temperatura con ±0,5 °C e l'umidità con circa ±2–5 % e funziona da -40 a 80 °C; spieghiamo la famiglia di sensori in dettaglio in Sensore di temperatura e umidità DHT11. Se hai un DHT11, cambia semplicemente DHT22 in DHT11 nel codice. Per il primo test di connessione bastano un ESP32 e un cavo USB; sensore e relè puoi aggiungerli dopo.



| Collegamento | 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 |
| Relè VCC | VIN (5V) | VIN (5V) | VBUS (5V) |
| Relè IN | GPIO 26 | D1 (GPIO 5) | GP14 |
| Relè GND | GND | GND | GND |
Installare PubSubClient nell'Arduino IDE
- Se nell'Arduino IDE non è ancora installato il pacchetto delle schede ESP32, installalo prima; i passaggi sono in Cos'è l'ESP32?.
- Apri Strumenti > Gestisci librerie, scrivi PubSubClient nella casella di ricerca e installa la libreria di Nick O'Leary. Il codice di questa guida è stato compilato con la versione 2.8.
- Nella stessa finestra cerca DHT sensor library e installa la libreria di Adafruit; quando ti chiede delle dipendenze, scegli Install all così viene installata anche Adafruit Unified Sensor.
- Se hai problemi a installare le librerie, consulta la guida Come aggiungere librerie in Arduino.
Primo test: collegare l'ESP32 al broker MQTT
Prima di aggiungere i sensori verifichiamo con il codice più semplice possibile che dati del Wi-Fi, indirizzo del broker e password siano corretti. Il codice qui sotto si collega al broker, pubblica "merhaba" (ciao) nel topic "test/esp32/durum" e stampa nel Monitor seriale ogni messaggio che arriva su "test/esp32/komut". Sostituisci nome del Wi-Fi, password, IP del broker e utente MQTT con i tuoi, carica il codice e apri il Monitor seriale a 115200 baud:
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}Quando nel Monitor seriale vedi "baglandi" (connesso), invia da un terminale del computer mosquitto_pub -h 192.168.1.10 -u esp32 -P latuapassword -t test/esp32/komut -m ciao; in pochi millisecondi nel Monitor seriale compare la riga "Mesaj [test/esp32/komut] ciao". Se la connessione non riesce, il codice stampa un codice di errore con mqtt.state() e riprova dopo 5 secondi. Questi codici ti dicono esattamente dove sta il problema:
| rc | Nome in PubSubClient | Significato e soluzione |
|---|---|---|
| -4 | MQTT_CONNECTION_TIMEOUT | Il broker non ha risposto in tempo; rete debole o broker sovraccarico |
| -3 | MQTT_CONNECTION_LOST | Una connessione già stabilita è caduta; di solito perché loop() non è stato chiamato a lungo o il Wi-Fi è sparito |
| -2 | MQTT_CONNECT_FAILED | La connessione TCP non si è mai aperta: IP o porta sbagliati, broker spento, Mosquitto in modalità solo locale o un firewall che blocca la 1883 |
| -1 | MQTT_DISCONNECTED | La connessione è stata chiusa correttamente (è stato chiamato disconnect) oppure non è mai stata aperta |
| 2 | MQTT_CONNECT_BAD_CLIENT_ID | Identificativo del client rifiutato; è stato usato un client ID vuoto o non valido |
| 4 | MQTT_CONNECT_BAD_CREDENTIALS | Nome utente o password errati (alcuni broker restituiscono questo codice) |
| 5 | MQTT_CONNECT_UNAUTHORIZED | Non autorizzato; Mosquitto restituisce questo codice sia con una password sbagliata sia quando si tenta di collegarsi senza credenziali |
Pubblicare i dati dei sensori e ascoltare i comandi del relè con l'ESP32
Ora costruiamo il progetto vero e proprio. Il codice qui sotto legge il DHT22 ogni 30 secondi e pubblica temperatura e umidità con il flag retain, comanda il relè con i comandi ON, OFF e TOGGLE che arrivano su "ev/salon/role/komut" e comunica il nuovo stato del relè su "ev/salon/role/durum". Quando si collega lascia al broker un messaggio di ultime volontà, si presenta a Home Assistant con MQTT Discovery e, se la connessione cade, riprova ogni 5 secondi senza bloccare loop(). Grazie al blocco #if defined(ESP8266) in cima, lo stesso codice si compila senza modifiche anche su 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}| Riga | Cosa fa |
|---|---|
| mqtt.connect(ISTEMCI_ID, ..., T_BAGLANTI, 1, true, "offline") | Registra le ultime volontà durante la connessione: se l'ESP32 cade senza preavviso, il broker scrive un "offline" retain in ev/salon/baglanti |
| mqtt.publish(T_BAGLANTI, "online", true) | Porta lo stato a "online" appena connesso; Home Assistant mostra di nuovo il dispositivo come disponibile |
| mqtt.subscribe(T_KOMUT, 1) | Ascolta i comandi del relè con QoS 1; PubSubClient supporta solo QoS 0 e 1 nelle iscrizioni |
| mqtt.setBufferSize(1024) | Ingrandisce il buffer dei pacchetti oltre i 256 byte predefiniti; il pacchetto di discovery più grande è di circa 355 byte |
| mqtt.loop() | Legge i messaggi in arrivo e invia i pacchetti keep-alive (PINGREQ); va chiamato a ogni giro di loop |
| ROLE_AKTIF_LOW | La maggior parte dei moduli relè scatta con un segnale LOW; se il tuo scatta con HIGH, impostalo a false |
| OLCUM_ARALIGI | Ogni quanto misurare; il DHT22 si può leggere al massimo ogni 2 secondi e per la temperatura di una stanza l'ideale è 30–60 secondi |
Alcuni dettagli del codice sono voluti. La funzione mesajGeldi() copia per prima cosa topic e payload in delle String, perché PubSubClient usa un unico buffer per i messaggi in entrata e in uscita: appena chiami publish() dentro la callback, i dati a cui puntano topic e payload vengono sovrascritti. Il payload inoltre non termina con \0 come una stringa C, perciò leggiamo esattamente length caratteri. Usiamo retain per le letture e per lo stato del relè così Home Assistant vede l'ultimo valore subito dopo un riavvio, senza aspettare 30 secondi. Anche i tempi sono gestiti con millis(): un lungo delay() dentro loop() ritarderebbe i pacchetti keep-alive e il broker chiuderebbe la connessione. Spieghiamo questa tecnica in dettaglio in Arduino millis() e delay().
Come appare in Home Assistant: MQTT Discovery
Home Assistant ascolta di continuo i topic che iniziano con il prefisso homeassistant/. Quando un dispositivo pubblica una configurazione JSON in un topic della forma homeassistant/[componente]/[nodo]/[oggetto]/config, Home Assistant crea automaticamente l'entità; questo meccanismo si chiama MQTT Discovery. Il nostro codice invia tre messaggi: due per i sensori (temperatura e umidità) in homeassistant/sensor/esp32-salon/... e uno per il relè in homeassistant/switch/esp32-salon/role/config. Essendo retain, sopravvivono anche a un riavvio di Home Assistant. Il codice è inoltre iscritto a homeassistant/status: all'avvio Home Assistant ci scrive "online" e l'ESP32 si ripresenta. Con molti dispositivi, la documentazione di Home Assistant consiglia di aggiungere un piccolo ritardo casuale prima di questa nuova presentazione.
| Campo JSON | Significato | Il nostro valore |
|---|---|---|
| name | Nome visualizzato dell'entità; davanti viene aggiunto il nome del dispositivo | Sıcaklık (appare come Salon ESP32 Sıcaklık) |
| unique_id | Identificativo permanente dell'entità; senza, nome e area non si possono modificare dall'interfaccia | esp32-salon_sicaklik |
| state_topic | Topic da cui si legge il valore | ev/salon/sicaklik |
| command_topic | Topic a cui si inviano i comandi dell'interruttore (switch) | ev/salon/role/komut |
| device_class | Stabilisce icona, unità disponibili e tipo di grafico | temperature, humidity |
| unit_of_measurement | Unità di misura | °C e % |
| state_class | Il valore measurement attiva le statistiche a lungo termine e i grafici | measurement |
| availability_topic | Topic da cui si legge lo stato online/offline; i payload predefiniti sono online e offline | ev/salon/baglanti |
| device | Raggruppa le entità in un'unica scheda dispositivo | identifiers, name, model |
Pochi secondi dopo il caricamento del codice, in Impostazioni > Dispositivi e servizi > MQTT compare un dispositivo chiamato "Salon ESP32". La sua scheda contiene i sensori di temperatura e umidità e un interruttore per il relè; toccando la temperatura si apre lo storico, azionando l'interruttore il relè scatta. Puoi aggiungere queste entità a una dashboard, esporle agli assistenti vocali o usarle nelle automazioni: per esempio una regola come "se il soggiorno supera i 27 °C accendi il relè del ventilatore e spegnilo sotto i 25 °C" si crea in pochi clic. Se scolleghi l'ESP32, le entità passano a "Non disponibile" al massimo dopo circa 22 secondi, segno che le ultime volontà funzionano. Se preferisci non usare la discovery, puoi anche definire le stesse entità a mano nel file configuration.yaml, come sensor e switch sotto mqtt:.
QoS e retain: quale usare e quando?
La QoS (Quality of Service) stabilisce quanto vuoi essere sicuro che un messaggio arrivi a destinazione. Un dettaglio importante: la QoS si applica separatamente su due tratte. Tra chi pubblica e il broker vale la QoS della pubblicazione, tra il broker e l'iscritto quella dell'iscrizione; l'iscritto ottiene la garanzia più bassa delle due. PubSubClient supporta solo QoS 0 in pubblicazione e QoS 0 e 1 nelle iscrizioni. Sul Wi-Fi di casa un messaggio perso con QoS 0 è molto raro, ma impostare a QoS 1 l'iscrizione ai comandi resta un'assicurazione a basso costo.
| QoS | Garanzia | Come funziona | Quando usarla |
|---|---|---|---|
| 0 | Al massimo una volta | Il messaggio parte una sola volta senza conferma; può perdersi se la connessione cade proprio in quel momento | Letture frequenti dei sensori |
| 1 | Almeno una volta | Il destinatario conferma con PUBACK e, se la conferma non arriva, il messaggio viene reinviato; può arrivare due volte | Comandi del relè, allarmi |
| 2 | Esattamente una volta | Scambio in quattro passaggi con PUBREC, PUBREL e PUBCOMP; il livello più lento | Contatori e casi in cui i duplicati fanno danni; non supportata da PubSubClient |
Il flag retain riguarda la memoria più che la consegna: il broker conserva solo l'ultimo messaggio retain di ogni topic e lo invia subito a chiunque si iscriva. È ideale per i messaggi di "stato attuale" come i valori dei sensori, lo stato del relè o la presenza online, ma pericoloso per comandi ed eventi singoli. Le ultime volontà (LWT) lo completano: se il broker non riceve alcun pacchetto dal client per 1,5 volte il periodo di keep-alive, considera persa la connessione e pubblica il messaggio di ultime volontà. Il keep-alive predefinito di PubSubClient è di 15 secondi, quindi un ESP32 scollegato appare "offline" al massimo dopo circa 22 secondi. Puoi cambiarlo con una riga come mqtt.setKeepAlive(30), ma più è lungo, più tardi ti accorgi di una disconnessione.
L'alternativa senza codice: ESPHome
ESPHome è uno strumento gratuito che trasforma un dispositivo descritto in un file YAML in un firmware pronto per l'ESP32; non scrivi neanche una riga di C++. In Home Assistant installa ESPHome Device Builder da Impostazioni > App, apri la sua interfaccia e crea una configurazione con la procedura guidata Nuovo dispositivo. Il primo caricamento si fa una sola volta via USB: Chrome o Edge possono programmare la scheda direttamente e, se non funziona, puoi caricare il file scaricato dalla procedura con la pagina ESPHome Web. Tutti gli aggiornamenti successivi passano via Wi-Fi (OTA). La configurazione qui sotto equivale al progetto Arduino precedente: legge il DHT22 sul GPIO 4 ogni 30 secondi e presenta il relè attivo basso sul GPIO 26 come interruttore. I dati del Wi-Fi e le password vengono letti con !secret da un file secrets.yaml separato:
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_sifresiC'è una differenza da tenere a mente: per impostazione predefinita ESPHome non usa MQTT ma la sua API nativa cifrata. Home Assistant trova il dispositivo da solo in rete e non ha bisogno di alcun broker. Scegli MQTT solo se vuoi che anche altri sistemi come Node-RED leggano gli stessi dati o se non usi Home Assistant. Per farlo, togli il commento alle righe mqtt: in fondo al file ed elimina il blocco api:; se non lo elimini, il dispositivo si riavvia ogni volta che per 15 minuti nessuno si collega all'API nativa (è l'impostazione reboot_timeout). In modalità MQTT, ESPHome invia da solo i messaggi di discovery per Home Assistant e i messaggi online/offline su salon-sensor/status, cioè fa automaticamente tutto ciò che abbiamo fatto a mano nel codice Arduino.
| Caratteristica | PubSubClient (codice Arduino) | ESPHome (YAML) |
|---|---|---|
| Programmazione | Scrivi tutto tu in C++ | Solo YAML; il firmware viene compilato automaticamente |
| Aggiunta a Home Assistant | Invii tu i JSON di discovery | Rilevato automaticamente |
| Flessibilità | Illimitata; qualsiasi libreria e logica | Limitata ai componenti già pronti, ma supporta centinaia di sensori; si può aggiungere C++ con le lambda |
| Aggiornamento wireless | Devi aggiungere tu ArduinoOTA | Già incluso |
| Serve un broker | Sì | No con l'API nativa |
| Valore didattico | Insegna il protocollo MQTT e la programmazione | Risultati rapidi, nasconde cosa succede sotto |
MQTT con ESP8266 e Raspberry Pi Pico W
Il codice completo qui sopra funziona senza modifiche sulle schede ESP8266 NodeMCU e Wemos D1 Mini: quando scegli NodeMCU 1.0 in Strumenti > Scheda, il blocco #if defined(ESP8266) seleziona automaticamente ESP8266WiFi.h al posto di WiFi.h e i pin D2 e D1. Sul Raspberry Pi Pico W usiamo invece il modulo MicroPython umqtt.simple. Non è incluso nel firmware MicroPython del Pico W; installalo in Thonny cercando umqtt.simple in Strumenti > Gestisci pacchetti, oppure scrivi import mip; mip.install("umqtt.simple") nella REPL con il Wi-Fi collegato. Il modulo dht che serve per il DHT22, invece, è già nel firmware. Il codice qui sotto fa fare a un Pico W in cucina lo stesso lavoro di misura e di comando del relè. Per tenerlo breve non include i messaggi di discovery; per vedere il Pico W in Home Assistant pubblica gli stessi JSON di discovery del codice ESP32 con i topic ev/mutfak, oppure definisci le entità a mano sotto mqtt: in configuration.yaml. Salva il file come main.py e partirà a ogni accensione della scheda:
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)Idee di progetti ESP32 MQTT
- Mappa della temperatura stanza per stanza: Metti in ogni stanza un ESP32 con un DHT22 o un BME280 e segui tutta la casa in un unico grafico con un'iscrizione a ev/+/sicaklik.
- Lampada e presa smart: Collega il relè a un'automazione di Home Assistant che lo accenda al tramonto e lo spenga a mezzanotte.
- Sensore per porte e finestre: Con un interruttore reed invia un messaggio MQTT quando la porta si apre e ricevi una notifica sul telefono quando non c'è nessuno in casa.
- Luce del corridoio a movimento: Lascia che un sensore PIR pubblichi il movimento e che un'automazione di Home Assistant accenda la luce.
- Stazione di irrigazione: Pubblica il valore del sensore di umidità del terreno e avvia la pompa con un comando MQTT quando la terra è secca.
- Monitoraggio dei consumi: Misura la corrente di un apparecchio con un sensore di corrente ACS712 e traccia il consumo giornaliero.
- Sensore a batteria: Costruisci un nodo che misura, invia il dato via MQTT e torna a dormire; i dettagli sono in ESP32 Deep Sleep.
Errori comuni con ESP32 e MQTT e soluzioni
| Sintomo o messaggio | Causa | Soluzione |
|---|---|---|
| rc=-2 continuo | IP o porta del broker sbagliati, broker spento o Mosquitto in modalità solo locale | Controlla l'IP, aggiungi listener 1883 alla configurazione, consenti la porta 1883 nel firewall |
| rc=5 | Nome utente o password errati, oppure tentativo di connessione senza credenziali | Prova la password dal computer con mosquitto_sub; se serve, ricrea l'utente |
| Si collega, cade dopo pochi secondi e ricomincia | Due dispositivi usano lo stesso client ID; Mosquitto scrive nel log "Client esp32-salon already connected, closing old connection." | Dai a ogni dispositivo un ISTEMCI_ID univoco |
| I messaggi di discovery non partono, publish() restituisce false | Il buffer di PubSubClient è di 256 byte per impostazione predefinita e il JSON non ci sta | Chiama mqtt.setBufferSize(1024) in setup() |
| rc=-3 frequente | Un lungo delay() dentro loop() blocca i keep-alive, oppure il segnale Wi-Fi è debole | Gestisci i tempi con millis() e avvicina la scheda al router |
| I comandi non arrivano all'ESP32 | Il nome del topic differisce per maiuscole o scrittura, oppure subscribe() non viene ripetuto dopo la riconnessione | Verifica il topic con mosquitto_sub; metti le righe subscribe() dentro la funzione di connessione |
| Il relè si accende da solo all'avvio | Sul topic dei comandi c'è un vecchio messaggio retain | Cancellalo con mosquitto_pub -r -n -t ev/salon/role/komut |
| Entità "Non disponibile" in Home Assistant | Il topic di disponibilità dice offline oppure online è scritto in modo diverso | Ascolta ev/salon/baglanti e assicurati che il codice pubblichi online dopo la connessione |
| Caratteri strani al posto del valore | Il payload non termina con \0 ed è stato letto senza usare length | Copia il payload con un ciclo fino a length |
| Il dispositivo ESPHome si riavvia ogni 15 minuti | In modalità MQTT c'è ancora il blocco api:, ma Home Assistant non si collega mai | Elimina il blocco api: o aggiungi reboot_timeout: 0s |
Con un broker, qualche topic e PubSubClient, il tuo ESP32 è diventato un dispositivo domotico che parla la stessa lingua del resto della casa. Puoi aggiungere nuovi sensori, altre stanze e schede diverse come il Pico W e gestire tutto da un'unica dashboard di Home Assistant. Nell'app BlueGrays trovi progetti come la connessione Wi-Fi dell'ESP32, la misura di temperatura e umidità con il DHT22, l'illuminazione intelligente con PIR e relè, il controllo in tempo reale con WebSocket e l'irrigazione intelligente delle piante, passo dopo passo con schemi elettrici e codice.
Domande frequenti
Cos'è MQTT e a cosa serve?
MQTT è un protocollo di messaggistica leggero in cui i dispositivi inviano e ricevono messaggi tramite un broker usando nomi di topic. Poiché consuma poca banda e poca energia, è ideale per far inviare dati dei sensori e ricevere comandi a piccoli dispositivi come l'ESP32. Home Assistant, Node-RED e la maggior parte dei sistemi IoT industriali parlano MQTT.
Che porta usa MQTT?
MQTT non cifrato usa per impostazione predefinita la porta 1883, MQTT cifrato con TLS la 8883. La porta WebSocket per le connessioni dal browser dipende dal broker; sul broker Mosquitto di Home Assistant è la 1884. In una rete domestica l'ESP32 di solito si collega alla 1883.
MQTT ha bisogno di internet?
No. Se il broker gira in casa, su un Raspberry Pi o in Home Assistant, il traffico tra ESP32 e broker resta interamente nella rete locale; sensori e relè continuano a funzionare anche se cade internet. Internet serve solo per accedere dall'esterno o per usare un broker nel cloud.
Perché il mio ESP32 non compare in Home Assistant?
Le cause più comuni sono un messaggio di discovery che non entra nel buffer da 256 byte di PubSubClient, un topic config scritto male o un errore di virgolette nel JSON. Ascolta homeassistant/# con mosquitto_sub per verificare che il messaggio arrivi al broker e assicurati che il codice contenga la riga mqtt.setBufferSize(1024). Inoltre l'integrazione MQTT di Home Assistant deve essere collegata allo stesso broker.
Meglio ESPHome o MQTT con Arduino?
Se vuoi ottenere in fretta un dispositivo domotico funzionante, ESPHome richiede meno lavoro: scrivi YAML, il dispositivo compare da solo in Home Assistant e si aggiorna via Wi-Fi. Se vuoi imparare il protocollo MQTT, scrivere la tua logica o lavorare con sistemi diversi da Home Assistant, Arduino con PubSubClient è più flessibile. I due convivono senza problemi nella stessa casa.
Che differenza c'è tra QoS 0, 1 e 2 in MQTT?
La QoS 0 invia il messaggio una volta senza attendere conferma, la QoS 1 lo reinvia finché non viene confermato ma può arrivare due volte, e la QoS 2 garantisce con uno scambio in quattro passaggi che arrivi esattamente una volta. Per le letture dei sensori basta la QoS 0, per i comandi la QoS 1. PubSubClient può pubblicare solo con QoS 0 e iscriversi con QoS 0 o 1.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
LED Lampeggiante con ESP32
Insegna l'uso di base delle uscite GPIO con l'ESP32. Otteniamo un effetto lampeggiante accendendo e spegnendo un LED dal pin digitale. Versione ESP32 del classico progetto blink su Arduino UNO; i comandi di base di blink nell'ambiente Arduino sono gli stessi, ma la disposizione dei pin e i livelli GPIO a 3,3 V dell'ESP32 sono diversi da quelli di Arduino UNO.

Connessione Wi-Fi STA con ESP32 (con display LCD)
In questo progetto colleghiamo l'ESP32 alla rete Wi-Fi domestica in modalità Station (STA) in modo sicuro e tollerante agli errori. Separiamo SSID e password in un file secrets.h per impedire fughe su Git, impostiamo un meccanismo di riconnessione automatica e visualizziamo il livello del segnale RSSI e l'indirizzo IP su un display LCD I2C. Il LED interno funge da indicatore di stato.

ESP32 DHT22 Temperatura e umidità (con display LCD)
Si tratta di un progetto che misura la temperatura e l'umidità dell'ambiente tramite il sensore DHT22 e le visualizza in tempo reale su un display LCD I2C 16x2. I dati vengono letti dal sensore utilizzando il protocollo one-wire tramite la libreria Adafruit DHT. Questo progetto costituisce la base per stazioni meteorologiche IoT, sistemi di automazione domestica intelligente o sistemi di monitoraggio ambientale nelle serre. La comunicazione con il DHT22 avviene tramite il pin GPIO 4 dell'ESP32.

Illuminazione Intelligente ESP32 (PIR + LDR + Relè + OLED)
Trasforma il tuo corridoio, bagno o dispensa in illuminazione intelligente con ESP32! Utilizzando un sensore di movimento PIR, un sensore di luce LDR e un modulo relè, costruiamo lo scenario classico "la luce si accende quando viene rilevato movimento al buio" — se l'ambiente è già luminoso, il movimento NON attiva la luce, risparmiando energia durante il giorno. La luce rimane accesa per 30 secondi; se il movimento continua, il timer si azzera e la luce rimane accesa più a lungo. Il display OLE

Contatore WebSocket ESP32 (2 pulsanti + LCD + Web in tempo reale)
In questo progetto due pulsanti collegati all'ESP32 (GPIO 5 incrementa, GPIO 4 decrementa) modificano un contatore. Il valore si aggiorna all'istante su un display LCD I2C 16x2 e, grazie al supporto WebSocket di ESPAsyncWebServer, in tutti i browser collegati senza ricaricare la pagina. Al posto del polling HTTP si usa un'unica connessione persistente e l'ESP32 invia il nuovo valore a tutti con ws.textAll().

ESP32 mDNS: accesso al dispositivo tramite bluegrays-esp.local (con schermo LCD)
In questo progetto, aggiungendo il servizio mDNS (Multicast DNS) all'ESP32, consentiamo l'accesso tramite un nome host leggibile, come bluegrays-esp.local, anziché tramite l'indirizzo IP. Anche se l'IP assegnato dal DHCP dovesse cambiare, potrete sempre raggiungere il dispositivo con lo stesso nome. Eseguendo anche un piccolo server web, inviamo comandi di controllo dei LED dal browser all’indirizzo http://bluegrays-esp.local/. Sul display LCD I2C vengono visualizzati il nome host, l’IP e lo

Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)
Un sistema di allarme di sicurezza intelligente che attiva buzzer e LED quando il sensore PIR rileva movimento, inviando contemporaneamente una notifica istantanea al proprietario tramite Telegram. Dispone di un tempo di attesa di 30 secondi per limitare la frequenza degli allarmi ripetuti; questo meccanismo non verifica la validità dei rilevamenti del sensore PIR né elimina le false attivazioni. Adatto a sicurezza domestica, monitoraggio di garage, magazzini o studi. Con l'ESP32-CAM è possibile
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 200 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

