Guide · 15 min di lettura

Bot Telegram con ESP32: notifiche e controllo di LED e relè

Crea un bot Telegram con ESP32: token da BotFather, chat ID, UniversalTelegramBot, avvisi di movimento e gas, relè via comando e risposte solo al tuo ID.

Un bot Telegram con ESP32 permette alla scheda ESP32 di casa tua di mandarti messaggi sul telefono e di eseguire i comandi che le invii. Quando c'è movimento davanti alla porta o viene rilevato gas in cucina, ti arriva subito una notifica; scrivi "/ac" e un relè accende la lampada, scrivi "/kapat" e la spegne. Non devi programmare un'app tua, aprire porte sul router o pagare un servizio cloud: bastano la Bot API gratuita di Telegram e il Wi-Fi integrato dell'ESP32.

In questa guida costruirai da zero un sistema funzionante: creerai un bot con BotFather e otterrai il suo token, scoprirai il tuo chat ID, installerai le librerie UniversalTelegramBot e ArduinoJson e invierai il primo messaggio dall'ESP32. Poi aggiungerai gli avvisi di movimento e gas con un sensore PIR e un sensore di gas MQ-2, e il controllo di un LED e di un relè con i comandi di Telegram. Vedremo anche come far rispondere il bot solo al tuo ID, come funziona l'impostazione del certificato, cosa cambia su ESP8266 e Raspberry Pi Pico W e quali sono gli errori più comuni.

Scheda di sviluppo ESP32 usata come bot Telegram
Grazie al Wi-Fi integrato, l'ESP32 si collega direttamente al server di Telegram; non servono moduli o gateway aggiuntivi.

Cos'è un bot Telegram con ESP32 e come funziona?

Su Telegram un bot è un account speciale gestito da un programma invece che da una persona; nel nostro progetto quel programma gira sull'ESP32. L'ESP32 e il telefono non si collegano mai direttamente: entrambi parlano con il server di Telegram. Quando scrivi "/ac" al bot dal telefono, il messaggio resta in attesa sul server. Ogni secondo l'ESP32 invia una richiesta HTTPS cifrata (getUpdates) ad api.telegram.org chiedendo "ci sono messaggi nuovi per me?", preleva il messaggio e lo esegue. Per inviare un avviso fa una richiesta sendMessage nella direzione opposta. Visto che è sempre l'ESP32 ad aprire la connessione, non servono inoltro delle porte né IP statico: la scheda funziona su qualsiasi rete Wi-Fi a 2,4 GHz con accesso a internet.

ConcettoA cosa serve?Esempio
BotFatherIl bot di Telegram per creare e gestire i bot/newbot, /setcommands, /revoke
Token del botLa password del bot; il tuo codice si collega a Telegram con questa1234567890:AAE... (numero, due punti, stringa lunga)
Chat IDIl numero della persona o del gruppo che riceve il messaggioPersona: 123456789, gruppo: -1001234567890
getUpdatesScarica dal server i nuovi messaggi inviati al botbot.getUpdates(...)
sendMessageInvia un messaggio al chat ID indicatobot.sendMessage(CHAT_ID, "Ciao")
ComandoMessaggio breve che inizia con / e che il bot capisce/ac, /kapat, /durum

Perché Telegram? Confronto con gli altri modi per ricevere notifiche

MetodoProControIdeale per
Bot TelegramGratis, avvisi istantanei, comandi nei due sensi, nessuna porta da aprireNiente grafici né dashboard prontaAllarmi e controllo remoto semplice
Blynk IoTPulsanti, indicatori e grafici già prontiLimiti di messaggi e dispositivi nel piano gratuitoDashboard di monitoraggio dei sensori
E-mail (SMTP)Funziona su ogni telefono, adatta a report lunghiIn ritardo, ricevere comandi è scomodoReport giornalieri
SMS (SIM800L)Non servono Wi-Fi né internetCosto della SIM e degli SMS, modulo in piùCasa di campagna o magazzino senza internet
Web server sull'ESP32Completamente locale e gratuitoDi solito raggiungibile solo dalla stessa rete, niente avvisiPannello di controllo in casa

In breve, Telegram è la strada più semplice ed economica per i progetti del tipo "avvisami quando succede qualcosa e fai questo quando ti mando un comando". Se vuoi seguire i dati dei sensori sui grafici, ti troverai meglio con la guida Blynk con ESP32; se ti servono avvisi da un posto senza Wi-Fi, dai un'occhiata alla guida al modulo GSM SIM800L.

Passo 1: creare il bot con BotFather e ottenere il token

  1. Apri Telegram sul telefono o sul computer, scrivi BotFather nella ricerca e scegli l'account ufficiale, quello con la spunta blu accanto al nome. Attento agli account falsi con nomi simili.
  2. Tocca Avvia (Start) e invia il comando /newbot.
  3. BotFather ti chiede prima il nome visualizzato del bot; scrivi quello che vuoi, per esempio "Allarme Casa".
  4. Poi ti chiede un nome utente. Deve essere unico, contenere solo lettere latine, numeri e trattini bassi e finire con bot, per esempio allarme_casa_bot. Se è già preso, aggiungi un numero alla fine e riprova.
  5. BotFather risponde con "Done! Congratulations on your new bot.", il link al tuo bot e il suo token. Il token ha la forma 1234567890:AAE...: un numero, due punti e una lunga stringa di caratteri. Copialo per intero e conservalo in un posto sicuro.
  6. Tocca il link inviato da BotFather per aprire il tuo bot e premi Avvia. Questo passaggio è obbligatorio: su Telegram i bot non possono mandare per primi un messaggio a un utente, quindi la conversazione devi iniziarla sempre tu.
Il token è la chiave del tuo bot: chi lo possiede può leggere i messaggi che riceve il tuo bot, scrivere a suo nome e prendersi i comandi destinati al tuo ESP32 prima di lui. Non condividere mai codice con il token su forum, screenshot o repository GitHub pubblici. Se pensi che sia trapelato, annulla quello vecchio con il comando /revoke di BotFather, ottieni un nuovo token e ricarica il codice.

Passo 2: come trovare il tuo chat ID di Telegram?

