Guias · 16 min de leitura

Bot do Telegram com ESP32: alertas, controle de LED e relé

Crie um bot do Telegram com ESP32: token no BotFather, chat ID, instalação da UniversalTelegramBot, alertas de movimento e gás, relé por comando e respostas só para você.

Um bot do Telegram com ESP32 permite que a placa ESP32 da sua casa envie mensagens para o seu celular e execute os comandos que você manda de volta. Quando há movimento na porta ou gás na cozinha, uma notificação chega no seu bolso na hora; digite “/ac” e um relé acende uma lâmpada, digite “/kapat” e ela apaga. Você não precisa escrever um app próprio para o celular, abrir uma porta no roteador nem pagar por um serviço de nuvem: a Bot API gratuita do Telegram e o Wi-Fi integrado do ESP32 já bastam.

Neste guia você vai montar um sistema funcional do zero: vai criar um bot no BotFather e obter o token dele, descobrir o seu próprio chat ID, instalar as bibliotecas UniversalTelegramBot e ArduinoJson e enviar a sua primeira mensagem a partir do ESP32. Depois vai adicionar alertas de movimento e de gás com um sensor PIR e um sensor de gás MQ-2, além de controle de LED e relé por comandos do Telegram. Também vamos ver como fazer o bot responder só ao seu ID, a configuração do certificado, as diferenças no ESP8266 e no Raspberry Pi Pico W e, um a um, os erros mais comuns.

Placa de desenvolvimento ESP32 funcionando como bot do Telegram
Graças ao Wi-Fi integrado, o ESP32 se conecta direto ao servidor do Telegram; não é preciso nenhum módulo extra nem gateway.

O que é um bot do Telegram com ESP32 e como ele funciona?

No Telegram, um bot é uma conta especial controlada por um programa em vez de uma pessoa; no nosso projeto, quem roda esse programa é o ESP32. O ESP32 e o seu celular nunca se conectam diretamente um ao outro; os dois conversam com o servidor do Telegram. Quando você digita “/ac” para o bot no celular, a mensagem fica esperando no servidor. A cada segundo, o ESP32 envia uma requisição HTTPS criptografada (getUpdates) para api.telegram.org perguntando “tem mensagem nova para mim?”, busca a mensagem e age de acordo com ela. Para enviar um alerta, ele faz uma requisição sendMessage no sentido contrário. Como é sempre o ESP32 que abre a conexão, você não precisa de redirecionamento de portas nem de IP estático no roteador; a placa funciona em qualquer rede Wi-Fi de 2,4 GHz com acesso à internet.

TermoPara que serveExemplo
BotFatherO bot do Telegram para criar e gerenciar bots/newbot, /setcommands, /revoke (comandos do BotFather)
Token do botA senha do bot; o seu código se conecta ao Telegram com ele1234567890:AAE... (número, dois-pontos, sequência longa)
Chat IDO número da pessoa ou do grupo para onde vai a mensagemPessoa: 123456789, grupo: -1001234567890
getUpdatesBusca no servidor as mensagens novas enviadas ao botbot.getUpdates(...)
sendMessageEnvia uma mensagem para o chat ID informadobot.sendMessage(CHAT_ID, "Olá")
ComandoUma mensagem curta que começa com / e que o bot entende/ac, /kapat, /durum

Por que o Telegram? Comparação com outras formas de receber notificações

MétodoVantagensDesvantagensIdeal para
Bot do TelegramGrátis, alertas instantâneos, comandos nos dois sentidos, sem abrir portasSem gráficos nem painel prontoAlarmes e controle remoto simples
Blynk IoTPainel pronto com botões, medidores e gráficosLimites de mensagens e de dispositivos no plano grátisPainéis de monitoramento de sensores
E-mail (SMTP)Funciona em qualquer celular, pode levar relatórios longosTem atraso, é difícil receber comandosRelatórios diários
SMS (SIM800L)Não precisa de Wi-Fi nem de internetCusto do chip e dos SMS, módulo extraSítios ou depósitos sem internet
Servidor web no ESP32Totalmente local e grátisEm geral só é acessível da mesma rede, sem alertasPainel de controle dentro de casa

