Seu portão eletrônico funciona perfeitamente, mas você sempre sonhou em controlá-lo pelo celular ou por comando de voz? Se o seu portão tem mais de 10 anos e não possui essas funcionalidades, este tutorial vai te mostrar como adicionar inteligência ao sistema existente sem precisar trocar a central.
Por que automatizar um portão antigo?
A maioria dos portões eletrônicos instalados entre 1995-2010 possui apenas controle remoto básico. Automatizar significa:
- Controle remoto ilimitado: Abra de qualquer lugar do mundo
- Integração com Alexa/Google: "Alexa, abra o portão"
- Histórico de acessos: Veja quem entrou e quando
- Múltiplos usuários: Compartilhe acesso com família
- Notificações: Receba alerta quando alguém chegar
Material necessário
Componentes eletrônicos:
- ESP32 DevKit V1 - R$ 30-50
- Módulo relé 5V 1 canal - R$ 12-25
- Sensor magnético reed switch - R$ 15-30
- Fonte 5V 2A - R$ 22-35
- Protoboard e jumpers - R$ 15-25
- Caixa plástica vedada - R$ 15-25
Ferramentas:
- Ferro de solda
- Multímetro
- Furadeira
- Chaves de fenda/phillips
Custo total: R$ 110-190
⚠️ Importante: As marcas mencionadas neste tutorial (Broadlink, Sinric Pro, Home Assistant, etc.) são citadas apenas para fins educativos e informativos. Não possuímos qualquer parceria, vínculo comercial ou patrocínio com essas empresas. As recomendações são baseadas em funcionalidade técnica e disponibilidade no mercado brasileiro.
Como funciona o sistema
O ESP32 atua como um "intermediário inteligente" entre você e a central do portão:
- Detecção: Sensor magnético monitora se portão está aberto/fechado
- Comando: ESP32 recebe comando (app, Alexa, botão)
- Acionamento: Relé simula o botão do controle remoto original
- Feedback: Sistema confirma se portão abriu/fechou
- Histórico: Registra todos os acionamentos com data/hora
Preparando o ambiente de desenvolvimento
1. Instalar Arduino IDE
Baixe em: https://www.arduino.cc/en/software
2. Configurar ESP32 no Arduino IDE
- Vá em Arquivo > Preferências
- Em "URLs Adicionais", adicione:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
- Ferramentas > Placa > Gerenciador de Placas
- Procure "esp32" e instale
3. Instalar bibliotecas necessárias
No Arduino IDE: Sketch > Incluir Biblioteca > Gerenciar Bibliotecas
Instale estas bibliotecas:
- WiFi (já incluída no ESP32)
- ESPAsyncWebServer por lacamera
- AsyncTCP por dvarrel
- ArduinoJson por Benoit Blanchon
- NTPClient por Fabrice Weinberg
Montagem do circuito
Conexões ESP32:
ESP32 | Componente |
---|---|
GPIO 2 | LED indicador (opcional) |
GPIO 4 | Pino IN do módulo relé |
GPIO 18 | Reed switch (sensor portão) |
5V | VCC do relé |
GND | GND do relé e reed switch |
⚠️ Importante - Segurança:
- NUNCA conecte o ESP32 diretamente na rede elétrica 110V/220V
- Use sempre um relé adequado para isolar os circuitos
- Desligue a energia antes de fazer qualquer conexão
Esquema de ligação na central do portão:
A maioria das centrais antigas possui dois fios para botão externo (normalmente rotulados como "BOTÃO" ou "BT"). O relé vai simular o pressionamento deste botão:
Central do Portão:
- Fio 1 (BOTÃO +) → Terminal COM do relé
- Fio 2 (BOTÃO -) → Terminal NA do relé
Código do ESP32
👀 Ver código completo do ESP32
#include <WiFi.h> #include <ESPAsyncWebServer.h> #include <ArduinoJson.h> #include <NTPClient.h> #include <WiFiUdp.h> // Configurações WiFi const char* ssid = "SEU_WIFI"; const char* password = "SUA_SENHA"; // Pinos const int RELAY_PIN = 4; const int REED_PIN = 18; const int LED_PIN = 2; // Servidor web AsyncWebServer server(80); // NTP para timestamp WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "pool.ntp.org", -3*3600, 60000); // Variáveis de estado bool portaoAberto = false; unsigned long ultimoAcionamento = 0; String historicoAcessos = ""; void setup() { Serial.begin(115200); // Configurar pinos pinMode(RELAY_PIN, OUTPUT); pinMode(REED_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); digitalWrite(LED_PIN, LOW); // Conectar WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Conectando ao WiFi..."); digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Piscar LED } digitalWrite(LED_PIN, HIGH); // LED fixo quando conectado Serial.println("WiFi conectado!"); Serial.print("IP: "); Serial.println(WiFi.localIP()); // Iniciar NTP timeClient.begin(); // Configurar rotas do servidor web configurarRotas(); // Iniciar servidor server.begin(); Serial.println("Servidor iniciado!" </>); } void loop() { timeClient.update(); // Ler estado do sensor bool estadoAtual = digitalRead(REED_PIN) == LOW; // LOW = portão aberto if (estadoAtual != portaoAberto) { portaoAberto = estadoAtual; String evento = portaoAberto ? "ABERTO" : "FECHADO"; adicionarHistorico(evento + " (sensor)"); Serial.println("Portão: " + evento); } delay(100); } void acionarPortao() { Serial.println("Acionando portão..."); // Pulso no relé (simula pressionar botão) digitalWrite(RELAY_PIN, HIGH); delay(500); // 0.5 segundos digitalWrite(RELAY_PIN, LOW); ultimoAcionamento = millis(); adicionarHistorico("ACIONADO (comando)"); } void adicionarHistorico(String evento) { String timestamp = timeClient.getFormattedTime(); String entrada = timestamp + " - " + evento + "\n"; historicoAcessos = entrada + historicoAcessos; // Manter apenas últimas 50 entradas int contadorLinhas = 0; int posicao = 0; while ((posicao = historicoAcessos.indexOf('\n', posicao + 1)) != -1) { contadorLinhas++; if (contadorLinhas >= 50) { historicoAcessos = historicoAcessos.substring(0, posicao); break; } } } void configurarRotas() { // Página principal server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ String html = gerarPaginaHTML(); request->send(200, "text/html", html); }); // Acionar portão server.on("/acionar", HTTP_POST, [](AsyncWebServerRequest *request){ acionarPortao(); request->send(200, "application/json", "{\"status\":\"ok\",\"message\":\"Portão acionado\"}"); }); // Status do portão server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request){ StaticJsonDocument<200> doc; doc["portaoAberto"] = portaoAberto; doc["ultimoAcionamento"] = ultimoAcionamento; doc["timestamp"] = timeClient.getFormattedTime(); String response; serializeJson(doc, response); request->send(200, "application/json", response); }); // Histórico server.on("/historico", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/plain", historicoAcessos); }); } String gerarPaginaHTML() { String html = R"( <!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1'> <title>Controle do Portão</title> <style> body { font-family: Arial; text-align: center; margin: 20px; } .button { background: #4CAF50; color: white; padding: 15px 30px; border: none; border-radius: 5px; font-size: 18px; cursor: pointer; margin: 10px; } .button:hover { background: #45a049; } .status { padding: 10px; margin: 20px 0; border-radius: 5px; font-weight: bold; font-size: 16px; } .aberto { background: #f44336; color: white; } .fechado { background: #4CAF50; color: white; } #historico { text-align: left; background: #f5f5f5; padding: 10px; border-radius: 5px; font-family: monospace; white-space: pre-line; max-height: 300px; overflow-y: auto; } </style> </head> <body> <h1>🚪 Controle do Portão Inteligente</h1> <div id='status' class='status'> Carregando status... </div> <button class='button' onclick='acionarPortao()'> 🔄 Acionar Portão </button> <h3>📋 Histórico de Acessos</h3> <div id='historico'>Carregando histórico...</div> <script> function atualizarStatus() { fetch('/status') .then(response => response.json()) .then(data => { const statusDiv = document.getElementById('status'); if (data.portaoAberto) { statusDiv.textContent = '🔓 PORTÃO ABERTO'; statusDiv.className = 'status aberto'; } else { statusDiv.textContent = '🔒 PORTÃO FECHADO'; statusDiv.className = 'status fechado'; } }); } function acionarPortao() { fetch('/acionar', { method: 'POST' }) .then(response => response.json()) .then(data => { alert(data.message); setTimeout(atualizarStatus, 2000); // Atualizar após 2s }); } function atualizarHistorico() { fetch('/historico') .then(response => response.text()) .then(data => { document.getElementById('historico').textContent = data || 'Nenhum histórico ainda.'; }); } // Atualizar a cada 5 segundos setInterval(atualizarStatus, 5000); setInterval(atualizarHistorico, 10000); // Carregar inicial atualizarStatus(); atualizarHistorico(); </script> </body> </html> )"; return html; }
Interface Web Completa
O sistema inclui uma interface web responsiva com controle completo do portão:
Funcionalidades da interface:
- 🚪 Status em tempo real: Portão aberto/fechado
- 🔄 Botão de acionamento: Abrir/fechar remotamente
- 📋 Histórico completo: Últimos 50 eventos
- 📱 Design responsivo: Funciona em qualquer dispositivo
- 🔄 Atualização automática: Status a cada 5 segundos
Instalação física
1. Localização do ESP32
Instale próximo à central do portão, em local protegido da chuva:
- Dentro de caixa vedada IP65
- Próximo a tomada 110V/220V
- Com sinal WiFi adequado
2. Instalação do sensor reed switch
O sensor detecta se o portão está aberto/fechado:
- Fixe o ímã na parte móvel do portão
- Fixe o sensor na parte fixa (pilar/muro)
- Distância máxima: 2cm entre ímã e sensor
- Teste antes de fixar definitivamente
3. Conexão na central existente
⚠️ IMPORTANTE: Desligue a energia antes desta etapa
- Localize os terminais "BOTÃO" na sua central
- Desconecte um dos fios do botão existente (se houver)
- Conecte os terminais COM e NA do relé nestes pontos
- O botão original continuará funcionando normalmente
Configuração e teste
1. Upload do código
- Conecte ESP32 no computador via USB
- Selecione a placa: ESP32 Dev Module
- Selecione a porta COM correta
- Altere SSID e senha do WiFi no código
- Faça upload
2. Primeiro teste
- Abra o monitor serial (115200 baud)
- ESP32 deve conectar ao WiFi e exibir o IP
- Acesse o IP no navegador
- Teste o botão "Acionar Portão"
3. Teste do sensor
- Aproxime/afaste o ímã do sensor
- Status deve mudar na interface web
- Histórico deve registrar as mudanças
Integração com Alexa
Para controle por voz, use o serviço Sinric Pro (gratuito para até 3 dispositivos):
1. Criar conta no Sinric Pro
- Acesse: https://sinric.pro/
- Crie conta gratuita
- Adicione dispositivo tipo "Switch"
2. Código adicional para Alexa
Adicione estas linhas no início do código:
#include <SinricPro.h> #include <SinricProSwitch.h> #define SINRIC_APP_KEY "SEU_APP_KEY" #define SINRIC_APP_SECRET "SEU_APP_SECRET" #define SINRIC_DEVICE_ID "SEU_DEVICE_ID" bool onPowerState(const String &deviceId, bool &state) { acionarPortao(); state = true; // Sempre retorna true após acionar return true; } // No setup(), adicione: SinricProSwitch& mySwitch = SinricPro[SINRIC_DEVICE_ID]; mySwitch.onPowerState(onPowerState); SinricPro.begin(SINRIC_APP_KEY, SINRIC_APP_SECRET);
3. Vincular com Alexa
- Instale skill "Sinric Pro" na Alexa
- Faça login com sua conta
- Descubra dispositivos
- Comando: "Alexa, ligar portão"
Troubleshooting
Problema: ESP32 não conecta ao WiFi
Soluções:
- Verificar SSID e senha no código
- Testar com celular se WiFi está funcionando
- Aproximar ESP32 do roteador
- Verificar se rede é 2.4GHz (ESP32 não suporta 5GHz)
Problema: Portão não aciona
Verificações:
- Relé está energizado? (LED do relé deve acender)
- Conexões na central estão corretas?
- Fios não estão invertidos?
- Central do portão está ligada?
Problema: Sensor não detecta posição
Soluções:
- Aproximar ímã do sensor (máximo 2cm)
- Verificar polaridade do ímã
- Testar sensor com multímetro
- Verificar conexão dos fios
Problema: Interface web não carrega
Verificações:
- ESP32 está conectado ao WiFi?
- IP está correto?
- Firewall não está bloqueando?
- Tentar acessar por outro dispositivo
Melhorias avançadas
1. Notificação push no celular
Integrate com Pushover ou Telegram Bot:
- Receba notificação quando portão abrir
- Alerta se portão ficar aberto por muito tempo
2. Controle por aplicativo dedicado
Use Blynk para criar app personalizado:
- Interface mais bonita
- Widgets customizados
- Histórico com gráficos
3. Backup de configurações
Salve configurações na memória EEPROM:
- WiFi não precisa ser reprogramado
- Configurações via interface web
4. Câmera de segurança
Adicione ESP32-CAM para:
- Ver quem está no portão
- Foto automática quando acionar
- Stream de vídeo
Considerações de segurança
1. Segurança de rede
- Use senha forte no WiFi
- Considere criar rede separada (IoT)
- Atualize firmware do roteador
2. Segurança física
- Proteja ESP32 em caixa vedada
- Dificulte acesso aos fios
- Use fonte com proteção
3. Backup manual
- Mantenha controle remoto original
- Instale botão manual de emergência
- Documente as conexões
Custo-benefício
Investimento e economia:
- Investimento inicial: R$ 110-190
- Economia vs. sistema novo: R$ 800-1500
Funcionalidades adicionais:
- Controle remoto ilimitado
- Integração com Alexa/Google
- Histórico de acessos
- Notificações personalizadas
- Expansão futura (câmeras, sensores)
Conclusão
Automatizar um portão antigo com ESP32 é um projeto gratificante que combina eletrônica básica com programação e resulta em um sistema extremamente útil no dia a dia.
O sistema criado é robusto, confiável e pode ser expandido com diversas funcionalidades. Mais importante: você não precisa descartar seu equipamento antigo - apenas adiciona inteligência a ele.
Próximos passos sugeridos:
- Monte o circuito em protoboard primeiro
- Teste todas as funcionalidades
- Solde em placa perfurada para instalação definitiva
- Documente sua instalação específica
- Compartilhe sua experiência com a comunidade maker!
Tem alguma dúvida ou sugestão? A automação residencial é um mundo fascinante e este é apenas o primeiro passo de uma jornada muito interessante!
💡 Dica: Depois de dominar este projeto, você pode aplicar os mesmos conceitos para automatizar outros equipamentos antigos como interfones, sistemas de irrigação e equipamentos industriais.