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
227 stars 121 forks source link

doorbell example has false positives #346

Closed tstack closed 7 months ago

tstack commented 8 months ago

First, thanks for writing this, it has made hooking up my doorbell to alexa/google-home really easy.

I started with the doorbell example, but it had a habit of being too sensitive and generated false positives. The following code will trigger an event at the slightest provocation:

https://github.com/sinricpro/esp8266-esp32-sdk/blob/246c363f8bb439f137fbe53162f7a334e298994f/examples/doorbell/doorbell.ino#L54-L55

I ended up rewriting it to make sure the button was pressed for at least 25ms before triggering the event. This is the code I ended up with (note that the pin mode for the button is set to INPUT_PULLUP):

enum class ButtonState {
  on,
  off,
};

// checkButtonpress
// reads if BUTTON_PIN gets LOW and send Event
void checkButtonPress() {
  static std::optional<unsigned long> firstBtnLow;
  static std::optional<unsigned long> firstBtnHigh;
  static ButtonState buttonState = ButtonState::off;
  unsigned long actualMillis = millis();
  auto buttonPinValue = digitalRead(BUTTON_PIN);

  if (buttonState == ButtonState::on) {
    if (buttonPinValue == HIGH) {
      if (!firstBtnHigh) {
        firstBtnHigh = actualMillis;
      } else {
        if (actualMillis - firstBtnHigh.value() > 25) {
          buttonState = ButtonState::off;
          firstBtnHigh = std::nullopt;
          firstBtnLow = std::nullopt;
        }
      }
    } else {
      firstBtnHigh = std::nullopt;
    }
  } else if (buttonPinValue == LOW) {
    if (!firstBtnLow) {
      firstBtnLow = actualMillis;
    } else {
      if (actualMillis - firstBtnLow.value() > 25) {
        firstBtnHigh = std::nullopt;
        firstBtnLow = std::nullopt;
        buttonState = ButtonState::on;
        Serial.printf("Ding dong...\r\n");
        // get Doorbell device back
        SinricProDoorbell& myDoorbell = SinricPro[DOORBELL_ID];

        // send doorbell event
        myDoorbell.sendDoorbellEvent();
      }
    }
  } else {
    firstBtnLow = std::nullopt;
  }
}

This code is much closer to what is generated for a button in esphome.

sivar2311 commented 7 months ago

It's been more than 14 days since anything happened on this issue, so I'm going to close it. If you have any further questions about this issue, please feel free to reopen it.