Resumindo, o Telegram é a opção mais fácil e mais barata para projetos do tipo “me avise quando algo acontecer e faça isto quando eu mandar um comando”. Se você quer acompanhar dados de sensores em gráficos, o tutorial do Blynk com ESP32 pode servir melhor; se precisa de alertas de um lugar sem Wi-Fi, dê uma olhada no guia do módulo GSM SIM800L.

Passo 1: crie um bot no BotFather e obtenha o token

  1. Abra o Telegram no celular ou no computador, digite BotFather na caixa de busca e escolha a conta oficial, com o selo azul de verificação ao lado do nome. Cuidado com contas falsas de nome parecido.
  2. Toque em Start (Iniciar) e envie o comando /newbot.
  3. Primeiro o BotFather pede o nome de exibição do bot; digite o nome que quiser, como “Alarme de Casa”.
  4. Em seguida ele pede um nome de usuário. O nome de usuário precisa ser único, usar só letras latinas, números e sublinhados e terminar em bot, por exemplo alarme_da_minha_casa_bot. Se já estiver em uso, acrescente um número no final e tente de novo.
  5. O BotFather responde com “Done! Congratulations on your new bot.” junto com o link do seu bot e o token dele. O token tem o formato 1234567890:AAE...: um número, dois-pontos e uma longa sequência de caracteres. Copie tudo e guarde em um lugar seguro.
  6. Toque no link que o BotFather enviou para abrir o seu bot e pressione Start. Este passo é essencial: no Telegram, os bots não podem mandar a primeira mensagem para um usuário, então é sempre você que precisa iniciar a conversa.
O token é a chave do seu bot: quem o obtiver pode ler as mensagens enviadas ao seu bot, mandar mensagens em nome dele e pegar os comandos destinados ao seu ESP32 antes dele. Nunca compartilhe código que contenha o token em fóruns, em capturas de tela ou em um repositório público no GitHub. Se achar que ele vazou, use o comando /revoke no BotFather para cancelar o antigo, obtenha um token novo e carregue o código de novo.

Passo 2: como descobrir o seu chat ID no Telegram

