CONTROLAR PERSIANAS COM O MÓDULO SHELLY 2.5 E ESP32 (ROLLER MODE)

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!