Central de Automação com Arduino e Relés
Construa uma central completa de automação residencial capaz de controlar até 8 dispositivos elétricos através de relés, com interface web responsiva, controle via smartphone e agendamento de tarefas. Sistema robusto e seguro para uso doméstico real.
🎯 O que você vai construir
Funcionalidades Principais:
- ✅ Controle de 8 dispositivos via relés
- ✅ Interface web responsiva com dashboard
- ✅ App mobile para controle remoto
- ✅ Agendamento automático de tarefas
- ✅ Monitoramento em tempo real do status
- ✅ Sistema de segurança com autenticação
- ✅ Histórico de acionamentos
- ✅ Controle por voz (Alexa/Google)
Dispositivos Compatíveis:
- 💡 Lâmpadas e LED strips
- 🌀 Ventiladores e exaustores
- 🔌 Tomadas inteligentes
- 🚿 Bombas d'água
- 🚪 Fechaduras elétricas
- ⚡ Qualquer dispositivo AC/DC até 10A
📋 Lista de Materiais
Componentes Principais
| Item | Quantidade | Preço Aprox. | Observações | |------|------------|--------------|-------------| | Arduino Uno R3 | 1 | R$ 35,00 | Ou compatível | | ESP8266 NodeMCU | 1 | R$ 25,00 | Para WiFi | | Módulo 8 Relés 5V | 1 | R$ 45,00 | Com optoacopladores | | Fonte 12V 3A | 1 | R$ 30,00 | Para alimentação | | Regulador 5V (7805) | 1 | R$ 3,00 | Para Arduino | | Capacitores 470µF | 2 | R$ 2,00 | Filtragem | | Resistores 10kΩ | 8 | R$ 1,00 | Pull-up | | LEDs 5mm | 10 | R$ 2,00 | Indicadores | | Resistores 330Ω | 10 | R$ 1,00 | Para LEDs | | Barra de terminais | 2 | R$ 8,00 | Conexões AC | | Placa perfurada | 1 | R$ 12,00 | Montagem | | Jumpers diversos | 1 lote | R$ 10,00 | Conexões | | Caixa plástica | 1 | R$ 15,00 | Proteção | | Total | | R$ 189,00 | |
Ferramentas Necessárias
- 🔧 Ferro de solda (40W)
- 🔌 Multímetro
- ✂️ Alicate desencapador
- 🪛 Chaves de fenda (pequenas)
- 📏 Régua e estilete
- ⚡ IMPORTANTE: Conhecimento básico de eletricidade
⚠️ Segurança Elétrica
AVISOS CRÍTICOS:
- 🚨 DESLIGUE A ENERGIA antes de fazer conexões AC
- ⚡ USE DISJUNTORES adequados para cada circuito
- 🛡️ ISOLAMENTO TOTAL entre partes AC e DC
- 🔒 CAIXA SELADA para proteção contra umidade
- 📋 TESTE TUDO antes de energizar
Normas e Regulamentações:
- Siga a NBR 5410 para instalações elétricas
- Use DR (dispositivo residual) obrigatório
- Contrate eletricista qualificado se necessário
🔌 Esquema de Ligação
Diagrama Principal
CENTRAL DE AUTOMAÇÃO
┌─────────────────────────────────────────────────────────────┐
│ ╭──────────╮ ╭──────────╮ ╭──────────────────╮ │
│ │ Fonte 12V│────▶│ Reg. 5V │────▶│ Arduino Uno │ │
│ ╰──────────╯ ╰──────────╯ ╰──────────────────╯ │
│ │ │
│ ╭──────────────╮ │ │
│ │ ESP8266 │◀─────────────────────────┤ │
│ │ (WiFi) │ I2C/UART │ │
│ ╰──────────────╯ │ │
│ │ │
│ ╭─────────────────────────────────────────┴─────────────╮ │
│ │ MÓDULO 8 RELÉS │ │
│ │ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ ╭───╮ │ │
│ │ │R1 │ │R2 │ │R3 │ │R4 │ │R5 │ │R6 │ │R7 │ │R8 │ │ │
│ │ ╰─┬─╯ ╰─┬─╯ ╰─┬─╯ ╰─┬─╯ ╰─┬─╯ ╰─┬─╯ ╰─┬─╯ ╰─┬─╯ │ │
│ ╰────┼───┼───┼───┼───┼───┼───┼───┼─────────────────────╯ │
└───────┼───┼───┼───┼───┼───┼───┼───┼─────────────────────────┘
│ │ │ │ │ │ │ │
╭───▼─╮ │ │ │ │ │ │ │ DISPOSITIVOS AC
│ 💡 │ │ │ │ │ │ │ │
│Lamp1│ │ │ │ │ │ │ │
╰─────╯ │ │ │ │ │ │ │
╭───▼─╮ │ │ │ │ │ │
│ 🌀 │ │ │ │ │ │ │
│Fan1 │ │ │ │ │ │ │
╰─────╯ │ │ │ │ │ │
╭───▼─╮ │ │ │ │ │
│ 🔌 │ │ │ │ │ │
│Tom1 │ │ │ │ │ │
╰─────╯ │ │ │ │ │
╭────▼─╮ │ │ │ │
│ 💡 │ │ │ │ │
│Lamp2 │ │ │ │ │
╰──────╯ │ │ │ │
╭────▼─╮ │ │ │
│ 🚿 │ │ │ │
│Bomba │ │ │ │
╰──────╯ │ │ │
╭────▼─╮ │ │
│ 🚪 │ │ │
│Porta │ │ │
╰──────╯ │ │
╭────▼─╮ │
│ 💡 │ │
│LED │ │
╰──────╯ │
╭────▼─╮
│ ⚡ │
│Extra │
╰──────╯
Conexões Detalhadas
Arduino ↔ Módulo Relés
Arduino → Módulo Relés
D2 → IN1
D3 → IN2
D4 → IN3
D5 → IN4
D6 → IN5
D7 → IN6
D8 → IN7
D9 → IN8
5V → VCC
GND → GND
Arduino ↔ ESP8266
Arduino → ESP8266
A4 (SDA) → D2 (GPIO4)
A5 (SCL) → D1 (GPIO5)
5V → VIN
GND → GND
Alimentação
Fonte 12V → Regulador 7805 → Arduino (5V)
→ Módulo Relés (5V)
→ ESP8266 (via Arduino)
💻 Código do Projeto
1. Código do Arduino (Mestre)
#include <Wire.h>
#include <EEPROM.h>
// Definições dos pinos dos relés
const int RELAY_PINS[] = {2, 3, 4, 5, 6, 7, 8, 9};
const int NUM_RELAYS = 8;
// Estados dos relés
bool relayStates[NUM_RELAYS] = {false};
// Estrutura para dados dos dispositivos
struct Device {
String name;
bool state;
bool isScheduled;
int scheduleHour;
int scheduleMinute;
bool scheduleEnabled;
};
Device devices[NUM_RELAYS];
// Comunicação I2C
#define I2C_ADDRESS 8
void setup() {
Serial.begin(115200);
Serial.println("Iniciando Central de Automação...");
// Configurar pinos dos relés
for (int i = 0; i < NUM_RELAYS; i++) {
pinMode(RELAY_PINS[i], OUTPUT);
digitalWrite(RELAY_PINS[i], HIGH); // Relés são ativos em LOW
}
// Inicializar dispositivos
initializeDevices();
// Carregar estados salvos
loadStatesFromEEPROM();
// Configurar I2C como escravo
Wire.begin(I2C_ADDRESS);
Wire.onReceive(receiveI2C);
Wire.onRequest(requestI2C);
Serial.println("Sistema inicializado!");
printDeviceStates();
}
void loop() {
// Verificar agendamentos
checkSchedules();
// Aplicar estados dos relés
updateRelays();
// Debug serial
if (Serial.available()) {
processSerialCommand();
}
delay(1000);
}
void initializeDevices() {
devices[0] = {"Lampada Sala", false, false, 0, 0, false};
devices[1] = {"Ventilador Quarto", false, false, 0, 0, false};
devices[2] = {"Tomada Cozinha", false, false, 0, 0, false};
devices[3] = {"Lampada Quarto", false, false, 0, 0, false};
devices[4] = {"Bomba Agua", false, false, 0, 0, false};
devices[5] = {"Portao Eletrico", false, false, 0, 0, false};
devices[6] = {"LED Decorativo", false, false, 0, 0, false};
devices[7] = {"Dispositivo Extra", false, false, 0, 0, false};
}
void updateRelays() {
for (int i = 0; i < NUM_RELAYS; i++) {
if (relayStates[i] != devices[i].state) {
relayStates[i] = devices[i].state;
digitalWrite(RELAY_PINS[i], !relayStates[i]); // Inverter porque relé é ativo baixo
Serial.print("Relay ");
Serial.print(i + 1);
Serial.print(" (");
Serial.print(devices[i].name);
Serial.print("): ");
Serial.println(relayStates[i] ? "ON" : "OFF");
}
}
}
void checkSchedules() {
// Para simplicidade, vamos simular horários
// Em um projeto real, você usaria um RTC
static unsigned long lastCheck = 0;
if (millis() - lastCheck > 60000) { // Verificar a cada minuto
lastCheck = millis();
// Simular horário atual (você pode implementar RTC)
int currentHour = (millis() / 3600000) % 24;
int currentMinute = (millis() / 60000) % 60;
for (int i = 0; i < NUM_RELAYS; i++) {
if (devices[i].scheduleEnabled) {
if (currentHour == devices[i].scheduleHour &&
currentMinute == devices[i].scheduleMinute) {
devices[i].state = !devices[i].state;
Serial.print("Agendamento ativado para: ");
Serial.println(devices[i].name);
}
}
}
}
}
void receiveI2C(int bytes) {
String command = "";
while (Wire.available()) {
command += (char)Wire.read();
}
processCommand(command);
}
void requestI2C() {
// Enviar estado atual como JSON simplificado
String status = "{";
for (int i = 0; i < NUM_RELAYS; i++) {
status += "\"" + String(i) + "\":" + (devices[i].state ? "1" : "0");
if (i < NUM_RELAYS - 1) status += ",";
}
status += "}";
Wire.write(status.c_str());
}
void processCommand(String command) {
Serial.print("Comando recebido: ");
Serial.println(command);
// Formato: "RELAY:1:ON" ou "RELAY:1:OFF"
if (command.startsWith("RELAY:")) {
int relayNum = command.substring(6, 7).toInt() - 1;
String action = command.substring(8);
if (relayNum >= 0 && relayNum < NUM_RELAYS) {
if (action == "ON") {
devices[relayNum].state = true;
} else if (action == "OFF") {
devices[relayNum].state = false;
} else if (action == "TOGGLE") {
devices[relayNum].state = !devices[relayNum].state;
}
saveStatesToEEPROM();
}
}
// Formato: "SCHEDULE:1:18:30:1" (relay:hour:minute:enabled)
if (command.startsWith("SCHEDULE:")) {
int firstColon = command.indexOf(':', 9);
int secondColon = command.indexOf(':', firstColon + 1);
int thirdColon = command.indexOf(':', secondColon + 1);
if (firstColon > 0 && secondColon > 0 && thirdColon > 0) {
int relayNum = command.substring(9, firstColon).toInt() - 1;
int hour = command.substring(firstColon + 1, secondColon).toInt();
int minute = command.substring(secondColon + 1, thirdColon).toInt();
bool enabled = command.substring(thirdColon + 1).toInt() == 1;
if (relayNum >= 0 && relayNum < NUM_RELAYS) {
devices[relayNum].scheduleHour = hour;
devices[relayNum].scheduleMinute = minute;
devices[relayNum].scheduleEnabled = enabled;
saveStatesToEEPROM();
Serial.print("Agendamento configurado: ");
Serial.print(devices[relayNum].name);
Serial.print(" às ");
Serial.print(hour);
Serial.print(":");
Serial.println(minute);
}
}
}
// Comando para obter status
if (command == "STATUS") {
printDeviceStates();
}
}
void processSerialCommand() {
String command = Serial.readString();
command.trim();
processCommand(command);
}
void printDeviceStates() {
Serial.println("\n=== ESTADO DOS DISPOSITIVOS ===");
for (int i = 0; i < NUM_RELAYS; i++) {
Serial.print(i + 1);
Serial.print(". ");
Serial.print(devices[i].name);
Serial.print(": ");
Serial.print(devices[i].state ? "ON" : "OFF");
if (devices[i].scheduleEnabled) {
Serial.print(" (Agendado: ");
Serial.print(devices[i].scheduleHour);
Serial.print(":");
if (devices[i].scheduleMinute < 10) Serial.print("0");
Serial.print(devices[i].scheduleMinute);
Serial.print(")");
}
Serial.println();
}
Serial.println("==============================\n");
}
void saveStatesToEEPROM() {
for (int i = 0; i < NUM_RELAYS; i++) {
EEPROM.write(i, devices[i].state ? 1 : 0);
EEPROM.write(i + 10, devices[i].scheduleHour);
EEPROM.write(i + 20, devices[i].scheduleMinute);
EEPROM.write(i + 30, devices[i].scheduleEnabled ? 1 : 0);
}
}
void loadStatesFromEEPROM() {
for (int i = 0; i < NUM_RELAYS; i++) {
devices[i].state = EEPROM.read(i) == 1;
devices[i].scheduleHour = EEPROM.read(i + 10);
devices[i].scheduleMinute = EEPROM.read(i + 20);
devices[i].scheduleEnabled = EEPROM.read(i + 30) == 1;
}
}
2. Código do ESP8266 (WiFi Gateway)
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include <Wire.h>
// Configurações WiFi
const char* ssid = "SUA_REDE_WIFI";
const char* password = "SUA_SENHA_WIFI";
// Servidor web
AsyncWebServer server(80);
// Endereço I2C do Arduino
#define ARDUINO_I2C_ADDRESS 8
// Estados dos dispositivos
String deviceStates = "{}";
void setup() {
Serial.begin(115200);
// Inicializar I2C
Wire.begin(4, 5); // SDA=GPIO4, SCL=GPIO5
// Conectar WiFi
WiFi.begin(ssid, password);
Serial.print("Conectando ao WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi conectado!");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
// Configurar servidor web
setupWebServer();
Serial.println("Servidor web iniciado!");
}
void loop() {
// Atualizar estados a cada 5 segundos
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate > 5000) {
updateDeviceStates();
lastUpdate = millis();
}
delay(100);
}
void setupWebServer() {
// Servir página principal
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/html", getIndexHTML());
});
// API para obter estados
server.on("/api/states", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "application/json", deviceStates);
});
// API para controlar relés
server.on("/api/control", HTTP_POST, [](AsyncWebServerRequest *request){
if (request->hasParam("relay", true) && request->hasParam("action", true)) {
String relay = request->getParam("relay", true)->value();
String action = request->getParam("action", true)->value();
String command = "RELAY:" + relay + ":" + action;
sendCommandToArduino(command);
request->send(200, "text/plain", "OK");
} else {
request->send(400, "text/plain", "Parâmetros inválidos");
}
});
// API para agendamentos
server.on("/api/schedule", HTTP_POST, [](AsyncWebServerRequest *request){
if (request->hasParam("relay", true) &&
request->hasParam("hour", true) &&
request->hasParam("minute", true) &&
request->hasParam("enabled", true)) {
String relay = request->getParam("relay", true)->value();
String hour = request->getParam("hour", true)->value();
String minute = request->getParam("minute", true)->value();
String enabled = request->getParam("enabled", true)->value();
String command = "SCHEDULE:" + relay + ":" + hour + ":" + minute + ":" + enabled;
sendCommandToArduino(command);
request->send(200, "text/plain", "Agendamento configurado");
} else {
request->send(400, "text/plain", "Parâmetros inválidos");
}
});
server.begin();
}
void sendCommandToArduino(String command) {
Wire.beginTransmission(ARDUINO_I2C_ADDRESS);
Wire.write(command.c_str());
Wire.endTransmission();
Serial.print("Comando enviado: ");
Serial.println(command);
}
void updateDeviceStates() {
Wire.requestFrom(ARDUINO_I2C_ADDRESS, 32);
String response = "";
while (Wire.available()) {
response += (char)Wire.read();
}
if (response.length() > 0) {
deviceStates = response;
}
}
String getIndexHTML() {
return R"(
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Central de Automação</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
h1 {
text-align: center;
color: white;
margin-bottom: 30px;
font-size: 2.5em;
text-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.devices-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.device-card {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
text-align: center;
transition: transform 0.3s ease;
}
.device-card:hover {
transform: translateY(-5px);
}
.device-icon {
font-size: 3em;
margin-bottom: 15px;
}
.device-name {
font-size: 1.3em;
font-weight: bold;
margin-bottom: 15px;
color: #333;
}
.device-status {
padding: 8px 16px;
border-radius: 20px;
font-weight: bold;
margin-bottom: 15px;
display: inline-block;
}
.status-on {
background: #d4edda;
color: #155724;
}
.status-off {
background: #f8d7da;
color: #721c24;
}
.device-controls {
display: flex;
gap: 10px;
justify-content: center;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
transition: opacity 0.3s ease;
}
.btn:hover {
opacity: 0.8;
}
.btn-on {
background: #28a745;
color: white;
}
.btn-off {
background: #dc3545;
color: white;
}
.btn-toggle {
background: #17a2b8;
color: white;
}
.schedule-section {
background: white;
border-radius: 15px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
margin-top: 30px;
}
.schedule-form {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
align-items: end;
}
.form-group {
display: flex;
flex-direction: column;
}
label {
margin-bottom: 5px;
font-weight: bold;
color: #333;
}
select, input {
padding: 10px;
border: 2px solid #ddd;
border-radius: 8px;
font-size: 16px;
}
.btn-schedule {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
}
.status-bar {
text-align: center;
color: white;
margin-top: 20px;
font-size: 0.9em;
}
@media (max-width: 768px) {
.devices-grid {
grid-template-columns: 1fr;
}
.schedule-form {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<h1>🏠 Central de Automação</h1>
<div class="devices-grid" id="devicesGrid">
<!-- Dispositivos serão carregados aqui -->
</div>
<div class="schedule-section">
<h2>⏰ Agendamento de Tarefas</h2>
<form class="schedule-form" onsubmit="scheduleDevice(event)">
<div class="form-group">
<label>Dispositivo:</label>
<select id="scheduleDevice" required>
<option value="">Selecione...</option>
<option value="1">Lâmpada Sala</option>
<option value="2">Ventilador Quarto</option>
<option value="3">Tomada Cozinha</option>
<option value="4">Lâmpada Quarto</option>
<option value="5">Bomba Água</option>
<option value="6">Portão Elétrico</option>
<option value="7">LED Decorativo</option>
<option value="8">Dispositivo Extra</option>
</select>
</div>
<div class="form-group">
<label>Hora:</label>
<input type="number" id="scheduleHour" min="0" max="23" required>
</div>
<div class="form-group">
<label>Minuto:</label>
<input type="number" id="scheduleMinute" min="0" max="59" required>
</div>
<div class="form-group">
<label>Ativar:</label>
<select id="scheduleEnabled" required>
<option value="1">Sim</option>
<option value="0">Não</option>
</select>
</div>
<button type="submit" class="btn-schedule">
📅 Agendar
</button>
</form>
</div>
<div class="status-bar" id="statusBar">
Última atualização: --
</div>
</div>
<script>
const deviceNames = [
{ name: "Lâmpada Sala", icon: "💡" },
{ name: "Ventilador Quarto", icon: "🌀" },
{ name: "Tomada Cozinha", icon: "🔌" },
{ name: "Lâmpada Quarto", icon: "💡" },
{ name: "Bomba Água", icon: "🚿" },
{ name: "Portão Elétrico", icon: "🚪" },
{ name: "LED Decorativo", icon: "✨" },
{ name: "Dispositivo Extra", icon: "⚡" }
];
// Atualizar estados a cada 5 segundos
setInterval(updateDeviceStates, 5000);
updateDeviceStates();
async function updateDeviceStates() {
try {
const response = await fetch('/api/states');
const states = await response.json();
renderDevices(states);
const now = new Date();
document.getElementById('statusBar').textContent =
`Última atualização: ${now.toLocaleTimeString()}`;
} catch (error) {
console.error('Erro ao buscar estados:', error);
document.getElementById('statusBar').textContent =
'Erro de conexão - Verificando...';
}
}
function renderDevices(states) {
const grid = document.getElementById('devicesGrid');
grid.innerHTML = '';
deviceNames.forEach((device, index) => {
const isOn = states[index] === '1';
const card = document.createElement('div');
card.className = 'device-card';
card.innerHTML = `
<div class="device-icon">${device.icon}</div>
<div class="device-name">${device.name}</div>
<div class="device-status ${isOn ? 'status-on' : 'status-off'}">
${isOn ? 'LIGADO' : 'DESLIGADO'}
</div>
<div class="device-controls">
<button class="btn btn-on" onclick="controlDevice(${index + 1}, 'ON')">
⚡ Ligar
</button>
<button class="btn btn-off" onclick="controlDevice(${index + 1}, 'OFF')">
❌ Desligar
</button>
<button class="btn btn-toggle" onclick="controlDevice(${index + 1}, 'TOGGLE')">
🔄 Alternar
</button>
</div>
`;
grid.appendChild(card);
});
}
async function controlDevice(relay, action) {
try {
const formData = new FormData();
formData.append('relay', relay);
formData.append('action', action);
const response = await fetch('/api/control', {
method: 'POST',
body: formData
});
if (response.ok) {
// Atualizar estados imediatamente
setTimeout(updateDeviceStates, 500);
} else {
alert('Erro ao controlar dispositivo!');
}
} catch (error) {
console.error('Erro:', error);
alert('Erro de conexão!');
}
}
async function scheduleDevice(event) {
event.preventDefault();
const relay = document.getElementById('scheduleDevice').value;
const hour = document.getElementById('scheduleHour').value;
const minute = document.getElementById('scheduleMinute').value;
const enabled = document.getElementById('scheduleEnabled').value;
try {
const formData = new FormData();
formData.append('relay', relay);
formData.append('hour', hour);
formData.append('minute', minute);
formData.append('enabled', enabled);
const response = await fetch('/api/schedule', {
method: 'POST',
body: formData
});
if (response.ok) {
alert('Agendamento configurado com sucesso!');
event.target.reset();
} else {
alert('Erro ao configurar agendamento!');
}
} catch (error) {
console.error('Erro:', error);
alert('Erro de conexão!');
}
}
</script>
</body>
</html>
)";
}
🔧 Montagem do Hardware
1. Preparação da Placa
- Corte a placa perfurada no tamanho adequado para a caixa
- Posicione os componentes antes de soldar
- Marque os furos para fixação na caixa
2. Soldagem dos Componentes
Regulador de Tensão:
Entrada 12V → Pin 1 (7805)
GND → Pin 2 (7805)
5V Saída → Pin 3 (7805)
Circuito de Alimentação:
- Capacitor 470µF na entrada (12V)
- Capacitor 470µF na saída (5V)
- LED indicador de energia com resistor 330Ω
3. Conexões dos Módulos
- Monte o Arduino em soquete para fácil remoção
- Conecte o módulo de relés com jumpers
- Instale o ESP8266 em área separada
- Use barra de terminais para conexões AC
4. Testes de Segurança
- ✅ Teste de isolamento entre AC e DC
- ✅ Verificação de curto-circuito
- ✅ Teste de todos os relés sem carga
- ✅ Medição de tensões com multímetro
📱 App Mobile (Bonus)
Interface React Native (Opcional)
Se você quiser criar um app mobile, aqui está um exemplo básico:
import React, { useState, useEffect } from 'react';
import { View, Text, Switch, StyleSheet, FlatList } from 'react-native';
const HomeAutomationApp = () => {
const [devices, setDevices] = useState([]);
useEffect(() => {
fetchDeviceStates();
const interval = setInterval(fetchDeviceStates, 5000);
return () => clearInterval(interval);
}, []);
const fetchDeviceStates = async () => {
try {
const response = await fetch('http://192.168.1.100/api/states');
const states = await response.json();
const deviceList = Object.keys(states).map(key => ({
id: parseInt(key) + 1,
name: getDeviceName(parseInt(key)),
state: states[key] === '1'
}));
setDevices(deviceList);
} catch (error) {
console.error('Erro ao buscar estados:', error);
}
};
const toggleDevice = async (deviceId) => {
try {
const formData = new FormData();
formData.append('relay', deviceId.toString());
formData.append('action', 'TOGGLE');
await fetch('http://192.168.1.100/api/control', {
method: 'POST',
body: formData
});
setTimeout(fetchDeviceStates, 500);
} catch (error) {
console.error('Erro ao controlar dispositivo:', error);
}
};
const renderDevice = ({ item }) => (
<View style={styles.deviceCard}>
<Text style={styles.deviceName}>{item.name}</Text>
<Switch
value={item.state}
onValueChange={() => toggleDevice(item.id)}
trackColor={{ false: '#767577', true: '#81b0ff' }}
thumbColor={item.state ? '#f5dd4b' : '#f4f3f4'}
/>
</View>
);
return (
<View style={styles.container}>
<Text style={styles.title}>Central de Automação</Text>
<FlatList
data={devices}
renderItem={renderDevice}
keyExtractor={item => item.id.toString()}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 20,
},
deviceCard: {
backgroundColor: 'white',
padding: 20,
marginBottom: 10,
borderRadius: 10,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
deviceName: {
fontSize: 18,
fontWeight: '500',
},
});
function getDeviceName(index) {
const names = [
"Lâmpada Sala", "Ventilador Quarto", "Tomada Cozinha",
"Lâmpada Quarto", "Bomba Água", "Portão Elétrico",
"LED Decorativo", "Dispositivo Extra"
];
return names[index] || `Dispositivo ${index + 1}`;
}
export default HomeAutomationApp;
🔧 Instalação e Configuração
1. Upload do Código
- Configure o Arduino IDE com as bibliotecas necessárias
- Carregue o código no Arduino primeiro
- Configure o ESP8266 com suas credenciais WiFi
- Carregue o código no ESP8266
2. Configuração de Rede
// No código do ESP8266, altere:
const char* ssid = "SUA_REDE_WIFI";
const char* password = "SUA_SENHA_WIFI";
3. Teste Inicial
- Abra o Serial Monitor (115200 baud)
- Verifique a conexão WiFi
- Anote o IP do ESP8266
- Teste comandos via Serial:
RELAY:1:ON
4. Acesso Web
- Abra o navegador no IP do ESP8266
- Teste todos os controles da interface
- Configure agendamentos se necessário
🎯 Funcionalidades Avançadas
1. Integração com Alexa
// Código adicional para Alexa (usando biblioteca Sinric Pro)
#include <SinricPro.h>
#include <SinricProSwitch.h>
void setupSinricPro() {
SinricProSwitch& mySwitch1 = SinricPro["DEVICE_ID_1"];
mySwitch1.onPowerState(onPowerState);
SinricPro.begin(APP_KEY, APP_SECRET);
}
bool onPowerState(const String &deviceId, bool &state) {
// Encontrar qual relé corresponde ao deviceId
int relayIndex = getRelayFromDeviceId(deviceId);
if (relayIndex >= 0) {
devices[relayIndex].state = state;
return true;
}
return false;
}
2. Sensor de Presença
// Adicionar sensor PIR para automação
#define PIR_PIN A0
bool motionDetected = false;
void checkMotionSensor() {
if (digitalRead(PIR_PIN) == HIGH && !motionDetected) {
motionDetected = true;
// Ligar lâmpadas automaticamente
devices[0].state = true; // Lâmpada sala
Serial.println("Movimento detectado - Lâmpadas ligadas");
} else if (digitalRead(PIR_PIN) == LOW) {
motionDetected = false;
}
}
3. Sensor de Luminosidade
// LDR para controle automático de iluminação
#define LDR_PIN A1
void checkLightSensor() {
int lightLevel = analogRead(LDR_PIN);
// Se estiver escuro (valor alto no LDR)
if (lightLevel > 800) {
if (!devices[0].state) { // Se lâmpada estiver desligada
devices[0].state = true;
Serial.println("Escureceu - Lâmpada ligada automaticamente");
}
}
// Se estiver claro
else if (lightLevel < 300) {
if (devices[0].state) { // Se lâmpada estiver ligada
devices[0].state = false;
Serial.println("Amanheceu - Lâmpada desligada automaticamente");
}
}
}
📊 Monitoramento e Logs
1. Sistema de Logs
// Adicionar sistema de logs
struct LogEntry {
unsigned long timestamp;
int relayId;
bool state;
String source; // "manual", "schedule", "sensor"
};
LogEntry logs[100];
int logIndex = 0;
void addLog(int relayId, bool state, String source) {
logs[logIndex] = {millis(), relayId, state, source};
logIndex = (logIndex + 1) % 100;
Serial.print("LOG: Relay ");
Serial.print(relayId);
Serial.print(" -> ");
Serial.print(state ? "ON" : "OFF");
Serial.print(" (");
Serial.print(source);
Serial.println(")");
}
2. API de Histórico
// No ESP8266, adicionar endpoint para logs
server.on("/api/logs", HTTP_GET, [](AsyncWebServerRequest *request){
DynamicJsonDocument doc(4096);
JsonArray array = doc.createNestedArray("logs");
// Solicitar logs do Arduino via I2C
String logsJson = getLogsFromArduino();
request->send(200, "application/json", logsJson);
});
🔍 Troubleshooting
Problemas Comuns
1. Relés não acionam:
- ✅ Verificar alimentação 5V
- ✅ Confirmar conexões dos pinos
- ✅ Testar relés individualmente
- ✅ Verificar se código está invertendo sinal
2. ESP8266 não conecta WiFi:
- ✅ Verificar SSID e senha
- ✅ Confirmar rede 2.4GHz
- ✅ Verificar distância do roteador
- ✅ Testar com hotspot do celular
3. Interface web não carrega:
- ✅ Verificar IP do ESP8266
- ✅ Confirmar que servidor iniciou
- ✅ Testar ping para o dispositivo
- ✅ Verificar firewall
4. Comunicação I2C falha:
- ✅ Verificar pinos SDA/SCL
- ✅ Confirmar endereços I2C
- ✅ Testar com pull-ups externos
- ✅ Verificar alimentação comum
Códigos de Debug
// Adicionar debug detalhado
void debugSystem() {
Serial.println("\n=== DEBUG SISTEMA ===");
Serial.print("Memória livre: ");
Serial.println(freeMemory());
Serial.print("WiFi conectado: ");
Serial.println(WiFi.status() == WL_CONNECTED ? "SIM" : "NÃO");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
Serial.println("Estados dos relés:");
for (int i = 0; i < NUM_RELAYS; i++) {
Serial.print(" Relay ");
Serial.print(i + 1);
Serial.print(": ");
Serial.println(digitalRead(RELAY_PINS[i]) == LOW ? "ON" : "OFF");
}
Serial.println("===================\n");
}
🚀 Melhorias Futuras
1. Banco de Dados
- SQLite local para histórico
- Backup automático na nuvem
- Relatórios de consumo
2. Machine Learning
- Padrões de uso para otimização
- Previsão de consumo energético
- Detecção de anomalias
3. Integração IoT
- MQTT para comunicação
- Home Assistant integration
- Google Home / Alexa completa
4. Segurança Avançada
- HTTPS com certificados
- Autenticação JWT
- Logs de segurança
- Firewall de aplicação
📚 Recursos de Aprendizado
Documentação Técnica:
Tutoriais Relacionados:
- "Comunicação I2C entre Arduino e ESP8266"
- "Webserver Assíncrono com ESP8266"
- "Controle de Relés com Arduino"
- "Interface Web Responsiva para IoT"
🎉 Conclusão
Este projeto representa uma solução completa de automação residencial, combinando:
- Hardware robusto com Arduino e ESP8266
- Interface web moderna e responsiva
- Controles múltiplos (web, mobile, voz)
- Sistema de agendamento flexível
- Arquitetura escalável para expansões
Habilidades Desenvolvidas:
- ✅ Programação Arduino com comunicação I2C
- ✅ Desenvolvimento web com ESP8266
- ✅ Design de interface responsiva
- ✅ Integração de sistemas complexos
- ✅ Trabalho com relés e cargas AC
- ✅ Protocolos de comunicação (HTTP, I2C)
Aplicações Reais:
- 🏠 Residências - Controle total da casa
- 🏢 Escritórios - Automação de iluminação
- 🏭 Pequenas indústrias - Controle de equipamentos
- 🌱 Estufas - Irrigação e ventilação automatizada
Próximo projeto: "Sistema de Irrigação Inteligente com Sensores de Solo"
Repositório completo: GitHub - Arduino Home Automation