Você já foi surpreendido por uma conta de água abusiva no final do mês devido a um vazamento invisível? Ou simplesmente esqueceu de verificar o medidor de água na calçada?
Neste exemplo vou mostrar como criar um Leitor Inteligente de Hidrômetro utilizando o microcontrolador de baixo custo ESP32-CAM e o Telegram. Trata-se de uma solução simples, prática e altamente funcional de Internet das Coisas (IoT).
O Conceito do Projeto
A lógica é extremamente simples e eficiente:
- Modo Sono Profundo (Deep Sleep): O ESP32-CAM fica desligado a maior parte do tempo, consumindo quase nada de energia.
- Despertar Automático: No horário programado (por exemplo, 1x ao dia), ele acorda automaticamente.
- Iluminação e Foto: Acende o LED flash por fração de segundo, tira uma foto nítida do visor numérico e se conecta ao Wi-Fi.
- Envio da Foto: Transmite a imagem com o registro do consumo direto para o seu aplicativo no Telegram.
- Retorno ao Sono: O módulo se desliga novamente para economizar energia.
Materiais Necessários
Para montar este projeto, você não precisa de conhecimentos avançados em eletrônica:
| Componente | Quantidade | Função no Projeto |
| ESP32-CAM + Câmera OV2640 | 1 un. | Cérebro do sistema + sensor de imagem de 2 Megapixels. |
| Fonte de Alimentação 5V (USB) | 1 un. | Carregador de celular padrão (5V / 2A) para garantir energia suficiente ao Wi-Fi. |
| Caixa Hermética de Proteção (IP65) | 1 un. | Caixa plástica para proteger os componentes de poeira e umidade no abrigo do medidor. |
| Fita Dupla Face / Abraçadeiras | 1 un. | Para fixar a câmera alinhada ao visor do hidrômetro. |
O Segredo Técnico: Ajustando o Foco Macro
A câmera OV2640 vem ajustada de fábrica para tirar fotos de objetos a partir de 50 cm de distância. Como ela vai ficar instalada a cerca de 10 a 15 cm do visor do hidrômetro, a imagem sairá embaçada se não fizer este ajuste simples:
- Localize a cola de silicone amarela travando a rosca da lente.
- Com cuidado (usando a ponta dos dedos ou um alicate pequeno), gire a rosca da lente no sentido anti-horário em aproximadamente 1/4 de volta.
- Isso ajustará o foco para curtas distâncias (Macro), tornando os números do visor perfeitamente legíveis.
Código Fonte Pronto (Arduino IDE)
Instale as bibliotecas UniversalTelegramBot e ArduinoJson no seu ambiente Arduino IDE, cole o código abaixo, preencha seus dados de Wi-Fi e Telegram, e faça o upload para a placa:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "esp_camera.h"
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>
// ======================================================
// CONFIGURAÇÕES DE REDE E TELEGRAM
// ======================================================
const char* ssid = "NOME_DA_SUA_REDE_WIFI";
const char* password = "SENHA_DO_SEU_WIFI";
const char* BOTtoken = "SEU_BOT_TOKEN_DO_TELEGRAM";
const char* CHAT_ID = "SEU_CHAT_ID_DO_TELEGRAM";
// Pinagem Padrão da Câmera (Módulo AI-THINKER)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#define FLASH_LED_PIN 4
WiFiClientSecure clientTCP;
UniversalTelegramBot bot(BOTtoken, clientTCP);
void configCamera() {
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
esp_camera_init(&config);
}
void enviarFotoTelegram() {
digitalWrite(FLASH_LED_PIN, HIGH); // Liga o Flash LED
delay(500); // Aguarda a luz estabilizar
camera_fb_t * fb = esp_camera_fb_get();
digitalWrite(FLASH_LED_PIN, LOW); // Desliga o Flash
if(!fb) return;
clientTCP.setInsecure(); // Ignora verificação estrita de SSL
if (clientTCP.connect("api.telegram.org", 443)) {
String head = "--Boundary\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\n" + String(CHAT_ID) +
"\r\n--Boundary\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"hidrometro.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n";
String tail = "\r\n--Boundary--\r\n";
size_t totalLen = head.length() + fb->len + tail.length();
clientTCP.println("POST /bot" + String(BOTtoken) + "/sendPhoto HTTP/1.1");
clientTCP.println("Host: api.telegram.org");
clientTCP.println("Content-Type: multipart/form-data; boundary=Boundary");
clientTCP.println("Content-Length: " + String(totalLen));
clientTCP.println();
clientTCP.print(head);
uint8_t *fbBuf = fb->buf;
size_t fbLen = fb->len;
for (size_t n=0; n<fbLen; n+=1024) {
if (n+1024 < fbLen) {
clientTCP.write(fbBuf + n, 1024);
} else {
clientTCP.write(fbBuf + n, fbLen - n);
}
}
clientTCP.print(tail);
clientTCP.stop();
}
esp_camera_fb_return(fb);
}
void setup() {
pinMode(FLASH_LED_PIN, OUTPUT);
digitalWrite(FLASH_LED_PIN, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
configCamera();
enviarFotoTelegram();
// Configura sono profundo por 24 horas (em microssegundos)
uint64_t tempoSono = 86400ULL * 1000000ULL;
esp_sleep_enable_timer_wakeup(tempoSono);
esp_deep_sleep_start();
}
void loop() {
// Loop permanece vazio pois o Deep Sleep reinicia o chip a cada ciclo
}
Passo a Passo de Execução
- Abra o Telegram e pesquise por
@BotFather. - Envie o comando
/newbotpara criar seu robô e guarde o Token API. - Pesquise por
@userinfobot, envie qualquer mensagem e anote seu número de Chat ID. - Abra o código na Arduino IDE, insira seu SSID, Senha do Wi-Fi, Token e Chat ID.
- Conecte o ESP32-CAM via módulo MB USB no PC e faça o upload (Selecione a placa AI Thinker ESP32-CAM).
- Instale o dispositivo na caixa hermética apontado para o medidor de água e pronto!
Próximos Passos & Automação Avançada
Este projeto pode facilmente evoluir. Com a imagem sendo gerada, você pode integrá-lo ao Home Assistant e utilizar o projeto open-source AI-on-the-edge-device, que aplica OCR (Reconhecimento Óptico de Caracteres) para ler os números da foto automaticamente e gerar gráficos do consumo de água por dia.
Ainda indo mais adiante você pode adicionar baterias, inclusive a Energia solar deixando ainda mais econômica e a prova de falta de energia
Views: 5
