Existem no mercado muitas soluções para automatizar a iluminação da sua casa, mas esses produtos podem ser controlados apenas por aplicativos proprietários ou assistentes virtuais. Neste post, veremos como criar um Interruptor Inteligente DIY que pode ser integrado com outros dispositivos ou softwares customizados feitos por nós, makers.

Materiais Necessários
- ESP-01
- Relé de 1 Canal
- Fonte regulada de 5V
- Regulador 3V3 LM78L03
- Perfboard
- Interruptor convencional
Circuito

A montagem do circuito pode ser vista na imagem acima. Você pode utilizar um carregador de celular junto com um regulador de 3.3V para fornecer energia ao circuito, ou utilizar uma fonte como a Hi-Link 3V3, sugerida na lista de materiais, para fornecer 3.3V a partir de 110V ou 220V.
A parte mais delicada envolve as ligações do relé:
- O comum do relé deve ser conectado à fase da rede elétrica da sua casa.
- O normalmente aberto deve ser conectado ao ao retorno da lâmpada que deseja controlar.
Os dois pólos do seu interruptor devem ser conectados aos pinos GPIO0 e GPIO2 do ESP-01.
É essencial desligar o disjuntor da área desejada antes de começar a instalação do equipamento. Caso não se sinta confortável lidando com rede elétrica, peça ajuda de um profissional para realizar a instalação.
PCB – Placa de Circuito Impresso (Opcional)

