sinricpro / esp8266-esp32-sdk

Library for https://sinric.pro - simple way to connect your device to Alexa, Google Home, SmartThings and cloud
https://sinric.pro
Other
236 stars 125 forks source link

Slinding gate with ESP32 and SINRIC code problems #257

Closed josebdomingues closed 2 years ago

josebdomingues commented 2 years ago

Hello, I wanted to control my sliding gate with an ESP32 and SINRIC, initially I am using only one limit switch for the gate to stop when it reaches the limit and two relays one to open and one to close, I am having problems in the code, when I order it to open in SINRIC, it receives the message and appears in the Serial Monitor, but the state of the relay does not change.

#define wifiLed   2
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif 
#include <Arduino.h>
#ifdef ESP8266 
#include <ESP8266WiFi.h>
#endif 
#ifdef ESP32   
#include <WiFi.h>
#endif

#include "SinricPro.h"
#include "SinricProGarageDoor.h"
int opening = 22;
int closing = 23;
int lmtswitch = 18;
int lmtswitch2 = 19;

#define WIFI_SSID         "-----"    
#define WIFI_PASS         "-------"
#define APP_KEY           "---------------"      // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET        "----------------------"   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define GARAGEDOOR_ID     "------------------"    // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define BAUD_RATE         9600                     // Change baudrate to your need

bool onDoorState(const String& deviceId, bool& doorState) {
    Serial.printf("Garagedoor is %s now.\r\n", doorState ? "closed" : "open");
    switch (doorState) {
        case true:
            if (digitalRead(lmtswitch) == LOW) {
                digitalWrite(opening, HIGH);
                digitalWrite(closing, LOW);
            } else {
                digitalWrite(opening, LOW);
                digitalWrite(closing, LOW);
            }

        case false:
            if (digitalRead(lmtswitch2) == LOW) {
                digitalWrite(closing, HIGH);
                digitalWrite(opening, LOW);
            } else {
                digitalWrite(opening, LOW);
                digitalWrite(closing, LOW);
                return true;
            }
    }
}

void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  IPAddress localIP = WiFi.localIP();
  digitalWrite(wifiLed, HIGH);
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %d.%d.%d.%d\r\n", localIP[0], localIP[1], localIP[2], localIP[3]);
}

void setupSinricPro() {
  SinricProGarageDoor &myGarageDoor = SinricPro[GARAGEDOOR_ID];
  myGarageDoor.onDoorState(onDoorState);

  // setup SinricPro
  SinricPro.onConnected([](){ Serial.printf("Connected to SinricPro\r\n"); }); 
  SinricPro.onDisconnected([](){ Serial.printf("Disconnected from SinricPro\r\n"); });
  SinricPro.begin(APP_KEY, APP_SECRET);
}

void setup() {
  pinMode(22, OUTPUT);
  pinMode(23, OUTPUT);
  digitalWrite(22, LOW);
  digitalWrite(23, LOW);
  pinMode(18, INPUT);
  pinMode(19, INPUT);
  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  setupWiFi();
  setupSinricPro();
}

void loop() {
  SinricPro.handle();
}
sivar2311 commented 2 years ago

Hi @josebdomingues! I have reformatted your code to make it more readable.