O token do bot responde à pergunta “qual bot?”, enquanto o chat ID responde a “quem recebe a mensagem?”. Todo usuário, grupo e canal do Telegram tem um ID numérico permanente, que não é a mesma coisa que o seu nome de usuário começado por @. Há três jeitos fáceis de descobrir o seu chat ID:

  1. Com um bot de ID: procure no Telegram um bot de ID, como o @userinfobot, e pressione Start; ele envia o seu número na linha Id. Esses bots não são seus, eles só mostram o seu ID.
  2. Pelo navegador: primeiro mande qualquer mensagem para o seu próprio bot. Depois abra api.telegram.org/botTOKEN/getUpdates no navegador do computador (cole o seu token no lugar de TOKEN e mantenha a palavra “bot” na frente dele). No texto que aparecer, o número em "chat":{"id":123456789 é o seu chat ID. Se a página mostrar uma lista result vazia, mande outra mensagem para o bot e recarregue a página.
  3. Com o ESP32: depois que você carregar o código de comandos abaixo, o ID de qualquer pessoa sem autorização é exibido no Monitor Serial em uma linha “unauthorized ID” (ID não autorizado). Quando quiser incluir alguém da família, peça para a pessoa mandar uma mensagem ao bot e leia o número dela ali.
Se você for usar o bot em um grupo da família, adicione-o ao grupo, mande uma mensagem lá e confira a página do getUpdates de novo: os IDs de grupo começam com um sinal de menos, e os de supergrupo com -100. Esquecer o sinal de menos é a causa mais comum do erro “chat not found”. No modo de privacidade padrão, o bot não lê a conversa do grupo; ele só vê os comandos começados por / dirigidos a ele, que é tudo de que um bot movido a comandos precisa.

Passo 3: instale a UniversalTelegramBot e a ArduinoJson

  1. Se o pacote de placas do ESP32 ainda não estiver instalado na Arduino IDE, instale-o primeiro; os passos estão em O que é o ESP32?.
  2. Abra Ferramentas > Gerenciar Bibliotecas, digite UniversalTelegramBot na caixa de busca e instale a biblioteca de Brian Lough. O código deste guia foi compilado com a UniversalTelegramBot 1.3.0, a ArduinoJson 7 e a versão 2.0.11 do pacote de placas do ESP32.
  3. Se o instalador perguntar sobre dependências, escolha Instalar tudo; se não perguntar, procure ArduinoJson na mesma janela e instale separadamente a biblioteca de Benoit Blanchon.
  4. Em Arquivo > Exemplos > UniversalTelegramBot > ESP32 você encontra exemplos prontos, como o FlashLED; o código deste guia é uma versão simplificada deles, com segurança adicionada.

A UniversalTelegramBot foi escrita no estilo da versão 6 da ArduinoJson, mas também compila sem problemas com a ArduinoJson 7. Se você ativou os avisos do compilador na Arduino IDE, vai ver linhas como “'DynamicJsonDocument' is deprecated: use JsonDocument instead”; são avisos, não erros, e o programa roda normalmente. Se tiver problemas para instalar bibliotecas, consulte o guia Como instalar uma biblioteca no Arduino.

Materiais e ligações

Para o projeto completo, você vai precisar de uma placa de desenvolvimento ESP32, um sensor de movimento PIR HC-SR501, um módulo sensor de gás MQ-2, um módulo relé de 5 V, um resistor de 10 kΩ e um de 20 kΩ, uma protoboard e jumpers. Como LED, vamos usar o LED azul integrado do ESP32, no GPIO 2. Para testar os dois primeiros passos, você só precisa do ESP32 e de um cabo USB; os sensores podem entrar depois.

ESP32
ESP32
PIR HC-SR501
PIR HC-SR501
MQ-2
MQ-2
Módulo relé
Módulo relé
LigaçãoESP32ESP8266 (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 (por um divisor de 10 kΩ / 20 kΩ)GPIO 34A0GP26 (ADC0)
VCC do reléVIN (5V)VIN (5V)VBUS (5V)
IN do reléGPIO 26D1 (GPIO 5)GP15
LEDGPIO 2 (integrado)D4 (integrado, acende em LOW)"LED" (integrado)
Todos os GNDGNDGNDGND
Os pinos do ESP32, do ESP8266 e do Pico trabalham com 3,3 V. Quando o módulo MQ-2 é alimentado com 5 V, a saída AO pode chegar a 5 V, então monte um Divisor de tensão: ligue o AO ao pino analógico por um resistor de 10 kΩ e o pino analógico ao GND por um de 20 kΩ. Assim os 5 V caem para cerca de 3,3 V. Se for acionar com o relé uma carga de 230 V da rede elétrica (no Brasil, 127 V ou 220 V), faça sempre as ligações com o plugue fora da tomada e peça ajuda a um adulto; os detalhes estão em O que é um módulo relé?.

Preste atenção também na alimentação: só o aquecedor do MQ-2 consome cerca de 150 mA e a bobina do relé uns 70 mA, enquanto o ESP32 pode ter picos breves de até 250 mA quando transmite pelo Wi-Fi. A porta USB de um computador nem sempre dá conta desse total, e a placa pode reiniciar bem na hora de enviar uma mensagem. Use uma fonte de 5 V de pelo menos 1 A e um cabo de boa qualidade; se o problema continuar, leia ESP32 brownout e Guru Meditation. Você pode ver todos os pinos da sua placa na ferramenta Pinagem.

Primeiro teste: envie uma mensagem do ESP32 para o Telegram

Antes de passar aos sensores, vamos confirmar o token e o chat ID com o sketch mais simples possível. No código abaixo, troque o nome da rede Wi-Fi, a senha e as linhas BOT_TOKEN e CHAT_ID pelos seus dados e carregue-o na placa. Depois abra o Monitor Serial 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}

Em poucos segundos, o seu bot deve mandar “Hello! ESP32 is online” no Telegram, e o Monitor Serial deve mostrar “Mesaj gonderildi / message sent” (mensagem enviada). sendMessage() retorna true quando a mensagem é entregue; se aparecer “message failed” (falha no envio), o problema está na conexão Wi-Fi, no token, no chat ID ou na configuração do certificado. Antes de culpar o código, abra api.telegram.org/botTOKEN/getMe no navegador: com um token válido você vê "ok":true e o nome do seu bot; com um token errado, aparece “Unauthorized”.

Configuração do certificado: setCACert ou setInsecure?

O Telegram só aceita HTTPS, e é por isso que o código usa WiFiClientSecure em vez de um WiFiClient comum. Em uma conexão criptografada, o ESP32 precisa ter certeza de que o servidor com quem está falando é mesmo o api.telegram.org; ele faz isso verificando o certificado do servidor com o certificado raiz que fica no topo da cadeia. A UniversalTelegramBot já traz esse certificado raiz pronto para uso, com o nome TELEGRAM_CERTIFICATE_ROOT. A cadeia de certificados do Telegram vai até a Go Daddy Root Certificate Authority - G2, que vale até o fim de 2037; se um dia o Telegram trocar de fornecedor de certificados, a biblioteca também vai precisar de atualização.

ConfiguraçãoO que fazSegurançaQuando usar
client.setCACert(TELEGRAM_CERTIFICATE_ROOT)Criptografa a conexão e verifica a identidade do servidorAltaA configuração recomendada, sempre
client.setInsecure()Criptografa a conexão, mas não confere a identidade do servidorMédia: não percebe um servidor falso no meio do caminhoUm teste rápido para descartar problemas de certificado
Nenhuma das duasNos núcleos atuais do ESP32, a conexão nunca é feitaNão funcionaNunca: nenhuma mensagem é enviada e nenhum erro aparece no Monitor Serial
ESP8266: setTrustAnchors(&cert)O equivalente no ESP8266; o certificado é passado como X509ListAltaNodeMCU e Wemos D1 Mini; exige a hora correta

Controle um LED e um relé com comandos do Telegram (/ac, /kapat)

Agora vamos deixar o bot de mão dupla. O código abaixo pergunta ao Telegram por mensagens novas uma vez por segundo; se o texto for /ac (“ligar” em turco), ele liga o relé e o LED, /kapat (“desligar”) desliga os dois, /durum (“estado”) informa o estado atual e /start envia a lista de comandos. Você pode renomear os comandos para /ligar e /desligar, mas lembre-se de que os comandos do Telegram só podem conter letras latinas minúsculas, números e sublinhados e ter no máximo 32 caracteres. Um comando com letras acentuadas, como “/aç” ou “/ação”, não é reconhecido como comando tocável.

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}
LinhaO que faz
bot.getUpdates(bot.last_message_received + 1)Pede as mensagens posteriores à última tratada e retorna quantas chegaram; o +1 evita que a mesma mensagem volte
bot.messages[i].chat_idO ID do chat de onde veio a mensagem; a resposta vai para lá e a verificação de segurança usa esse valor
bot.messages[i].text (texto da mensagem)O texto recebido; é com ele que comparamos o comando
metin.indexOf('@')Corta a parte @nome_do_bot que o Telegram acrescenta aos comandos em grupos
ROLE_AKTIF_LOWA maioria dos módulos relé liga com sinal LOW; coloque false se o seu ligar com HIGH
KONTROL_ARALIGICom que frequência consultar; 1000 ms reage rápido, 3000–5000 ms carrega menos a rede