Caso queira montar uma PCB como a realizada no projeto, baixe o PDF com o design e siga os passos apresentados no post Como fazer uma PCB de forma caseira.
Configuração Sinric Pro
Para controlar o interruptor pela nuvem e pelos assistentes virtuais, utilizaremos o serviço Sinric Pro. Basta seguir os passos de configuração do serviço apresentados no post Faça sua Fita LED Smart com Alexa e ESP8266 selecionando o tipo do dispositivo como Smart Switch.
Programação do Interruptor Inteligente
Para a programação do nosso interruptor, utilizaremos a biblioteca SinricPro, que pode ser instalada a partir do gerenciador de bibliotecas da ferramenta Arduino IDE. Com a biblioteca instalada, basta substituir os dados da sua rede WiFi e da SinricPro definidos na configuração no código e carregar no ESP8266.
/* #------------------------# | Smart Switch | | 1CH | | Ítalo Coelho | #------------------------# */ //WIFI ----------------------- #include <Arduino.h> #include <ArduinoOTA.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> //Arduino-------------------- #include <EEPROM.h> //Sinric Pro----------------- #include <SinricPro.h> #include <SinricProSwitch.h> //Settings----------------------------------------------------------------------------------- #define MySSID "nome-da-rede-wifi" #define MyWifiPassword "senha-da-rede-wifi" #define Sinric_Key "chave-SinricPro" #define Sinric_Secret "segredo-SinricPro" #define Switch_ID "id-do-dispositivo" #define UpdateDelay 5 //5 Seconds before HUB Update #define SwitchGND 0 //Switch Ground Pin #define SwitchPin 2 //Switch Control Pin #define RelayPin 3 //Living Room Light Relay Pin //------------------------------------------------------------------------------------------- //Object Declarations HTTPClient http; WiFiClient client; WiFiServer server(80); //Control Variables------------ bool State = false; bool SwitchState = false; //Function Prototypes------------------------------------------------ void LAN(); void turnOn(String deviceId); void turnOff(String deviceId); void UpdateHub(bool CommandSent = false); bool onPowerState(const String &deviceId, bool &state) { if(state) turnOn(deviceId); else turnOff(deviceId); return true; // request handled properly } void setup() { pinMode(SwitchGND, OUTPUT); pinMode(SwitchPin, INPUT); pinMode(RelayPin, OUTPUT); digitalWrite(SwitchGND, LOW); EEPROM.begin(4); State = EEPROM.read(1); SwitchState = EEPROM.read(2); if(State) digitalWrite(RelayPin, LOW); else digitalWrite(RelayPin, HIGH); Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY); //WiFi Connection WiFi.mode(WIFI_STA); WiFi.begin(MySSID, MyWifiPassword); Serial.print("\nConnecting to Wifi: "); Serial.print(MySSID); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println("[OK]"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); //Setup SinricPro + Callback Functions SinricProSwitch& mySwitch = SinricPro[Switch_ID]; mySwitch.onPowerState(onPowerState); SinricPro.onConnected ([](){ Serial.println("[SinricPro]: Connected");}); SinricPro.onDisconnected([](){ Serial.println("[SinricPro]: Disconnected");}); SinricPro.begin(Sinric_Key, Sinric_Secret); //Start the server server.begin(); //Start OTA Update Service ArduinoOTA.setHostname("Interruptor Inteligente"); ArduinoOTA.begin(); //Blink Lights to Indicate Successful Boot for(int i = 0; i < 2; i++) { delay(1000); if(State) digitalWrite(RelayPin, HIGH); else digitalWrite(RelayPin, LOW); delay(1000); if(State) digitalWrite(RelayPin, LOW); else digitalWrite(RelayPin, HIGH); } } void loop() { ArduinoOTA.handle(); SinricPro.handle(); LAN(); UpdateHub(false); static uint64_t then = millis()/100; static uint64_t now = millis()/100; now = millis()/100; if(now - then > 1) { bool newSwitchState = digitalRead(SwitchPin); if(newSwitchState != SwitchState) { then = now; SwitchState = newSwitchState; EEPROM.write( 2, SwitchState); EEPROM.commit(); if(State) { turnOff(Switch_ID); } else { turnOn(Switch_ID); } } } } void turnOn(String deviceId) { if (deviceId == Switch_ID) { digitalWrite(RelayPin, LOW); State = true; EEPROM.write( 1, State); EEPROM.commit(); Serial.println(" Turn ON"); UpdateHub(true); } } void turnOff(String deviceId) { if (deviceId == Switch_ID) { digitalWrite(RelayPin, HIGH); State = false; EEPROM.write( 1, State); EEPROM.commit(); Serial.println(" Turn OFF"); UpdateHub(true); } } void LAN() { //Check if a client has connected WiFiClient clientLAN = server.available(); if (!clientLAN) return; //Wait until the client sends some data while (!clientLAN.available()) { delay(1); } //Read the first line of the request Serial.print("\nLAN request: "); String request = clientLAN.readStringUntil('\r'); Serial.println(request); //Handle the request if (request.indexOf("OK") != -1) return; if (request.indexOf("RESTART") != -1) ESP.restart(); if (request.indexOf("_off") != -1) turnOff(Switch_ID); if (request.indexOf("_on") != -1) turnOn(Switch_ID); clientLAN.print("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); clientLAN.flush(); } void UpdateHub(bool CommandSent) { static uint64_t LastUpdate = millis()/1000; if(millis()/1000 - LastUpdate >= 120) { SinricProSwitch& mySwitch = SinricPro[Switch_ID]; mySwitch.sendPowerStateEvent(State); LastUpdate = millis()/1000; } }
Utilização do Interruptor Inteligente
Uma vez montado, nosso circuito permite que o interruptor inteligente possa ser controlado de diversas formas:
- Pelo botão físico
- Pelo aplicativo da Sinric Pro
- Pelos assistentes virtuais Alexa e Google Home
- Assim como por meio de requisições GET feitas para o IP do dispositivo na rede local.
Em se tratando das requisições GET, a estrutura das requisições é muito simples:
- http://xxx.xxx.x.xxx/_on → Liga
- http://xxx.xxx.x.xxx/_off → Desliga
Sendo xxx.xxx.x.xxx o endereço IP do dispositivo na rede local. É recomendado definir um IP fixo para esses dispositivos no seu roteador para garantir que o IP não se altere com o passar do tempo e eventual reinicialização do roteador.

Como nosso interruptor pode ser facilmente controlado pela rede local, podemos integrá-lo com outros projetos como, por exemplo, o Botão Inteligente.
Gostou de aprender a fazer seu próprio interruptor inteligente? Deixe um comentário aqui embaixo nos contando o que achou.
Ítalo, ótimo post. Sabe de algum controlador que tenha interface API com uma quantidade maior de relês?
Olá Cleiton.
Infelizmente não temos disponível.
Att.
Vitor Mattos.
Suporte Técnico MakerHero.
Olá Ítalo, tenho um projeto desenvolver uma fechadura com integração com DB. Você desenvolve projetos sobre demanda?