Il token risponde alla domanda "quale bot?", il chat ID alla domanda "chi riceve il messaggio?". Ogni utente, gruppo e canale di Telegram ha un identificativo numerico fisso, che non coincide con il tuo nome utente con la @. Ci sono tre modi semplici per scoprire il tuo chat ID:

  1. Con un bot di identificazione: cerca su Telegram un bot come @userinfobot e premi Avvia; ti manda il tuo numero nella riga Id. Questi bot non sono tuoi, mostrano solo il tuo ID.
  2. Con il browser: prima manda un messaggio qualsiasi al tuo bot. Poi apri api.telegram.org/botTOKEN/getUpdates nel browser del computer (incolla il tuo token al posto di TOKEN lasciando davanti la parola "bot"). Nel testo che compare, il numero in "chat":{"id":123456789 è il tuo chat ID. Se la pagina mostra una lista result vuota, scrivi di nuovo al bot e ricarica la pagina.
  3. Con l'ESP32: quando carichi il codice dei comandi qui sotto, l'ID di chiunque non sia autorizzato viene stampato nel Monitor seriale con la riga "unauthorized ID". Se vuoi aggiungere un familiare, chiedigli di scrivere al bot e leggi lì il suo numero.
Se userai il bot in un gruppo di famiglia, aggiungilo al gruppo, scrivi lì un messaggio e guarda di nuovo la pagina getUpdates: gli ID dei gruppi iniziano con il segno meno, quelli dei supergruppi con -100. Dimenticare il segno meno è la causa più frequente dell'errore "chat not found". Nella modalità privacy predefinita il bot non legge la chat del gruppo, ma vede solo i comandi che iniziano con / rivolti a lui; per un bot a comandi è sufficiente.

Passo 3: installare UniversalTelegramBot e ArduinoJson

  1. Se nell'Arduino IDE non hai ancora installato il pacchetto delle schede ESP32, fallo prima; i passaggi sono in Cos'è l'ESP32?.
  2. Apri Strumenti > Gestisci librerie, scrivi UniversalTelegramBot nella ricerca e installa la libreria di Brian Lough. I codici di questa guida sono stati compilati con UniversalTelegramBot 1.3.0, ArduinoJson 7 e la versione 2.0.11 del pacchetto schede ESP32.
  3. Se l'installazione ti chiede delle dipendenze, scegli Install all; se non lo fa, cerca ArduinoJson nella stessa finestra e installa a parte la libreria di Benoit Blanchon.
  4. In File > Esempi > UniversalTelegramBot > ESP32 trovi esempi pronti come FlashLED; i codici di questa guida ne sono versioni semplificate con in più la sicurezza.

UniversalTelegramBot è scritta con la sintassi della versione 6 di ArduinoJson, ma si compila senza problemi anche con ArduinoJson 7. Se nell'Arduino IDE hai attivato gli avvisi del compilatore vedrai righe come "'DynamicJsonDocument' is deprecated: use JsonDocument instead"; sono avvisi, non errori, e il programma funziona normalmente. Se hai difficoltà a installare le librerie, consulta la guida Come aggiungere una libreria Arduino.

Materiale e schema dei collegamenti

Per il progetto completo ti servono una scheda di sviluppo ESP32, un sensore di movimento PIR HC-SR501, un modulo sensore di gas MQ-2, un modulo relè da 5 V, una resistenza da 10 kΩ e una da 20 kΩ, una breadboard e dei cavetti jumper. Come LED useremo il LED blu integrato dell'ESP32 sul GPIO 2. Per provare i primi due passi bastano l'ESP32 e un cavo USB; i sensori puoi aggiungerli dopo.

ESP32
ESP32
PIR HC-SR501
PIR HC-SR501
MQ-2
MQ-2
Modulo relè
Modulo relè
CollegamentoESP32ESP8266 (NodeMCU)Raspberry Pi Pico W
PIR VCCVIN (5V)VIN (5V)VBUS (5V)
PIR OUTGPIO 27D5 (GPIO 14)GP16
MQ-2 VCCVIN (5V)VIN (5V)VBUS (5V)
MQ-2 AO (tramite partitore 10 kΩ / 20 kΩ)GPIO 34A0GP26 (ADC0)
Relè VCCVIN (5V)VIN (5V)VBUS (5V)
Relè INGPIO 26D1 (GPIO 5)GP15
LEDGPIO 2 (integrato)D4 (integrato, si accende con LOW)"LED" (integrato)
Tutti i GNDGNDGNDGND
I pin di ESP32, ESP8266 e Pico lavorano a 3,3 V. Quando il modulo MQ-2 è alimentato a 5 V, la sua uscita AO può arrivare a 5 V: costruisci quindi un Partitore di tensione collegando AO al pin analogico tramite 10 kΩ e il pin analogico a GND tramite 20 kΩ. Così i 5 V scendono a circa 3,3 V. Se con il relè commuti un carico di rete a 230 V, fai sempre i collegamenti con la spina staccata e chiedi aiuto a un adulto; trovi i dettagli in Cos'è un modulo relè?.

Fai attenzione anche all'alimentazione: da solo il riscaldatore dell'MQ-2 assorbe circa 150 mA e la bobina del relè intorno ai 70 mA, mentre l'ESP32 può arrivare per un attimo fino a 250 mA quando trasmette in Wi-Fi. La porta USB del computer non sempre regge questo totale e la scheda può riavviarsi proprio mentre invia un messaggio. Usa un alimentatore da 5 V di almeno 1 A e un buon cavo; se il problema continua, leggi ESP32 Brownout e Guru Meditation. Puoi vedere tutti i pin della tua scheda nello strumento Pinout.

Primo test: inviare un messaggio dall'ESP32 a Telegram

Prima di passare ai sensori, verifichiamo token e chat ID con il codice più semplice possibile. Nel codice qui sotto sostituisci nome della rete Wi-Fi, password e le righe BOT_TOKEN e CHAT_ID con i tuoi dati e caricalo sulla scheda. Poi apri il Monitor seriale a 115200 baud:

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <WiFiClientSecure.h>
3#include <UniversalTelegramBot.h>
4#include <ArduinoJson.h>
5
6const char* WIFI_SSID = "AgAdi";          // Wi-Fi adın (yalnız 2,4 GHz) / your Wi-Fi name (2.4 GHz only)
7const char* WIFI_PASS = "Sifre123";       // Wi-Fi şifren / your Wi-Fi password
8#define BOT_TOKEN "1234567890:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"   // BotFather'ın verdiği token / token from BotFather
9#define CHAT_ID   "123456789"             // kendi Telegram ID'n / your own Telegram ID
10
11WiFiClientSecure client;                  // şifreli (HTTPS) bağlantı / encrypted (HTTPS) connection
12UniversalTelegramBot bot(BOT_TOKEN, client);
13
14void setup() {
15  Serial.begin(115200);
16  WiFi.mode(WIFI_STA);
17  WiFi.begin(WIFI_SSID, WIFI_PASS);
18  Serial.print("Wi-Fi'ye baglaniyor / connecting to Wi-Fi");
19  while (WiFi.status() != WL_CONNECTED) {
20    delay(500);
21    Serial.print(".");
22  }
23  Serial.println();
24  Serial.println(WiFi.localIP());
25
26  client.setCACert(TELEGRAM_CERTIFICATE_ROOT);   // api.telegram.org kök sertifikası / root certificate of api.telegram.org
27
28  if (bot.sendMessage(CHAT_ID, "Merhaba! ESP32 çevrimiçi / Hello! ESP32 is online")) {
29    Serial.println("Mesaj gonderildi / message sent");
30  } else {
31    Serial.println("Mesaj gonderilemedi / message failed");
32  }
33}
34
35void loop() {
36}

Nel giro di pochi secondi il tuo bot dovrebbe mandarti "Hello! ESP32 is online" su Telegram e il Monitor seriale dovrebbe mostrare "Mesaj gonderildi / message sent". sendMessage() restituisce true quando il messaggio viene consegnato; se vedi "message failed", il problema sta nella connessione Wi-Fi, nel token, nel chat ID o nell'impostazione del certificato. Prima di dare la colpa al codice, apri api.telegram.org/botTOKEN/getMe nel browser: con un token valido vedrai "ok":true e il nome del tuo bot, con uno sbagliato "Unauthorized".

Impostazione del certificato: setCACert o setInsecure?

Telegram accetta solo HTTPS, per questo il codice usa WiFiClientSecure invece di un semplice WiFiClient. In una connessione cifrata l'ESP32 deve essere sicuro che il server con cui parla sia davvero api.telegram.org; lo fa verificando il certificato del server con il certificato radice in cima alla catena. UniversalTelegramBot include questo certificato radice già pronto con il nome TELEGRAM_CERTIFICATE_ROOT. La catena di certificati di Telegram arriva a Go Daddy Root Certificate Authority - G2, valido fino alla fine del 2037; se un giorno Telegram cambiasse fornitore di certificati, andrebbe aggiornata anche la libreria.

ImpostazioneCosa faSicurezzaQuando usarla?
client.setCACert(TELEGRAM_CERTIFICATE_ROOT)Cifra la connessione e verifica l'identità del serverAltaSempre, è l'impostazione consigliata
client.setInsecure()Cifra la connessione ma non controlla chi è il serverMedia: non si accorge di un server falso nel mezzoTest veloce per escludere problemi di certificato
Nessuna delle dueCon i core ESP32 attuali la connessione non viene mai stabilitaNon funzionaMai: non parte nessun messaggio e nel Monitor seriale non compare alcun errore
ESP8266: setTrustAnchors(&cert)L'equivalente su ESP8266; il certificato si passa come X509ListAltaNodeMCU e Wemos D1 Mini; serve l'ora corretta

Controllare LED e relè con i comandi Telegram (/ac, /kapat)

Ora rendiamo il bot bidirezionale. Il codice qui sotto chiede a Telegram una volta al secondo se ci sono messaggi nuovi; se il testo è /ac ("accendi" in turco) accende relè e LED, /kapat ("spegni") li spegne, /durum ("stato") comunica lo stato attuale e /start invia l'elenco dei comandi. Puoi rinominarli in /accendi e /spegni, ma ricorda che i comandi di Telegram possono contenere solo lettere latine minuscole, numeri e trattini bassi, al massimo 32 caratteri. Un comando con lettere accentate come "/più" non viene riconosciuto come comando toccabile.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <WiFiClientSecure.h>
3#include <UniversalTelegramBot.h>
4#include <ArduinoJson.h>
5
6const char* WIFI_SSID = "AgAdi";
7const char* WIFI_PASS = "Sifre123";
8#define BOT_TOKEN "1234567890:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
9#define CHAT_ID   "123456789"                 // yalnız bu ID'ye yanıt verilir / only this ID gets answers
10
11const int LED_PIN  = 2;                       // çoğu DevKit'te dahili LED / onboard LED on most DevKits
12const int ROLE_PIN = 26;                      // röle modülünün IN pini / relay module IN pin
13const bool ROLE_AKTIF_LOW = true;             // çoğu modül LOW'da çeker / most modules switch on with LOW
14
15const unsigned long KONTROL_ARALIGI = 1000;   // Telegram'a saniyede bir sor / ask Telegram once per second
16unsigned long sonKontrol = 0;
17bool roleAcik = false;
18
19WiFiClientSecure client;
20UniversalTelegramBot bot(BOT_TOKEN, client);
21
22void roleYaz(bool acik) {
23  roleAcik = acik;
24  if (ROLE_AKTIF_LOW) digitalWrite(ROLE_PIN, acik ? LOW : HIGH);
25  else                digitalWrite(ROLE_PIN, acik ? HIGH : LOW);
26  digitalWrite(LED_PIN, acik ? HIGH : LOW);   // LED röle durumunu gösterir / LED mirrors the relay
27}
28
29void mesajlariIsle(int adet) {
30  for (int i = 0; i < adet; i++) {
31    String chatId = bot.messages[i].chat_id;
32    String metin  = bot.messages[i].text;
33
34    // Güvenlik: tanımadığın kişiye cevap verme / security: never answer strangers
35    if (chatId != CHAT_ID) {
36      Serial.println("Yetkisiz ID / unauthorized ID: " + chatId);
37      continue;
38    }
39
40    int at = metin.indexOf('@');              // gruptaki "/ac@bot_adi" -> "/ac" / "/ac@bot_name" in groups -> "/ac"
41    if (at > 0) metin = metin.substring(0, at);
42
43    if (metin == "/start") {
44      String yardim = "Merhaba " + bot.messages[i].from_name + "!\n";
45      yardim += "/ac - röleyi aç / relay ON\n";
46      yardim += "/kapat - röleyi kapat / relay OFF\n";
47      yardim += "/durum - son durum / status";
48      bot.sendMessage(chatId, yardim);
49    } else if (metin == "/ac") {
50      roleYaz(true);
51      bot.sendMessage(chatId, "Röle AÇIK / relay ON");
52    } else if (metin == "/kapat") {
53      roleYaz(false);
54      bot.sendMessage(chatId, "Röle KAPALI / relay OFF");
55    } else if (metin == "/durum") {
56      bot.sendMessage(chatId, roleAcik ? "Röle AÇIK / relay ON" : "Röle KAPALI / relay OFF");
57    } else {
58      bot.sendMessage(chatId, "Bilinmeyen komut, /start yaz / unknown command, send /start");
59    }
60  }
61}
62
63void setup() {
64  Serial.begin(115200);
65  pinMode(LED_PIN, OUTPUT);
66  pinMode(ROLE_PIN, OUTPUT);
67  roleYaz(false);                             // açılışta röle kapalı / relay off at boot
68
69  WiFi.mode(WIFI_STA);
70  WiFi.begin(WIFI_SSID, WIFI_PASS);
71  while (WiFi.status() != WL_CONNECTED) delay(500);
72  Serial.println(WiFi.localIP());
73
74  client.setCACert(TELEGRAM_CERTIFICATE_ROOT);
75  bot.sendMessage(CHAT_ID, "Bot hazır, /start yaz / bot ready, send /start");
76}
77
78void loop() {
79  if (millis() - sonKontrol > KONTROL_ARALIGI) {
80    int adet = bot.getUpdates(bot.last_message_received + 1);   // yeni mesaj var mı? / any new messages?
81    while (adet) {
82      mesajlariIsle(adet);
83      adet = bot.getUpdates(bot.last_message_received + 1);
84    }
85    sonKontrol = millis();
86  }
87}
RigaFunzione
bot.getUpdates(bot.last_message_received + 1)Chiede i messaggi successivi all'ultimo elaborato e restituisce quanti ne sono arrivati; il +1 evita che torni lo stesso messaggio
bot.messages[i].chat_idL'ID della chat da cui arriva il messaggio; la risposta va lì e il controllo di sicurezza lo usa
bot.messages[i].textIl testo ricevuto; con questo confrontiamo il comando
metin.indexOf('@')Taglia la parte @nome_bot che Telegram aggiunge ai comandi nei gruppi
ROLE_AKTIF_LOWLa maggior parte dei moduli relè si attiva con LOW; se il tuo si attiva con HIGH, mettilo a false
KONTROL_ARALIGIOgni quanto si interroga Telegram; 1000 ms risponde in fretta, 3000–5000 ms affatica meno la rete

Sicurezza: il bot deve rispondere solo al tuo ID

Su Telegram i nomi utente dei bot sono pubblici e si possono cercare. Se qualcuno indovina allarme_casa_bot o lo vede in uno screenshot e gli scrive /ac, un ESP32 senza controlli eseguirà anche quel comando. Per questo la riga più importante del codice è il controllo chatId != CHAT_ID. Il tuo chat ID non deve per forza restare segreto: la protezione nasce dal fatto che è Telegram stesso a certificare chi ha inviato ogni messaggio, e nessuno può falsificare l'ID di un altro. Non rispondere affatto agli sconosciuti è anche una scelta voluta: finché il bot tace, nessuno capisce nemmeno che è in funzione.

  • Usa una lista bianca: tieni gli ID autorizzati in un array, ignora tutti gli altri messaggi e aggiungi i familiari uno alla volta.
  • Nei gruppi controlla la persona: in un gruppo il chat ID è quello del gruppo; se solo alcune persone devono poter dare comandi, confronta from_id invece di chat_id.
  • Tieni il token in un file a parte: metti token e password del Wi-Fi in un file come secrets.h e lascialo fuori quando condividi il codice.
  • Salta i comandi vecchi: un /ac inviato durante un blackout non deve scattare in un momento inaspettato quando la scheda si riaccende; la pulizia all'avvio del codice completo se ne occupa.
  • Stato iniziale sicuro: parti sempre con il relè spento a ogni accensione; con carichi come stufette o pompe è fondamentale.
  • Non affidare le cose critiche solo al bot: per una serratura o una caldaia pensa a cosa può causare un comando sbagliato e aggiungi un messaggio di conferma o un limite di tempo.

Allarme movimento e gas: progetto completo con notifiche Telegram

Ora mettiamo insieme tutti i pezzi. Il codice qui sotto ti invia una notifica Telegram con l'orario quando il sensore PIR rileva un movimento e quando la lettura del gas dell'MQ-2 supera la soglia. Nello stesso tempo ascolta i comandi /ac, /kapat, /alarm_ac, /alarm_kapat e /durum, mostra un menu di pulsanti in fondo allo schermo quando scrivi /start e aggiunge i comandi al pulsante Menu di Telegram. Per i dettagli dei sensori, guarda le guide al sensore di movimento PIR e al sensore di gas MQ-2.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <WiFiClientSecure.h>
3#include <UniversalTelegramBot.h>
4#include <ArduinoJson.h>
5#include <time.h>
6
7const char* WIFI_SSID = "AgAdi";
8const char* WIFI_PASS = "Sifre123";
9#define BOT_TOKEN "1234567890:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
10#define CHAT_ID   "123456789"                  // bildirimlerin gideceği ID / the ID that receives alerts
11
12// Komut verebilecek kişiler; aile üyesi eklemek için: { CHAT_ID, "222222222" }
13// People allowed to send commands; to add a family member: { CHAT_ID, "222222222" }
14const char* YETKILI[] = { CHAT_ID };
15const int YETKILI_SAYISI = sizeof(YETKILI) / sizeof(YETKILI[0]);
16
17const int LED_PIN  = 2;                        // dahili LED / onboard LED
18const int ROLE_PIN = 26;                       // röle modülü IN / relay module IN
19const int PIR_PIN  = 27;                       // PIR sensörü OUT / PIR sensor OUT
20const int GAZ_PIN  = 34;                       // MQ-2 AO, gerilim bölücü üzerinden / MQ-2 AO through a voltage divider
21const bool ROLE_AKTIF_LOW = true;              // çoğu modül LOW'da çeker / most modules switch on with LOW
22
23const int GAZ_ESIK = 1800;                     // temiz havadaki değere göre ayarla / tune it from your clean-air reading
24const int GAZ_FARK = 200;                      // histerezis payı / hysteresis margin
25const unsigned long HAREKET_BEKLEME = 60000;   // iki hareket bildirimi arası en az 60 sn / at least 60 s between motion alerts
26const unsigned long GAZ_ISINMA = 120000;       // MQ-2 ilk 2 dakika ısınır / MQ-2 warms up for the first 2 minutes
27const unsigned long KONTROL_ARALIGI = 1000;    // Telegram'a saniyede bir sor / poll Telegram once per second
28
29WiFiClientSecure client;
30UniversalTelegramBot bot(BOT_TOKEN, client);
31
32bool alarmKurulu = true;                       // hareket alarmı açık mı / is the motion alarm armed
33bool roleAcik = false;
34bool gazVar = false;
35unsigned long sonKontrol = 0;
36unsigned long sonHareket = 0;
37
38String saat() {                                // "14:05:31" biçiminde saat / time as "14:05:31"
39  struct tm t;
40  if (!getLocalTime(&t, 100)) return "--:--:--";
41  char buf[9];
42  strftime(buf, sizeof(buf), "%H:%M:%S", &t);
43  return String(buf);
44}
45
46bool yetkiliMi(const String& id) {
47  for (int i = 0; i < YETKILI_SAYISI; i++) {
48    if (id == YETKILI[i]) return true;
49  }
50  return false;
51}
52
53void roleYaz(bool acik) {
54  roleAcik = acik;
55  if (ROLE_AKTIF_LOW) digitalWrite(ROLE_PIN, acik ? LOW : HIGH);
56  else                digitalWrite(ROLE_PIN, acik ? HIGH : LOW);
57}
58
59String durumMetni() {
60  String s = "Röle / relay: ";
61  s += roleAcik ? "AÇIK / ON" : "KAPALI / OFF";
62  s += "\nAlarm: ";
63  s += alarmKurulu ? "KURULU / ARMED" : "KAPALI / DISARMED";
64  s += "\nGaz / gas: " + String(analogRead(GAZ_PIN));
65  s += "\nWi-Fi: " + String(WiFi.RSSI()) + " dBm";
66  return s;
67}
68
69void mesajlariIsle(int adet) {
70  for (int i = 0; i < adet; i++) {
71    String chatId = bot.messages[i].chat_id;
72    String metin  = bot.messages[i].text;
73
74    if (!yetkiliMi(chatId)) {                  // yabancıya sessiz kal / stay silent to strangers
75      Serial.println("Yetkisiz ID / unauthorized ID: " + chatId);
76      continue;
77    }
78    int at = metin.indexOf('@');               // "/ac@bot_adi" -> "/ac"
79    if (at > 0) metin = metin.substring(0, at);
80
81    if (metin == "/ac") {
82      roleYaz(true);
83      bot.sendMessage(chatId, "Röle AÇIK / relay ON");
84    } else if (metin == "/kapat") {
85      roleYaz(false);
86      bot.sendMessage(chatId, "Röle KAPALI / relay OFF");
87    } else if (metin == "/alarm_ac") {
88      alarmKurulu = true;
89      bot.sendMessage(chatId, "Hareket alarmı kuruldu / motion alarm armed");
90    } else if (metin == "/alarm_kapat") {
91      alarmKurulu = false;
92      bot.sendMessage(chatId, "Hareket alarmı kapatıldı / motion alarm disarmed");
93    } else if (metin == "/durum") {
94      bot.sendMessage(chatId, durumMetni());
95    } else {                                   // /start ve diğer her şey: tuş menüsü / /start and anything else: button menu
96      String klavye = "[[\"/ac\",\"/kapat\"],[\"/alarm_ac\",\"/alarm_kapat\"],[\"/durum\"]]";
97      bot.sendMessageWithReplyKeyboard(chatId, "Komut seç / choose a command", "", klavye, true);
98    }
99  }
100}
101
102void setup() {
103  Serial.begin(115200);
104  pinMode(LED_PIN, OUTPUT);
105  pinMode(ROLE_PIN, OUTPUT);
106  pinMode(PIR_PIN, INPUT);
107  roleYaz(false);                              // açılışta röle kapalı / relay off at boot
108
109  WiFi.mode(WIFI_STA);
110  WiFi.begin(WIFI_SSID, WIFI_PASS);
111  while (WiFi.status() != WL_CONNECTED) {
112    delay(500);
113    Serial.print(".");
114  }
115  Serial.println(WiFi.localIP());
116
117  client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // api.telegram.org kök sertifikası / root certificate of api.telegram.org
118  bot.maxMessageLength = 4000;                 // büyük mesajlarda takılmayı önler / prevents hanging on big messages
119  configTime(3 * 3600, 0, "pool.ntp.org");     // Türkiye UTC+3; kendi saat dilimini yaz / Turkey is UTC+3, set your own zone
120
121  // Telegram'daki Menü düğmesi; komutlar küçük harf, Türkçe karakter yok
122  // The Menu button in Telegram; commands are lowercase with no special letters
123  bot.setMyCommands("[{\"command\":\"ac\",\"description\":\"Röleyi aç\"},"
124                    "{\"command\":\"kapat\",\"description\":\"Röleyi kapat\"},"
125                    "{\"command\":\"alarm_ac\",\"description\":\"Hareket alarmını kur\"},"
126                    "{\"command\":\"alarm_kapat\",\"description\":\"Hareket alarmını kapat\"},"
127                    "{\"command\":\"durum\",\"description\":\"Durumu göster\"}]");
128
129  // Kart kapalıyken gelen eski komutları atla / skip old commands sent while the board was off
130  while (bot.getUpdates(bot.last_message_received + 1)) { }
131
132  bot.sendMessage(CHAT_ID, "Sistem açıldı / system started " + saat());
133}
134
135void loop() {
136  unsigned long simdi = millis();
137
138  // 1) Hareket alarmı / motion alarm
139  if (alarmKurulu && digitalRead(PIR_PIN) == HIGH && simdi - sonHareket > HAREKET_BEKLEME) {
140    sonHareket = simdi;
141    digitalWrite(LED_PIN, HIGH);
142    bot.sendMessage(CHAT_ID, "Hareket algılandı! / motion detected! " + saat());
143    digitalWrite(LED_PIN, LOW);
144  }
145
146  // 2) Gaz alarmı: ısınmadan sonra, susturulamaz / gas alarm: after warm-up, cannot be muted
147  if (simdi > GAZ_ISINMA) {
148    int gaz = analogRead(GAZ_PIN);             // 0-4095
149    if (!gazVar && gaz > GAZ_ESIK) {
150      gazVar = true;
151      bot.sendMessage(CHAT_ID, "GAZ ALARMI! / GAS ALARM! " + String(gaz) + " " + saat());
152    } else if (gazVar && gaz < GAZ_ESIK - GAZ_FARK) {
153      gazVar = false;
154      bot.sendMessage(CHAT_ID, "Gaz normale döndü / gas back to normal: " + String(gaz));
155    }
156  }
157
158  // 3) Telegram komutları / Telegram commands
159  if (simdi - sonKontrol > KONTROL_ARALIGI && WiFi.status() == WL_CONNECTED) {
160    int adet = bot.getUpdates(bot.last_message_received + 1);
161    while (adet) {
162      mesajlariIsle(adet);
163      adet = bot.getUpdates(bot.last_message_received + 1);
164    }
165    sonKontrol = millis();
166  }
167}
ImpostazioneValoreSpiegazione
GAZ_ESIK1800Valore ADC grezzo da 0 a 4095; fissalo in base alla tua misura in aria pulita
GAZ_FARK200La lettura deve scendere di tanto sotto la soglia prima del messaggio "tornato normale"; evita avvisi che vanno e vengono al limite
HAREKET_BEKLEME60000 msLascia almeno 60 secondi tra due avvisi di movimento
GAZ_ISINMA120000 msL'MQ-2 dà valori alti mentre si scalda; il gas non viene controllato nei primi 2 minuti
KONTROL_ARALIGI1000 msOgni quanto si chiedono a Telegram i nuovi messaggi
bot.maxMessageLength4000La risposta più lunga che la libreria legge; il valore predefinito è 1500

I due allarmi del codice funzionano in modo diverso di proposito. Quello di movimento è protetto da un tempo di attesa: un sensore PIR scatta di continuo mentre qualcuno gira per la stanza, e senza attesa il telefono si riempirebbe di decine di messaggi al minuto. Poiché il contatore parte da zero, il primo avviso arriva non prima di 60 secondi dall'accensione della scheda, che coincide anche con il minuto circa di cui un sensore PIR ha bisogno per stabilizzarsi all'avvio. Quello del gas usa invece l'isteresi: avvisa una volta quando la lettura supera la soglia, dice "tornato normale" solo quando scende 200 unità sotto e, per sicurezza, non si può silenziare con /alarm_kapat. Neanche Telegram accetta messaggi troppo ravvicinati: se provi a mandare più di un messaggio al secondo nella stessa chat o più di 20 al minuto in un gruppo, ricevi l'errore "Too Many Requests: retry after".

Imposta GAZ_ESIK misurando, non a occhio: lascia la scheda accesa 5–10 minuti in aria pulita, invia /durum su Telegram e annota il valore del gas che ricevi. Metti la soglia qualche centinaio di unità più in alto. Vale la pena conoscere anche la variabile bot.longPoll: se le dai un valore come 20, getUpdates aspetta fino a 20 secondi l'arrivo di un messaggio e i comandi ricevono risposta all'istante, ma per quel tempo loop() resta ferma e i sensori non vengono letti. Nei progetti di allarme lascia longPoll a 0.
L'MQ-2 è un sensore didattico e hobbistico, non un rilevatore di gas certificato, e se cade il Wi-Fi o internet non arriva nessun avviso. Non usarlo mai come unica protezione contro le fughe di gas in casa; installa un rilevatore commerciale a norma e considera questo progetto un sistema di avviso aggiuntivo.

Bot Telegram con ESP8266 (NodeMCU)

La stessa libreria funziona anche sulle schede ESP8266 NodeMCU e Wemos D1 Mini; la logica di comandi e allarmi resta identica e cambia solo la parte della connessione. Si include ESP8266WiFi.h al posto di WiFi.h, il certificato radice si passa come X509List a setTrustAnchors() e, dato che l'ESP8266 controlla le date di validità del certificato, bisogna ottenere l'ora via NTP prima di collegarsi. Senza l'ora ogni connessione fallisce in silenzio. Il LED integrato del NodeMCU è sul pin D4 e si accende con LOW, e c'è un solo ingresso analogico, A0.

C++ (Arduino IDE)
1#include <ESP8266WiFi.h>
2#include <WiFiClientSecure.h>
3#include <UniversalTelegramBot.h>
4#include <ArduinoJson.h>
5#include <time.h>
6
7const char* WIFI_SSID = "AgAdi";
8const char* WIFI_PASS = "Sifre123";
9#define BOT_TOKEN "1234567890:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
10#define CHAT_ID   "123456789"
11
12X509List cert(TELEGRAM_CERTIFICATE_ROOT);      // ESP8266'da kök sertifika böyle verilir / how ESP8266 takes the root certificate
13WiFiClientSecure client;
14UniversalTelegramBot bot(BOT_TOKEN, client);
15
16void setup() {
17  Serial.begin(115200);
18  configTime(0, 0, "pool.ntp.org");            // sertifika kontrolü için saat şart / the clock is needed to check the certificate
19  client.setTrustAnchors(&cert);
20
21  WiFi.mode(WIFI_STA);
22  WiFi.begin(WIFI_SSID, WIFI_PASS);
23  while (WiFi.status() != WL_CONNECTED) delay(500);
24
25  time_t simdi = time(nullptr);                // NTP saatini bekle / wait for the NTP time
26  while (simdi < 24 * 3600) {
27    delay(100);
28    simdi = time(nullptr);
29  }
30  bot.sendMessage(CHAT_ID, "ESP8266 çevrimiçi / ESP8266 is online");
31}
32
33void loop() {
34}

Bot Telegram con Raspberry Pi Pico W e MicroPython

Il Raspberry Pi Pico W non ha bisogno di librerie apposite: con il modulo requests di MicroPython puoi inviare richieste direttamente alla Bot API di Telegram. Il codice qui sotto manda un avviso quando rileva un movimento, comanda con /ac e /kapat il relè collegato a GP15 e il LED integrato della scheda, e risponde solo al tuo chat ID. Installa un MicroPython aggiornato sul Pico W con Thonny e salva il codice come main.py. Il modulo requests di MicroPython cifra la connessione ma non verifica il certificato del server, quindi il livello di sicurezza è lo stesso di setInsecure() sull'ESP32.

MicroPython
1import network, time
2import requests
3from machine import Pin
4
5WIFI_SSID = "AgAdi"                    # Wi-Fi adın / your Wi-Fi name
6WIFI_PASS = "Sifre123"                 # Wi-Fi şifren / your Wi-Fi password
7TOKEN = "1234567890:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
8CHAT_ID = 123456789                    # sayı olarak yaz / write it as a number
9API = "https://api.telegram.org/bot" + TOKEN
10
11led = Pin("LED", Pin.OUT)              # Pico W dahili LED / Pico W onboard LED
12role = Pin(15, Pin.OUT, value=1)       # aktif LOW röle kapalı başlar / active-LOW relay starts off
13pir = Pin(16, Pin.IN)                  # PIR OUT
14
15wlan = network.WLAN(network.STA_IF)
16wlan.active(True)
17wlan.connect(WIFI_SSID, WIFI_PASS)
18while not wlan.isconnected():
19    time.sleep(0.5)
20print("IP:", wlan.ifconfig()[0])
21
22def gonder(metin):
23    try:
24        r = requests.post(API + "/sendMessage", json={"chat_id": CHAT_ID, "text": metin})
25        r.close()
26    except Exception as e:
27        print("Gonderilemedi / send failed:", e)
28
29def yeni_mesajlar(offset):
30    try:
31        r = requests.get(API + "/getUpdates?timeout=0&limit=5&offset=%d" % offset)
32        sonuc = r.json().get("result", [])
33        r.close()
34        return sonuc
35    except Exception as e:
36        print("Okunamadi / read failed:", e)
37        return []
38
39# Kart kapalıyken gelen eski komutları atla / skip old commands sent while the board was off
40offset = 0
41eski = yeni_mesajlar(offset)
42while eski:
43    offset = eski[-1]["update_id"] + 1
44    eski = yeni_mesajlar(offset)
45
46gonder("Pico W çevrimiçi / Pico W is online")
47son_hareket = time.ticks_ms()          # ilk 60 sn PIR dengelenir / the PIR settles in the first 60 s
48
49while True:
50    if pir.value() and time.ticks_diff(time.ticks_ms(), son_hareket) > 60000:
51        son_hareket = time.ticks_ms()
52        gonder("Hareket algılandı! / motion detected!")
53
54    for u in yeni_mesajlar(offset):
55        offset = u["update_id"] + 1
56        mesaj = u.get("message", {})
57        if mesaj.get("chat", {}).get("id") != CHAT_ID:     # yalnız sana yanıt ver / answer only you
58            continue
59        komut = mesaj.get("text", "").split("@")[0]
60        if komut == "/ac":
61            role.value(0)              # aktif LOW: 0 = açık / active LOW: 0 = on
62            led.on()
63            gonder("Röle AÇIK / relay ON")
64        elif komut == "/kapat":
65            role.value(1)
66            led.off()
67            gonder("Röle KAPALI / relay OFF")
68        elif komut == "/durum":
69            gonder("Röle / relay: " + ("AÇIK / ON" if role.value() == 0 else "KAPALI / OFF"))
70    time.sleep(1)

Idee di progetto con un bot Telegram e l'ESP32

  • Allarme per porte e finestre: con un sensore reed o un sensore PIR manda un messaggio al telefono quando c'è movimento e in casa non c'è nessuno.
  • Telecamera di sicurezza con foto: scatta una foto con un ESP32-CAM quando rileva un movimento e inviala su Telegram; i passaggi sono nella guida ESP32-CAM e Telegram.
  • Controllo di stanza o serra: ricevi un avviso quando la temperatura misurata con un DHT11 supera un limite e chiedi il valore attuale con /durum.
  • Promemoria per l'irrigazione: ricevi un avviso quando un sensore di umidità del terreno segnala secco e accendi la pompa per qualche secondo con un comando come /sula ("annaffia").
  • Avviso incendio: abbina un sensore di fiamma all'MQ-2 per controllare entrambi i pericoli insieme.
  • Sensore per la cassetta delle lettere a batteria: tieni l'ESP32 in deep sleep, sveglialo all'apertura dello sportello, invia un solo messaggio e rimettilo a dormire.
  • Presa remota: accendi e spegni una lampada da scrivania o un ventilatore da qualsiasi parte del mondo con /ac e /kapat tramite un relè.

Errori comuni del bot Telegram con ESP32 e soluzioni

Sintomo o messaggioCausaSoluzione
sendMessage restituisce false e nel Monitor seriale non c'è nessun erroreManca la riga setCACert o setInsecure, il token contiene uno spazio o il Wi-Fi non è connessoAggiungi la riga del certificato, ricopia il token e controlla prima la connessione Wi-Fi
"Forbidden: bot can't initiate conversation with a user" nel test dal browserNon hai mai premuto Avvia nel bot oppure l'hai bloccatoApri il bot su Telegram e premi Avvia; se l'avevi bloccato, sbloccalo
"Bad Request: chat not found"Chat ID sbagliato, segno meno mancante nell'ID di un gruppo o bot rimosso dal gruppoRileggi l'ID con getUpdates e scrivi gli ID dei gruppi con il segno meno
"Unauthorized"Il token è sbagliato o è stato sostituito con /revokeCopia il token attuale da BotFather e ricarica il codice
Invia messaggi ma non risponde ai comandiUn delay() lungo in loop(), un chat ID sbagliato o il @nome_bot aggiunto al comando in un gruppoAttendi con millis(), taglia la parte con la @ e guarda la riga "unauthorized ID" nel Monitor seriale
Il bot è diventato muto dopo una foto o uno stickerLa libreria legge solo i primi 1500 caratteri di una risposta; una risposta lunga non si decodifica e lo stesso messaggio torna di continuoAggiungi la riga bot.maxMessageLength = 4000; in setup()
All'avvio la scheda esegue comandi vecchiTelegram conserva i messaggi non letti fino a 24 oreAll'avvio leggi e scarta i messaggi in attesa
"Conflict: terminated by other getUpdates request"Lo stesso token gira contemporaneamente su due dispositivi o in uno script sul computerCrea un bot separato su BotFather per ogni dispositivo
"Too Many Requests: retry after 30"I messaggi vengono inviati troppo ravvicinatiAggiungi un tempo di attesa; al massimo un messaggio al secondo nella stessa chat
In compilazione "ArduinoJson.h: No such file or directory"La libreria ArduinoJson non è installataInstalla ArduinoJson dal Gestore librerie
La scheda si riavvia mentre invia un messaggioL'alimentazione non regge il picco di corrente durante la trasmissione Wi-Fi (brownout)Alimentatore da 1 A, cavo corto e di qualità e un condensatore da 100–470 µF tra 3V3 e GND
Segui un ordine quando cerchi il guasto: prima verifica nel Monitor seriale che il Wi-Fi sia connesso, poi prova nel browser il token con getMe e il chat ID con sendMessage, e guarda il codice per ultimo. Per il test dal browser basta aprire api.telegram.org/botTOKEN/sendMessage?chat_id=123456789&text=prova; Telegram spiega la causa di ogni errore in testo semplice nella riga description. Se ti blocchi già alla fase del Wi-Fi, consulta la guida L'ESP32 non si collega al Wi-Fi.

Con un token, un chat ID e poche righe di codice, il tuo ESP32 è diventato un piccolo assistente che ti tiene aggiornato su cosa succede in casa ed esegue i tuoi comandi. Puoi ampliare lo stesso schema con sensori di temperatura, di livello dell'acqua o delle porte e mandare gli avvisi a un gruppo di famiglia. Nell'app BlueGrays trovi passo passo, con schemi e codice, il sistema di allarme di movimento con ESP32 che avvisa su Telegram con PIR, buzzer e LED, l'allarme con rilevatore di gas e fumo MQ-2 e i progetti Wi-Fi con l'ESP32.

Domande frequenti

Un bot Telegram con ESP32 è gratuito?

Sì. Creare un bot su Telegram, usare la Bot API e inviare messaggi è del tutto gratuito e non c'è un limite mensile di messaggi. Ci sono solo limiti di velocità: circa un messaggio al secondo nella stessa chat e 20 messaggi al minuto in un gruppo. Per i progetti di casa sono più che sufficienti.

Come trovo il mio chat ID di Telegram?

Il modo più semplice è premere Avvia in un bot di identificazione come @userinfobot, che ti invia il tuo numero di ID. In alternativa scrivi al tuo bot, apri api.telegram.org/botTOKEN/getUpdates nel browser e leggi il valore id nella sezione "chat". Gli ID dei gruppi iniziano con il segno meno.

Perché il mio ESP32 non invia messaggi a Telegram?

Le cause più comuni sono non aver mai premuto Avvia nel bot, un chat ID sbagliato, uno spazio nel token o la mancanza della riga setCACert o setInsecure nel codice. Aprendo gli indirizzi getMe e sendMessage nel browser puoi provare token e chat ID senza dipendere dal codice. Controlla anche che la scheda sia collegata a una rete Wi-Fi a 2,4 GHz.

Qualcun altro può controllare il mio bot Telegram?

I nomi utente dei bot sono pubblici, quindi se nel codice non metti un controllo dell'ID, sì: chiunque trovi il bot può mandargli comandi. Confrontare il chat ID di ogni messaggio con il tuo e ignorare gli altri lo impedisce, perché è Telegram a certificare l'identità del mittente. Non condividere nemmeno il token; se trapela, sostituiscilo con /revoke su BotFather.

Si può fare un bot Telegram con l'ESP8266?

Sì. La libreria UniversalTelegramBot funziona anche su schede ESP8266 come NodeMCU e Wemos D1 Mini. Il certificato radice si passa come X509List a setTrustAnchors() e prima di collegarsi bisogna ottenere l'ora via NTP. Dato che l'ESP8266 ha meno memoria, con i messaggi lunghi l'ESP32 se la cava meglio.

L'ESP32 può inviare foto su Telegram?

Sì. Con la funzione sendPhotoByBinary() della libreria puoi inviare direttamente su Telegram un'immagine scattata da un ESP32-CAM. Un ESP32 senza fotocamera può inviare allo stesso modo un'immagine salvata su una scheda SD, oppure l'indirizzo di un'immagine online con sendPhoto(). I sistemi che mandano una foto quando rilevano un movimento sono tra i progetti di sicurezza più popolari.

Vedi tutti i progetti
LED Lampeggiante con ESP32
#103Principiante

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.

4.7(37)
99
Lampeggio del LED interno dell'ESP32
#106Principiante

Lampeggio del LED interno dell'ESP32

Far lampeggiare il LED blu integrato nell'ESP32 DevKit V1. Non sono necessari componenti esterni! Il primo progetto da provare quando si acquista un ESP32. Il GPIO 2 è collegato al LED interno.

4.8(29)
53
Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)
#145Avanzato
Premium

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