Segurança: faça o bot responder só ao seu ID

Os nomes de usuário dos bots no Telegram são públicos e aparecem na busca. Se alguém adivinhar alarme_da_minha_casa_bot ou vê-lo em uma captura de tela e mandar /ac, um ESP32 sem verificação vai obedecer a esse comando também. Por isso a linha mais importante do código é a verificação chatId != CHAT_ID. O seu chat ID não precisa ser secreto; a proteção vem do próprio Telegram, que confere quem enviou cada mensagem, e ninguém consegue falsificar o ID de outra pessoa. Não responder a estranhos de jeito nenhum também é uma escolha proposital: enquanto o bot fica em silêncio, ninguém consegue nem saber que ele está funcionando.

  • Use uma lista de permitidos: guarde os IDs autorizados em um array, ignore todas as outras mensagens e inclua os membros da família um a um.
  • Confira a pessoa nos grupos: em um grupo, o chat ID é o ID do grupo; se só algumas pessoas podem mandar comandos, compare o from_id em vez do chat_id.
  • Guarde o token em um arquivo separado: coloque o token e a senha do Wi-Fi em um arquivo como secrets.h e deixe esse arquivo de fora quando compartilhar o seu código.
  • Ignore comandos antigos: um /ac enviado durante uma queda de energia não deve disparar em um momento inesperado quando a placa voltar; a limpeza na inicialização do código completo cuida disso.
  • Estado inicial seguro: comece com o relé desligado toda vez que a placa iniciar; isso é muito importante para cargas como aquecedores ou bombas.
  • Não deixe tarefas críticas só por conta do bot: para coisas como uma fechadura de porta ou um aquecedor a gás, pense no que um comando errado poderia causar e acrescente uma mensagem de confirmação ou um limite de tempo.