Pitfall: It looks like your switch / case statement is missing a break. If doorState is true also the false case gets executed! Better use an if statement instead of switch / case. (It's a boolean, it only can be true or false:

bool onDoorState(const String& deviceId, bool& doorState) {
    Serial.printf("Garagedoor is %s now.\r\n", doorState ? "closed" : "open");
    if (doorState == true) {
        if (digitalRead(lmtswitch) == LOW) {
            digitalWrite(opening, HIGH);
            digitalWrite(closing, LOW);
        } else {
            digitalWrite(opening, LOW);
            digitalWrite(closing, LOW);
        }
    } else {
        if (digitalRead(lmtswitch2) == LOW) {
            digitalWrite(closing, HIGH);
            digitalWrite(opening, LOW);
        } else {
            digitalWrite(opening, LOW);
            digitalWrite(closing, LOW);
        }
    }
    return true;
}
sivar2311 commented 2 years ago

Warning: There is no check for the limitswitches while the gate is moving! Your gate won't stop moving if one of the limitswitch is HIGH.

sivar2311 commented 2 years ago
void open_gate() {
    if (digitalRead(lmtswitch) == HIGH) return; // do noting when the gate is open
    digitalWrite(opening, LOW);
    digitalWrite(closing, HIGH);
}

void close_gate() {
    if (digitalRead(lmtswitch2) == HIGH) return; // do noting when the gate is closed
    digitalWrite(opening, HIGH);
    digitalWrite(closing, LOW);
}

void stop_gate() {
    digitalWrite(opening, LOW);
    digitalWrite(closing, LOW);
}

bool check_gate() {
    if (digitalRead(lmtswitch) == HIGH || digitalRead(lmtswitch2) == HIGH) stop_gate();
}

bool onDoorState(const String& deviceId, bool& doorState) {
    Serial.printf("Garagedoor is %s now.\r\n", doorState ? "closed" : "open");
    if (doorState == true) {
        if (digitalRead(lmtswitch) == LOW) {
            close_gate();
        } else {
            stop_gate();
        }
    } else {
        if (digitalRead(lmtswitch2) == LOW) {
            open_gate();
        } else {
            stop_gate();
        }
    }
    return true;
}

void loop() {
    SinricPro.handle();
    check_gate();
}

Edit: fixed missing digitalRead's

josebdomingues commented 2 years ago

Thanks a lot for the help! When I close and open the gate in SINRIC, the state of the relay changes, but if I press the limit switch it does nothing, when I press the limit switch the motor should stop

sivar2311 commented 2 years ago

It looks like your motor wiring is active low.

Since I don't know your exact wiring, I have made the code more abstract. You can now adapt the configuration to your wiring by changing lines 31-33 (LIMITSWITCH_ACTIVE_LEVEL, MOTOR_ACTIVE_LEVEL, WIFI_LED_ACTIVE_LEVEL)

#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <WiFi.h>
#endif

#include "SinricPro.h"
#include "SinricProGarageDoor.h"

#define WIFI_SSID     "-----"
#define WIFI_PASS     "-------"
#define APP_KEY       "---------------"         // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET    "----------------------"  // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define GARAGEDOOR_ID "------------------"      // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define BAUD_RATE     9600                      // Change baudrate to your need

#define WIFI_LED 2

#define MOTOR_OPEN        22
#define MOTOR_CLOSE       23
#define LIMITSWITCH_OPEN  18
#define LIMITSWITCH_CLOSE 19

#define MOTOR_ACTIVE_LEVEL       LOW
#define LIMITSWITCH_ACTIVE_LEVEL HIGH
#define WIFI_LED_ACTIVE_LEVEL    LOW

void open_gate() {
    if (digitalRead(LIMITSWITCH_OPEN) == LIMITSWITCH_ACTIVE_LEVEL) return;  // do noting when the gate is open
    digitalWrite(MOTOR_OPEN, MOTOR_ACTIVE_LEVEL);
    digitalWrite(MOTOR_CLOSE, !MOTOR_ACTIVE_LEVEL);
}

void close_gate() {
    if (digitalRead(LIMITSWITCH_CLOSE) == LIMITSWITCH_ACTIVE_LEVEL) return;  // do noting when the gate is closed
    digitalWrite(MOTOR_OPEN, !MOTOR_ACTIVE_LEVEL);
    digitalWrite(MOTOR_CLOSE, MOTOR_ACTIVE_LEVEL);
}

void stop_gate() {
    digitalWrite(MOTOR_OPEN, !MOTOR_ACTIVE_LEVEL);
    digitalWrite(MOTOR_CLOSE, !MOTOR_ACTIVE_LEVEL);
}

bool gate_is_closed() {
    return digitalRead(LIMITSWITCH_CLOSE) == LIMITSWITCH_ACTIVE_LEVEL;
}

bool gate_is_open() {
    return digitalRead(LIMITSWITCH_OPEN) == LIMITSWITCH_ACTIVE_LEVEL;
}

void check_gate() {
    if (gate_is_closed() || gate_is_open()) stop_gate();
}

bool onDoorState(const String& deviceId, bool& doorState) {
    Serial.printf("Gate is %s\r\n", doorState ? "closing" : "opening");
    if (doorState == true) {
        if (gate_is_closed() == false) close_gate();
    } else {
        if (gate_is_open() == false) open_gate();
    }
    return true;
}

void setupWiFi() {
    Serial.printf("\r\n[Wifi]: Connecting");
    WiFi.begin(WIFI_SSID, WIFI_PASS);

    while (WiFi.status() != WL_CONNECTED) {
        Serial.printf(".");
        delay(250);
    }
    digitalWrite(WIFI_LED, !WIFI_LED_ACTIVE_LEVEL);
    Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

void setup_pins() {
    pinMode(MOTOR_OPEN, OUTPUT);
    pinMode(MOTOR_CLOSE, OUTPUT);

    pinMode(LIMITSWITCH_OPEN, INPUT);
    pinMode(LIMITSWITCH_CLOSE, INPUT);

    pinMode(WIFI_LED, OUTPUT);
}

void setupSinricPro() {
    SinricProGarageDoor& myGarageDoor = SinricPro[GARAGEDOOR_ID];
    myGarageDoor.onDoorState(onDoorState);

    // setup SinricPro
    SinricPro.onConnected([]() { Serial.printf("Connected to SinricPro\r\n"); });
    SinricPro.onDisconnected([]() { Serial.printf("Disconnected from SinricPro\r\n"); });
    SinricPro.begin(APP_KEY, APP_SECRET);
}

void setup() {
    Serial.begin(BAUD_RATE);
    Serial.printf("\r\n\r\n");
    setup_pins();
    stop_gate();
    setupWiFi();
    setupSinricPro();
}

void loop() {
    SinricPro.handle();
    check_gate();
}
josebdomingues commented 2 years ago

When I open the gate and press the limit switch close it stops but when I have any limit switch active it does not open or close, for example if the "limit switch close" is active when I open the gate it just clicks on the relay and not stay active, I really appreciate your help, if you want i can send a video

PS: when I open the gate this message appears in SINRIC "Device did not handle "setMode""

sivar2311 commented 2 years ago

Please see and accept my invitation to a private repository and let's continue there. Your questions are outside of SinricPro library.

sivar2311 commented 2 years ago

This issue is closed because the bug has been identified in comment #2. The project will be continued in another repository.