0.0(0)
9
Allarme rilevatore di gas/fumo ESP32 MQ-2
#122Intermedio

Allarme rilevatore di gas/fumo ESP32 MQ-2

In questo progetto, il rilevamento di gas combustibili (GPL, metano, propano) e fumo viene effettuato tramite un modulo sensore di gas MQ-2; al rilevamento viene emesso un segnale acustico simile a una sirena tramite un cicalino passivo. L'uscita digitale di soglia (DO) del sensore viene collegata al GPIO 4 dell'ESP32; quando gas o fumo superano la soglia, DO passa a LOW e l'allarme si attiva. La sensibilità si regola tramite il potenziometro del modulo. Il cicalino è pilotato con tone().

4.7(28)
43
Illuminazione Intelligente ESP32 (PIR + LDR + Relè + OLED)
#141Avanzato
Premium

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

4.3(6)
11
Illuminazione automatica con sensore di movimento PIR ESP32
#121Intermedio
Premium

Illuminazione automatica con sensore di movimento PIR ESP32

In questo progetto, utilizzeremo il sensore di movimento PIR HC-SR501 per rilevare la presenza di una persona che entra nella stanza e accendere automaticamente il LED. Monitoreremo il tempo di accensione del LED con millis(); ogni lettura HIGH del sensore aggiornerà l'istante dell'ultimo movimento e il LED si spegnerà quando saranno trascorsi almeno 10 secondi dall'ultima lettura HIGH. Il codice attuale attende anche 50 ms a ogni iterazione con delay(50), quindi il ciclo dell'applicazione n

4.4(24)
38
Connessione Wi-Fi STA con ESP32 (con display LCD)
#127Avanzato

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.

4.4(21)
34