Vídeo deste Projeto no nosso canal do YouTube:
Se num dos últimos artigos deste blog aprendemos a controlar o Shelly 1PM com a ESP32 controlar o Shelly 1PM com a ESP32, ficava pendente o controlo de mais alguns módulos da marca. Neste artigo, vamos, através da nossa placa ESP32, alterar o estado das nossas persianas de casa, podendo fechá-las ou abri-las com um simples clique!
- Material Necessário
Para este projeto, vamos precisar dos seguintes materiais:
Imagem | Produto | Comprar |
---|---|---|
![]() |
ESP32 (NodeMCU) | |
![]() |
Shelly 2.5 | |
![]() |
Display LCD 20×4 I2C | |
![]() |
2 Breadboard’s 830 Pinos | |
![]() |
3 Botões de Pressão | |
![]() |
3 Resistências 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 os 3 botões de pressão em configuração pull-up resistor com as respetivas resistências, e os impulsos ligam-se às portas 2, 5 e 19, dos botões de fechar, parar e abrir a persiana, respetivamente.
No que toca ao módulo Shelly, alimentamos o mesmo com o fio fase e neutro, de onde este último derivamos para o neutro do motor de persiana. Ligamos um fio de controlo do motor ao terminal “01” do Shelly e o outro ao terminal “02”.
- 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 Controlo de Persiana Modelos testados e aprovados: ->Shelly 2.5 (Roller Mode) DISCLAMER: Restantes módulos podem não funcionar corretamente. www.electrofun.pt/blog/controlar-persianas-com-o-modulo-shelly-2-5-e-esp32-roller-mode 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 pinoBotaoFechar 2 //Conectar o botão de pressão em configuração pull-up resistor ao pino GPIO 2 #define pinoBotaoParar 5 //Conectar o botão de pressão em configuração pull-up resistor ao pino GPIO 5 #define pinoBotaoAbrir 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"; char* updateShelly25RollerPath = "http://[IP_DO_SHELLY]/roller/0"; char* openShelly25RollerPath = "http://[IP_DO_SHELLY]/roller/0?go=open"; char* closeShelly25RollerPath = "http://[IP_DO_SHELLY]/roller/0?go=close"; char* stopShelly25RollerPath = "http://[IP_DO_SHELLY]/roller/0?go=stop"; char* setRollerModeShelly25RollerPath = "http://[IP_DO_SHELLY]/settings/0?mode=roller"; //Declaração de Variáveis Necessárias String estadoPersianaString, lastDirPersianaString, leituraShelly; unsigned long delayLCD = 0; long oldTime = 0; void setup() { Serial.begin(115200); pinMode(pinoBotaoFechar, INPUT); pinMode(pinoBotaoParar, INPUT); pinMode(pinoBotaoAbrir, 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(); httpGETRequest(setRollerModeShelly25RollerPath); lcd.init(); lcd.backlight(); lcd.setCursor(2, 0); lcd.print("Controlo Modulo"); lcd.setCursor(5, 1); lcd.print("Shelly 2.5"); lcd.setCursor(5, 2); lcd.print("Modo Roller"); lcd.setCursor(1, 3); lcd.print("By Electrofun@2022"); delay(5000); lcd.clear(); } void loop() { atualizarDados(); atualizarLCD(); mudarEstadoPersiana(); } void atualizarDados() { if ((millis() - oldTime) > 1000 || oldTime == 0) { if (WiFi.status() == WL_CONNECTED) { leituraShelly = httpGETRequest(updateShelly25RollerPath); JSONVar myObject = JSON.parse(leituraShelly); if (JSON.typeof(myObject) == "undefined") { Serial.println("Parsing input failed!"); return; } JSONVar keys = myObject.keys(); JSONVar estadoPersianaJSONValue = myObject[keys[0]]; JSONVar lastDirPersianaJSONValue = myObject[keys[7]]; estadoPersianaString = JSON.stringify(estadoPersianaJSONValue); estadoPersianaString = estadoPersianaString.substring(1, 5); lastDirPersianaString = JSON.stringify(lastDirPersianaJSONValue); lastDirPersianaString = lastDirPersianaString.substring(1, 5); Serial.println(estadoPersianaString); Serial.println(lastDirPersianaString); } else { Serial.println("WiFi Disconnected"); } oldTime = millis(); } } void atualizarLCD() { if (millis() - delayLCD > 1000 || delayLCD == 0) { lcd.clear(); lcd.setCursor(7, 0); lcd.print("STATUS"); lcd.setCursor(2, 2); lcd.print("Estado Persiana:"); if (estadoPersianaString == "stop" && lastDirPersianaString == "clos") { lcd.setCursor(6, 3); lcd.print("Fechada"); } else if (estadoPersianaString == "stop" && lastDirPersianaString == "open") { lcd.setCursor(7, 3); lcd.print("Aberta");; } else if (estadoPersianaString == "open") { lcd.setCursor(6, 3); lcd.print("A Abrir");; } else if (estadoPersianaString == "clos") { lcd.setCursor(6, 3); lcd.print("A Fechar");; } delayLCD = millis(); } } void mudarEstadoPersiana() { if (digitalRead(pinoBotaoFechar) == 1) { //Fechar delay(500); Serial.println("Fechar"); httpGETRequest(closeShelly25RollerPath); } else if (digitalRead(pinoBotaoParar) == 1) { //Parar Serial.println("Parar"); delay(500); httpGETRequest(stopShelly25RollerPath); } else if (digitalRead(pinoBotaoAbrir) == 1) { //Abrir Serial.println("Abrir"); delay(500); httpGETRequest(openShelly25RollerPath); } } 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!