Alarme de movimento e gás: um projeto completo que envia alertas pelo Telegram

Agora vamos juntar as peças. O código abaixo manda para você um alerta no Telegram com data e hora quando o sensor PIR detecta movimento e quando a leitura de gás do MQ-2 passa do limite. Ao mesmo tempo, ele escuta os comandos /ac, /kapat, /alarm_ac, /alarm_kapat e /durum, mostra um menu de botões tocáveis na parte de baixo da tela quando você digita /start e adiciona os comandos ao botão Menu do Telegram. Para os detalhes de cada sensor, veja os guias do sensor de movimento PIR e do sensor de gás 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}
ConfiguraçãoValorExplicação
GAZ_ESIK1800Valor bruto do ADC, de 0 a 4095; defina a partir da sua leitura em ar limpo
GAZ_FARK200Quanto a leitura precisa cair abaixo do limite antes de o aviso “voltou ao normal” ser enviado; evita alertas que ficam indo e voltando no limite
HAREKET_BEKLEME60000 msDeixa pelo menos 60 segundos entre dois alertas de movimento
GAZ_ISINMA120000 msO MQ-2 dá leituras altas enquanto aquece; o gás não é verificado nos primeiros 2 minutos
KONTROL_ARALIGI1000 msCom que frequência o Telegram é consultado em busca de mensagens novas
bot.maxMessageLength4000A resposta mais longa que a biblioteca lê; o padrão é 1500

Os dois alarmes do código funcionam de jeitos diferentes de propósito. O alarme de movimento é protegido por um tempo de espera: um sensor PIR dispara várias e várias vezes enquanto alguém anda pelo cômodo e, sem esse tempo de espera, o seu celular se encheria com dezenas de mensagens por minuto. Como o contador do tempo de espera começa do zero, o primeiro alerta chega no mínimo 60 segundos depois que a placa liga, o que também coincide com o cerca de um minuto que um sensor PIR leva para se estabilizar depois de energizado. Já o alarme de gás usa histerese: avisa uma vez quando a leitura passa do limite, só diz “voltou ao normal” quando ela cai 200 unidades abaixo dele e, por segurança, não pode ser silenciado com /alarm_kapat. O Telegram também não permite mensagens muito frequentes: se você tentar enviar mais de uma mensagem por segundo para o mesmo chat, ou mais de 20 por minuto para um grupo, vai receber o erro “Too Many Requests: retry after”.

Defina o GAZ_ESIK medindo, não chutando: deixe a placa funcionando em ar limpo por 5–10 minutos, mande /durum no Telegram e anote o valor de gás que ele devolve. Coloque o limite algumas centenas de unidades acima desse valor. Também vale conhecer a variável bot.longPoll: se você der a ela um valor como 20, o getUpdates espera até 20 segundos por uma mensagem nova, então os comandos são respondidos na hora, mas o loop() fica parado durante esse tempo e os sensores não são lidos. Em projetos de alarme, deixe o longPoll em 0.
O MQ-2 é um sensor para aprendizado e hobby, não um detector de gás certificado, e nenhum alerta chega quando o Wi-Fi ou a internet caem. Nunca o use como única proteção contra vazamentos de gás em casa; instale um detector comercial que siga as normas e trate este projeto como um sistema de aviso extra, junto com ele.

Bot do Telegram no ESP8266 (NodeMCU)

