SonOff ESP8266: Probleme beim Button-Handling

Hallo,

ich bin erfahrener Web-Entwickler (Java, Javascript), Arduino bzw. ESP8266 sind jedoch komplett neu für mich. Mit C hatte ich Berührung im Studium. Ist aber eine zeitlang her.

Worum geht’s mir?
Ich habe den Artikel “Basteffreundlich” aus der C’t verfolgt und auf einigen SonOff S20 bei mir im Haus die über GitHub erhältliche freie Firmware geflasht und auch einige Anpassungen gemacht. Alles gut soweit!

Ich habe im Haus auf einem Raspberry eine zentrale Steckdosenverwaltung auf NodeJS-Basis entwickelt.
Meine SonOff-Geräte lassen sich nun über ein zentrales WebFrontend schalten.

Was mir fehlt, ich eine Notification an meine Verwaltung auf dem Raspi, wenn jemand manuell den Button auf der SonOff drückt.
Hierzu habe ich eine Funktion UpdateSocket() geschrieben, die einen POST an meinen Server sendet:

void UpdateSocket(int state) {
    char cState[16];
    itoa(state, cState, 10);
    HTTPClient http;
    http.begin("http://raspberrypi:3000/update");
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    char payload[400];
    snprintf(payload, sizeof(payload), "socket_id=%s&title=%s&type=ip&url=%s%s&state=%s&host=%s&icon_filename=%s", socketId, socketName, socketHost, toggleMethod, cState, socketHost, iconFilename);
    int httpCode = http.POST(payload);
}

Diese Funktion rufe ich an zentraler Stelle, in den Funktionen Switch_On / Switch_Off auf:

void Switch_On(void) {
  relais = 1;
  digitalWrite(gpio13Led, LOW);
  digitalWrite(gpio12Relay, relais);
  startAt = 0;
  delay(1000);
  UpdateSocket(1);
}
void Switch_Off(void) {
  relais = 0;
  digitalWrite(gpio13Led, HIGH);
  digitalWrite(gpio12Relay, relais);
  stopAt = 0;
  delay(1000);
  UpdateSocket(0);
}

Diese beiden Funktionen werden sowohl beim Schalten über HTTP, als auch über den Button aufgerufen.

D.h. eigentlich sollte der Ablauf identisch sein.

Jedoch wird meine Funktion bei Betätigung des Buttons nicht aufgerufen, obwohl in jedem Fall Switch_On() bzw. Switch_Off() durchlaufen werden.

Der Button wird über folgende Funktion abgefragt, die über einen Ticker alle 0.1 Sekunden ausgeführt wird:

void check(void)
{
  // removed other code
  [...]
  
#if USE_LOCAL_BUTTON == 1
  //check gpio0 (button of Sonoff device)

  if ((digitalRead(0) == 0) and not status)
  {
    status = (digitalRead(0) == 0);
    if (relais == 0) {
      Switch_On();
    } else {
      Switch_Off();
    }
  }
  status = (digitalRead(0) == 0);
#endif
}

Wie kann es sein, dass mein Post-Request über den Button niemals getriggert wird, bei Aufruf über HTTP jedoch schon?

Es scheint so, als würde der Aufruf meiner Funktion UpdateSocket() beim Einstieg über den Button einfach übergangen, als existierte er nicht.

Anbei meine komplette Firmware und oben über Github auch die original freie Firmware von der C’t.

Über jegliche Hilfe wäre ich sehr dankbar.

Viele Grüße,
Sascha.

Aux1.ino (11.6 KB)

bau dir mehr serial prints ein und verfolge was dein Programm macht.

auch nach
int httpCode = http.POST(payload);
würde ich mir den httpCode ausgeben lassen.

deine Ifs ...

was willst du mit

status = (digitalRead(0) == 0);

zuweisen? einen negierten digitalread?

Gibt es einen PullUp- oder PullDown-Widerstand, sonst vermisse ich sowas wie pinMode(0, INPUT_PULLUP);