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!
Comments
Comentários