A mesma biblioteca também funciona em placas ESP8266 NodeMCU e Wemos D1 Mini; a lógica de comandos e de alarme é exatamente a mesma, só muda a parte da conexão. Você usa ESP8266WiFi.h em vez de WiFi.h, passa o certificado raiz como X509List para setTrustAnchors() e, como o ESP8266 confere as datas de validade do certificado, a hora precisa ser obtida por NTP antes de conectar. Sem a hora, todas as conexões falham em silêncio. O LED integrado do NodeMCU fica no pino D4 e acende em LOW, e há apenas uma entrada analógica, a 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 do Telegram com Raspberry Pi Pico W e MicroPython

O Raspberry Pi Pico W não precisa de uma biblioteca separada; você pode enviar requisições direto para a Telegram Bot API com o módulo requests do MicroPython. O código abaixo envia um alerta quando detecta movimento, aciona o relé no GP15 e o LED integrado da placa com os comandos /ac e /kapat e só responde ao seu chat ID. Grave um MicroPython atualizado no Pico W com o Thonny e salve o código como main.py. O módulo requests do MicroPython criptografa a conexão, mas não verifica o certificado do servidor, então o nível de segurança é o mesmo do setInsecure() no 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)

Ideias de projetos com bot do Telegram e ESP32

  • Alarme de porta e janela: use um reed switch ou um sensor PIR para mandar uma mensagem ao celular quando houver movimento sem ninguém em casa.
  • Câmera de segurança com fotos: tire uma foto com um ESP32-CAM quando houver movimento e envie para o Telegram; os passos estão no guia ESP32-CAM com Telegram.
  • Monitor de cômodo e estufa: receba um aviso quando a temperatura medida por um DHT11 passar de um limite e peça a leitura atual com /durum.
  • Lembrete de rega das plantas: receba um alerta quando um sensor de umidade do solo indicar terra seca e ligue a bomba por alguns segundos com um comando como /sula (“regar”).
  • Aviso de incêndio: combine um sensor de chama com o MQ-2 para vigiar os dois perigos ao mesmo tempo.
  • Sensor de caixa de correio a bateria: mantenha o ESP32 em deep sleep, acorde-o quando a tampa abrir, envie uma única mensagem e volte a dormir.
  • Tomada remota: ligue e desligue uma luminária de mesa ou um ventilador de qualquer lugar do mundo com /ac e /kapat, por meio de um relé.

Erros comuns do bot do Telegram com ESP32 e como resolver

Sintoma ou mensagemCausaSolução
sendMessage retorna false, sem erro no Monitor SerialFalta a linha setCACert ou setInsecure, o token tem um espaço ou o Wi-Fi não está conectadoAdicione a linha do certificado, copie o token de novo e confira primeiro a conexão Wi-Fi
“Forbidden: bot can't initiate conversation with a user” (o bot não pode iniciar a conversa) em um teste no navegadorVocê nunca pressionou Start no bot ou o bloqueouAbra o bot no Telegram e pressione Start; se o bloqueou, desbloqueie
“Bad Request: chat not found” (chat não encontrado)Chat ID errado, falta o sinal de menos em um ID de grupo ou o bot foi removido do grupoLeia o ID de novo com o getUpdates e escreva os IDs de grupo com o sinal de menos
“Unauthorized” (não autorizado)O token está errado ou foi trocado com /revokeCopie o token atual no BotFather e carregue o código de novo
Envia mensagens, mas ignora os comandosUm delay() longo no loop(), um chat ID errado ou o @nome_do_bot acrescentado ao comando em um grupoUse millis() para as esperas, corte a parte com @ e confira a linha “unauthorized ID” no Monitor Serial
O bot ficou totalmente mudo depois de uma foto ou figurinhaA biblioteca só lê os primeiros 1500 caracteres de uma resposta; uma resposta longa não pode ser interpretada e a mesma mensagem fica voltandoAdicione a linha bot.maxMessageLength = 4000; no setup()
A placa executa comandos antigos ao iniciarO Telegram guarda as mensagens não lidas por até 24 horasLeia e descarte as mensagens pendentes na inicialização
“Conflict: terminated by other getUpdates request” (conflito com outra requisição getUpdates)O mesmo token está rodando em dois dispositivos ao mesmo tempo, ou em um script no seu computadorCrie um bot separado no BotFather para cada dispositivo
“Too Many Requests: retry after 30” (requisições demais)As mensagens estão sendo enviadas muito próximas umas das outrasAdicione um tempo de espera; envie no máximo uma mensagem por segundo para o mesmo chat
“ArduinoJson.h: No such file or directory” ao compilarA biblioteca ArduinoJson não está instaladaInstale a ArduinoJson pelo Gerenciador de Bibliotecas
A placa reinicia ao enviar uma mensagemA fonte não aguenta o pico de corrente durante a transmissão Wi-Fi (brownout)Uma fonte de 1 A, um cabo curto de boa qualidade e um capacitor de 100–470 µF entre 3V3 e GND
Siga uma ordem na hora de procurar o defeito: primeiro confirme no Monitor Serial que o Wi-Fi conectou, depois teste o token com getMe e o chat ID com sendMessage no navegador, e só por último olhe o código. Para um teste no navegador, basta abrir api.telegram.org/botTOKEN/sendMessage?chat_id=123456789&text=test; o Telegram explica o motivo de qualquer erro em texto simples na linha description. Se você travar na etapa do Wi-Fi, veja o guia ESP32 não conecta ao Wi-Fi.

