GPIO & Button Input as a toggle button

Hello,

I am really struggling with my code, I have tried to archive what I want for a long time.
I have a SONOFF Basic, so it’s basically a ESP8266, and reprogrammed it with the Arduino IDE.
GPIO14 is used as an Input. If it's LOW the relay should close and vise versa. GPIO14 has a PULLUP Resistor.
Now I want to use the GPIO0, which is a Button to toggle the relay as well.The button is already soldered on the PCB of the SONOFF.

In short what I want to archive is a GPIO Input and Button Input as a toggle button of the same Output:

  • GPIO14 is either HIGH or LOW. HIGH = Relay closed, LOW = Relay open
  • GPIO0 is a connected to a button. LOW when pressed. HIGH when released.
    It should work like a toggle button:
    -> relay is open -> press button -> relay is closed -> press button -> relay is open -> …
  • and if GPIO14 is LOW the relay should be open as well, to avoid a closed relay when the Input on
    GPIO14 is LOW if it gets LOW due to a crash or not powered MCU where the Input for the GPIO14 is
    coming from.

I have written a code which archives nearly this. The Input from GPIO14 is controlling the relay as it should, but the GPIO0 only works half as I like it. It only closes the relay when the button is pressed, when it is released the relay opens again.

My Code looks like this:

const int detect = 14;
const int relay = 12;
const int led = 13;
const int button = 0;

bool current_ledState = 0;
bool detect_state;
bool button_state = 0;

void setup() {
  Serial.begin(115200);

  pinMode(detect, INPUT);

  pinMode(relay, OUTPUT);
  digitalWrite(relay, LOW);   //LOW = OFF

  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH);    //HIGH = LED is OFF

  pinMode(button, INPUT);

}

void loop() {
  detect_state = digitalRead(detect);    //NodeMCU gibt vor ob Licht ON oder OFF sein soll
  button_state = digitalRead(button)
                 ;
  Serial.print("current_ledState: "); Serial.println(current_ledState);
  Serial.print("detect_state: "); Serial.println(detect_state);
  Serial.print("button_state: "); Serial.println(button_state);

  if (button_state == 0) {
    digitalWrite(relay, HIGH);
    digitalWrite(led, LOW);
    current_ledState = 1;
    Serial.println("Relay ON 2");
  }
  else if (detect_state == 1 && current_ledState == 0) {
    digitalWrite(relay, HIGH);
    digitalWrite(led, LOW);
    current_ledState = 1;
    Serial.println("Relay ON 1");
  }
  else if (detect_state == 0 && current_ledState == 1) {  
    digitalWrite(relay, LOW);
    digitalWrite(led, HIGH);
    current_ledState = 0;
    Serial.println("Relay OFF 1");
  }
  else {
    Serial.println("STAY AS IT IS");
  }

  Serial.println("-------------------------");



}

I hope I haven’t written it too confusing. Thanks

  if (button_state == 0)

Don't you think that condition should be checking current_ledState? After all, the other if statements do.

But, after you fix that, you will probably find it still does not work. Have a look at some of the basic example sketches. There is one called "debounce" which does the things your sketch needs to do.