CONTROLAR O MÓDULO SHELLY 1PM COM ESP32!
Não há como negar, os módulos da marca Shelly são ótimos para quem pretende uma domótica de forma fácil e em conta, mas os verdadeiros fãs de eletrónica gostam sempre de mostrar ideias “out-of-the-box”, explorando não só o básico dos seus produtos, como também os desafios mais exigentes! Neste projeto, vamos controlar o módulo Shelly 1PM com a ESP32, capaz de ligar ou desligar o relé e mostrar o consumo em tempo real no display LCD, bem como a tensão aos terminais da saída do mesmo. Vamos começar!
- Material Necessário
Para este projeto, vamos precisar dos seguintes materiais:
Imagem | Produto | Comprar |
---|---|---|
ESP32 (NodeMCU) | ||
Shelly 1PM | ||
Display LCD 20×4 I2C | ||
2 Breadboard’s 830 Pinos | ||
Botão de Pressão | ||
Resistência 1K | ||
Fios de Ligação Macho-Macho | ||
Fios de Ligação Macho-Fêmea |
- Montagem do Circuito
Vamos interligar todos os componentes anteriormente mencionados. Começamos por ligar o LCD: o pino 21 liga-se ao pino SDA e o pino 22 ao pino SCL. Usamos o “Vin” e o “GND” da ESP32 para alimentação. De seguida, configuramos o botão em função pull-up resistor e o sinal é enviado para o pino 19.
- Configurar o módulo Shelly
Abrimos a app “Shelly Cloud” no smartphone e adicionamos o mesmo na nossa rede local. Se já tiver um adicionado, basta anotar o IP do mesmo, utilizado posteriormente no código do programa.
- Arduino IDE
Por último, resta abrir o Arduino IDE, transferir todas as livrarias necessárias para o projeto, selecionar a correta placa microcontroladora, bem como a sua porta série, e colar o código do projeto.
Biblioteca LiquidCrytal_I2C.h
Biblioteca Arduino_JSON.h
Código
/*Código do Sistema de Controlo de Módulos de Automação Shelly Possibilidade de controlar o estado da saída do módulo e a sua tensão, bem como monitorar o consumo do equipamento. Modelos testados e aprovados: ->Shelly Plus 1PM DISCLAMER: Restantes módulos podem não funcionar corretamente. www.electrofun.pt/blog/controlar-o-modulo-shelly-1pm-com-esp32 Electrofun@2022 ---> www.electrofun.pt */ //Inclusão de livrarias e add-on's #include <WiFi.h> #include <HTTPClient.h> #include <Arduino_JSON.h> #include <LiquidCrystal_I2C.h> #define pinoBotao 19 //Conectar o botão de pressão em configuração pull-up resistor ao pino GPIO 19 LiquidCrystal_I2C lcd(0x27, 20, 4); //A preencher pelo utilizador const char* SSID_WIFI = "SSID"; const char* PASSWORD_WIFI = "PASSWORD"; const char* updateShellyPath = "http://[IP_DO_SHELLY]/rpc/Switch.GetStatus?id=0"; const char* onShellyPath = "http://[IP_DO_SHELLY]/relay/0?turn=on"; const char* offShellyPath = "http://[IP_DO_SHELLY]/relay/0?turn=off"; //Declaração de Variáveis Necessárias int potenciaInt, tensaoInt; unsigned long oldTime = 0; unsigned long delayLCD = 0; String leituraShelly, estadoReleString; bool estadoShellyBool, estadoBotao; void setup() { Serial.begin(115200); pinMode(pinoBotao, INPUT); WiFi.begin(SSID_WIFI, PASSWORD_WIFI); Serial.print("A ligar à rede Wi-Fi"); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(300); } Serial.println(); Serial.print("Conexão bem sucedida. IP: "); Serial.println(WiFi.localIP()); Serial.println(); lcd.init(); lcd.backlight(); lcd.setCursor(2, 0); lcd.print("Controlo Modulos"); lcd.setCursor(7, 1); lcd.print("Shelly"); lcd.setCursor(0, 2); lcd.print("Com Medicao Consumo"); lcd.setCursor(1, 3); lcd.print("By Electrofun@2022"); delay(5000); lcd.clear(); } void loop() { atualizarDados(); estadoBotao = digitalRead(pinoBotao); if (estadoBotao == 1) { delay(500); mudarEstadoShelly(); } atualizarLCD(); } void atualizarDados() { if ((millis() - oldTime) > 1000) { if (WiFi.status() == WL_CONNECTED) { leituraShelly = httpGETRequest(updateShellyPath); JSONVar myObject = JSON.parse(leituraShelly); if (JSON.typeof(myObject) == "undefined") { Serial.println("Parsing input failed!"); return; } JSONVar keys = myObject.keys(); JSONVar estadoReleJSONValue = myObject[keys[2]]; JSONVar potenciaJSONValue = myObject[keys[3]]; JSONVar tensaoJSONValue = myObject[keys[4]]; estadoReleString = JSON.stringify(estadoReleJSONValue); if (estadoReleString == "false") { estadoShellyBool = false; } else if (estadoReleString == "true") { estadoShellyBool = true; } potenciaInt = int(potenciaJSONValue); tensaoInt = int(tensaoJSONValue); } else { Serial.println("WiFi Disconnected"); } oldTime = millis(); } } void mudarEstadoShelly() { if (estadoReleString == "false") { httpGETRequest(onShellyPath); } else if (estadoReleString == "true") { httpGETRequest(offShellyPath); } } void atualizarLCD() { if (millis() - delayLCD > 2000 || delayLCD == 0) { lcd.clear(); lcd.setCursor(5, 0); lcd.print("Shelly 1PM"); lcd.setCursor(0, 1); lcd.print("Estado: "); if (estadoReleString == "false") { lcd.print("OFF"); } else { lcd.print("ON"); } lcd.setCursor(0, 2); lcd.print("Tensao: "); lcd.print(tensaoInt); lcd.print('V'); lcd.setCursor(0, 3); lcd.print("Potencia: "); lcd.print(potenciaInt); lcd.print('W'); delayLCD = millis(); } } String httpGETRequest(const char* serverName) { WiFiClient client; HTTPClient http; http.begin(client, serverName); int httpResponseCode = http.GET(); String payload = "{}"; if (httpResponseCode > 0) { payload = http.getString(); } else { Serial.print("Error code: "); Serial.println(httpResponseCode); } http.end(); return payload; }
Não se esqueçam de ver o nosso vídeo sobre este artigo no nosso canal do YouTube:
Para mais projetos, percorram o nosso blog, onde podem encontrar vários artigos interessantes relacionados com eletrónica, robótica e muito mais! Visitem também o nosso site, onde encontram tudo para eletrónica e robótica!