Com um token, um chat ID e algumas linhas de código, o seu ESP32 virou um pequeno assistente que dá notícias da sua casa e recebe os seus comandos. Você pode ampliar a mesma estrutura com sensores de temperatura, de nível de água ou de porta e direcionar os alertas para um grupo da família. No app BlueGrays você encontra, passo a passo, com esquemas do circuito e código, o sistema de alarme de movimento com ESP32 que envia alertas pelo Telegram usando PIR, buzzer e LED, o alarme com detector de gás e fumaça MQ-2 e os projetos de Wi-Fi com ESP32.

Perguntas frequentes

Um bot do Telegram com ESP32 é grátis?

Sim. Criar um bot no Telegram, usar a Bot API e enviar mensagens é totalmente grátis, e não existe cota mensal de mensagens. Há apenas limites de frequência: cerca de uma mensagem por segundo para o mesmo chat e 20 mensagens por minuto para um grupo. Para projetos caseiros, esses limites são mais do que suficientes.

Como descubro o meu chat ID no Telegram?

O jeito mais fácil é pressionar Start em um bot de ID, como o @userinfobot, no Telegram; ele envia o seu número de ID. Outra opção é mandar uma mensagem para o seu próprio bot, abrir api.telegram.org/botTOKEN/getUpdates no navegador e ler o valor id na seção “chat”. Os IDs de grupo começam com um sinal de menos.

Por que o meu ESP32 não envia mensagens para o Telegram?

As causas mais comuns são nunca ter pressionado Start no bot, um chat ID errado, um espaço no token ou a falta da linha setCACert ou setInsecure no código. Você pode testar o token e o chat ID independentemente do código abrindo os endereços getMe e sendMessage no navegador. Confirme também que a placa está conectada a uma rede Wi-Fi de 2,4 GHz.

Outra pessoa pode controlar o meu bot do Telegram?

Os nomes de usuário dos bots são públicos, então, se você não colocar uma verificação de ID no código, sim, qualquer pessoa que encontrar o bot pode mandar comandos para ele. Comparar cada chat ID recebido com o seu e ignorar o resto evita isso, porque o Telegram confere quem é o remetente. Também nunca compartilhe o token; se ele vazar, troque-o com /revoke no BotFather.

Dá para fazer um bot do Telegram com o ESP8266?

Sim. A biblioteca UniversalTelegramBot também funciona em placas ESP8266, como a NodeMCU e a Wemos D1 Mini. O certificado raiz é passado como X509List para setTrustAnchors(), e a hora precisa ser obtida por NTP antes de conectar. O ESP8266 tem menos memória, então o ESP32 lida melhor com mensagens longas.

O ESP32 consegue enviar fotos para o Telegram?

Sim. Com a função sendPhotoByBinary() da biblioteca, você pode enviar um quadro capturado por um ESP32-CAM direto para o Telegram. Um ESP32 sem câmera pode enviar do mesmo jeito uma imagem guardada em um cartão SD, ou o endereço de uma imagem on-line com sendPhoto(). Sistemas que enviam uma foto quando detectam movimento estão entre os projetos de segurança mais populares.

Ver todos os projetos
LED piscando com ESP32
#103Iniciante

LED piscando com ESP32

Ensina o uso básico de uma saída GPIO no ESP32. Fazemos um LED piscar ligando e desligando um pino digital. É a versão para ESP32 do clássico projeto blink do Arduino UNO: os comandos básicos de blink no ambiente Arduino são os mesmos, mas a disposição dos pinos e os níveis de 3,3 V dos GPIOs do ESP32 diferem dos do Arduino UNO.

4.7(37)
99
LED integrado do ESP32 piscando
#106Iniciante

LED integrado do ESP32 piscando

Faça o LED azul integrado do ESP32 DevKit V1 piscar. Nenhum componente externo é necessário! O primeiro projeto para experimentar ao comprar um ESP32. GPIO 2 está conectado ao LED integrado.

4.8(29)
53
Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)
#145Avançado
Premium

Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)

Um sistema de alarme de segurança inteligente que aciona o buzzer e o LED quando o sensor PIR detecta movimento e, ao mesmo tempo, envia uma notificação instantânea ao proprietário pelo Telegram. Inclui um intervalo de espera de 30 segundos para limitar a frequência dos alarmes repetidos; esse mecanismo não valida as detecções do PIR nem elimina disparos falsos. Pode ser usado na segurança de casas, no monitoramento de garagens, depósitos ou salas de trabalho.

0.0(0)
9
Alarme detector de gás e fumaça com ESP32 e MQ-2
#122Intermediário

Alarme detector de gás e fumaça com ESP32 e MQ-2

Neste projeto, um módulo sensor de gás MQ-2 detecta gases combustíveis (LPG, metano e propano) e fumaça, acionando um alarme tipo sirene em um buzzer passivo. A saída digital de limiar (DO) do sensor é conectada ao GPIO 4 do ESP32. Quando a concentração de gás ou fumaça ultrapassa o limiar, DO passa para LOW e o alarme é acionado. A sensibilidade é ajustada pelo potenciômetro do módulo. O buzzer passivo é acionado com tone() para criar um efeito de sirene que alterna entre duas frequências.

4.7(28)
43
Iluminação inteligente com ESP32 (PIR + LDR + relé + OLED)
#141Avançado
Premium

Iluminação inteligente com ESP32 (PIR + LDR + relé + OLED)

Transforme a iluminação do corredor, banheiro ou despensa em iluminação inteligente com ESP32! Com um sensor de movimento PIR, um sensor de luz LDR e um módulo relé, montamos o cenário clássico de "acender a luz ao detectar movimento no escuro" — se o ambiente já estiver claro, o movimento NÃO aciona a luz, economizando energia durante o dia. A luz fica acesa por 30 segundos; se o movimento continuar, o temporizador reinicia e a luz permanece acesa por mais tempo.

4.3(6)
11
Iluminação automática com ESP32 e sensor de movimento PIR
#121Intermediário
Premium

Iluminação automática com ESP32 e sensor de movimento PIR

Neste projeto, usaremos o sensor de movimento PIR HC-SR501 para detectar quando alguém entra no cômodo e acender o LED automaticamente. Acompanharemos o tempo em que o LED fica aceso com millis(). Cada leitura HIGH do sensor atualizará o instante do último movimento, e o LED apagará pelo menos 10 segundos após a última leitura HIGH. O código atual também espera 50 ms em cada ciclo com delay(50), portanto o laço da aplicação não é totalmente livre de bloqueios.

4.4(24)
38
Conexão Wi-Fi STA com ESP32 e display LCD
#127Avançado

Conexão Wi-Fi STA com ESP32 e display LCD

Neste projeto, conectamos o ESP32 à rede Wi-Fi de casa no modo estação (STA), de forma segura e tolerante a falhas. Guardamos o SSID e a senha em um arquivo secrets.h separado para evitar que sejam expostos no Git, configuramos um mecanismo de reconexão automática e exibimos o nível de sinal RSSI e o endereço IP em um display LCD I2C. O LED integrado funciona como indicador de status. É um gerenciador de conexão pronto para uso em produção.

4.4(21)
34