3 Devices Connected Through Bridge / Light Switches

Hello everyone,

I am doing this project for my room. I have 3 lights in different positions and I made 3 different devices in order to control these lights from a physical button as well as a through the blynk app. So far I have been able to make this work. The devices talk to each other through bridge and they work great. I only have one small issue. I have one device with 4 physical buttons, these buttons are one per light and the forth is to turn them all on or off at the same time. The issue i am encountering with this is that when I turn them all on or off, if i want to turn one of the lights on or off after that, I need to press of the physical button twise in order for it to turn on and/or off. I would like if anyone is able to help me figure how I am able to just have it work were only one press of the button is needed instead of two.

The way the devices are working are
Module 1 has the 4 physical buttons to control module 2 and 3
Module 2 has a 2 channel relay, which control 2 lights, no physical button on this one.
Module 3 has one relay to control one light as well as one physical button which only control the light attached to this module.

Here is the code for module 1

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <WiFiUdp.h> //OTA NEEDED
#include <ArduinoOTA.h> //OTA NEEDED

char auth[] = "Module 1 Auth"; //blynk auth token for Main device
char auth2[] = "Module 2 Auth"; //Auth Token for Module #2
char auth3[] = "Module 3 Auth"; //Auth Token for Module #3

// Your WiFi credentials.
char ssid[] = "xxxx"; //Wifi Name
char pass[] = "xxxx"; //Wifi Password // Set password to "" for open networks.

//Bridge Widget on virtual pins
WidgetBridge bridge2(V6); // Module #2
WidgetBridge bridge3(V7); // Module #3

void lightOn(int VPIN);
void lightOff(int VPIN);

boolean LampState1 = 0;
boolean LampState2 = 0;
boolean LampState3 = 0;
boolean LampState4 = 0;

boolean SwitchReset1 = true;
boolean SwitchReset2 = true;
boolean SwitchReset3 = true;
boolean SwitchReset4 = true;

const int Switch1 = D1; // Physical Push Buttons
const int Switch2 = D2;
const int Switch3 = D3;
const int Switch4 = D4;

SimpleTimer timer;

WidgetLED VLED1(V12);  // Two LEDs in the App for relay status from modulo2
WidgetLED VLED2(V13);  //

void setup()      
{
  Serial.begin(115200);
  pinMode(Switch1, INPUT_PULLUP);
  pinMode(Switch2, INPUT_PULLUP);
  pinMode(Switch3, INPUT_PULLUP);
  pinMode(Switch4, INPUT_PULLUP);
  delay(10);

  // OTA CODE NEEDED //
  ArduinoOTA.setHostname("UG Room - Door Buttons"); //Device Name
  ArduinoOTA.setPassword((const char *)"xxxx"); // Device Password for OTA Upgrades
  ArduinoOTA.begin(); 
  // OTA CODE NEEDED ENDS //
    
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(100, ButtonCheck);
}

BLYNK_CONNECTED() {
  bridge2.setAuthToken(auth2); // Connect via bridge to other devices
  bridge3.setAuthToken(auth3);
}

void loop()
{
  ArduinoOTA.handle(); //OTA NEEDED
  Blynk.run();
  timer.run();
}
void ButtonCheck() {
  boolean SwitchState = (digitalRead(Switch1));
  if (!SwitchState && SwitchReset1 == true) {
    if (!LampState1) {
      bridge2.virtualWrite(V2, HIGH);
    LampState1=true;
    } else {
      bridge2.virtualWrite(V2, LOW);
    LampState1=false;
    }
    SwitchReset1 = false;
  delay(50);
  }
  else if (SwitchState) {
    SwitchReset1 = true;
  }

  SwitchState = (digitalRead(Switch2));
  if (!SwitchState && SwitchReset2 == true) {
    if (!LampState2) {
      bridge2.virtualWrite(V3, HIGH);
    LampState2=true;
    } else {
      bridge2.virtualWrite(V3, LOW);
    LampState2=false;
    }
    SwitchReset2 = false;
  delay(50);
  }
  else if (SwitchState) {
    SwitchReset2 = true;
  }

  SwitchState = (digitalRead(Switch3));
  if (!SwitchState && SwitchReset3 == true) {
    if (!LampState3) {
      bridge3.virtualWrite(V3, HIGH);
    LampState3=true;
    } else {
      bridge3.virtualWrite(V3, LOW);
    LampState3=false;
    }
    SwitchReset3 = false;
  delay(50);
  }
  else if (SwitchState) {
    SwitchReset3 = true;
  }


  SwitchState = (digitalRead(Switch4));
  if (!SwitchState && SwitchReset4 == true) {
    if (!LampState4) {
    bridge2.virtualWrite(V2, HIGH);
    bridge2.virtualWrite(V3, HIGH);
    bridge3.virtualWrite(V3, HIGH);
      LampState4=true;
    } else {
    bridge2.virtualWrite(V2, LOW);
    bridge2.virtualWrite(V3, LOW);
    bridge3.virtualWrite(V3, LOW);
      LampState4=false;
    }
    SwitchReset4 = false;
  delay(50);
  }
  else if (SwitchState) {
    SwitchReset4 = true;
  }

}  

void lightOn(int VPIN) {
    Blynk.virtualWrite(VPIN, HIGH);
}
void lightOff(int VPIN) {
    Blynk.virtualWrite(VPIN, LOW); 
}

BLYNK_WRITE(V1) {  // Status returned from modulo2 (relay1)
  int SwitchStatus = param.asInt();
    if (SwitchStatus == 2) {
  VLED1.on();
  }
  else {
  VLED1.off();
  }
}

BLYNK_WRITE(V2) {  // Status returned from modulo2 (relay2)
  int SwitchStatus = param.asInt();
    if (SwitchStatus == 2) {
  VLED2.on();
  }
  else {
  VLED2.off();
  }
}

BLYNK_WRITE(V3) {  //If you prefer use a virtual button in V3 for button # 4 
  int SwitchStatus = param.asInt();
    if (SwitchStatus == 2) {
    bridge2.virtualWrite(V2, HIGH);
    bridge2.virtualWrite(V3, HIGH);
    bridge3.virtualWrite(V3, HIGH);
  }
  else {
    bridge2.virtualWrite(V2, LOW);
    bridge2.virtualWrite(V3, LOW);
    bridge3.virtualWrite(V3, LOW);
  }
}

Here is Module #2

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <WiFiUdp.h> //OTA NEEDED
#include <ArduinoOTA.h> //OTA NEEDED

#define VPIN1 V2
#define VPIN2 V3

char auth[] = "xxxx"; //blynk auth token for modulo2

// Your WiFi credentials.
char ssid[] = "xxxx"; //Wifi Name
char pass[] = "xxxx"; //Wifi Password // Set password to "" for open networks.

void lightOn(int VPIN);
void lightOff(int VPIN);

boolean LampState1 = 0;
boolean LampState2 = 0;

const int RelayPin1 = D2; 
const int RelayPin2 = D3; 

SimpleTimer timer;
WidgetLED VLED1(V12);  // Two LEDs in the App
WidgetLED VLED2(V13);  //

void setup()      
{
  Serial.begin(115200);
  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  
  digitalWrite(RelayPin1, LOW);
  digitalWrite(RelayPin2, LOW);

  delay(10);

  // OTA CODE NEEDED //
  ArduinoOTA.setHostname("UG Room - Door & Bed Light Relays"); //Device Name
  ArduinoOTA.setPassword((const char *)"xxxx"); // Device Password for OTA Upgrades
  ArduinoOTA.begin(); 
  // OTA CODE NEEDED ENDS //
    
  Blynk.begin(auth, ssid, pass);

}

void loop()
{
  ArduinoOTA.handle(); //OTA NEEDED
  Blynk.run();
  timer.run();
}

void ToggleRelay1() {
  LampState1 = !LampState1;
  if (LampState1) {
       lightOn(VPIN1);
  }
  else lightOff(VPIN1);
}
void ToggleRelay2() {
  LampState2 = !LampState2;
  if (LampState2) {
       lightOn(VPIN2);
  }
  else lightOff(VPIN2);
}
void lightOn(int VPIN) {
    if (VPIN==VPIN1) {
    digitalWrite(RelayPin1, HIGH);
    LampState1 = 1;
    Blynk.virtualWrite(VPIN1, HIGH); 
    VLED1.on();
  } else {
    digitalWrite(RelayPin2, HIGH);
    LampState2 = 1;
    Blynk.virtualWrite(VPIN2, HIGH); 
    VLED2.on();
  }
}
void lightOff(int VPIN) {
    if (VPIN==VPIN1) {
    digitalWrite(RelayPin1, LOW);
    LampState1 = 0;
    Blynk.virtualWrite(VPIN1, LOW); 
    VLED1.off();
  } else {
    digitalWrite(RelayPin2, LOW);
    LampState2 = 0;
    Blynk.virtualWrite(VPIN2, LOW); 
    VLED2.off();
  }
}
BLYNK_WRITE(VPIN1) {
  int SwitchStatus = param.asInt();
  if (SwitchStatus == 2){
    ToggleRelay1();
  }
  else if (SwitchStatus){
    lightOn(VPIN1);
  }
  else lightOff(VPIN1);
}

BLYNK_WRITE(VPIN2) {
  int SwitchStatus = param.asInt();
  if (SwitchStatus == 2){
    ToggleRelay2();
  }
  else if (SwitchStatus){
    lightOn(VPIN2);
  }
  else lightOff(VPIN2);
}

and Module #3

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <WiFiUdp.h> //OTA NEEDED
#include <ArduinoOTA.h> //OTA NEEDED
// #define BLYNK_PRINT Serial // Defines the object that is used for printing
// #define BLYNK_DEBUG        // Optional, this enables more detailed prints

#define VPIN V3

char auth[] = "xxxx"; //blynk auth token

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxx";
char pass[] = "xxxx";

void lightOn();
void lightOff();

boolean LampState = 0;
boolean SwitchReset = true;

const int TacSwitch = D2; 
const int RelayPin = D1; 

SimpleTimer timer;
WidgetLED VLED(V13);

void setup()      
{
  Serial.begin(115200);
  pinMode(RelayPin, OUTPUT);
  digitalWrite(RelayPin, HIGH);
  pinMode(TacSwitch, INPUT_PULLUP);
  delay(10);
  Blynk.begin(auth, ssid, pass);
  
    // OTA CODE NEEDED //
  ArduinoOTA.setHostname("UG Room - Desk Light"); //Device Name
  ArduinoOTA.setPassword((const char *)"xxxx"); // Device Password for OTA Upgrades
  ArduinoOTA.begin(); 
  // OTA CODE NEEDED ENDS //
  
  timer.setInterval(100, ButtonCheck);
}
void loop()
{
  Blynk.run();
    ArduinoOTA.handle(); //OTA NEEDED
  timer.run();
}
void ButtonCheck() {
  boolean SwitchState = (digitalRead(TacSwitch));
  if (!SwitchState && SwitchReset == true) {
    if (LampState) {
      lightOff();
    } else {
      lightOn();
    }
    SwitchReset = false;
    delay(50);
  }
  else if (SwitchState) {
    SwitchReset = true;
  }
}
void ToggleRelay() {
  LampState = !LampState;
  if (LampState) {
       lightOn();
  }
  else lightOff();
}
void lightOn() {
    digitalWrite(RelayPin, LOW);
    LampState = 1;
    Blynk.virtualWrite(VPIN, HIGH); 
    VLED.on();
}
void lightOff() {
    digitalWrite(RelayPin, HIGH);
    LampState = 0;
    Blynk.virtualWrite(VPIN, LOW); 
    VLED.off();
}
BLYNK_WRITE(VPIN) {
  int SwitchStatus = param.asInt();
    if (SwitchStatus == 2){
    ToggleRelay();
  }
  else if (SwitchStatus){
    lightOn();
  }
  else lightOff();
}

Thank you everyone!

does anyone has any input?

Looks like a logic issue with the SwitchReset group of variables to me.
Their state is initially undefined within void loop() and is only set to true after the first press of the button, so the first time the button is pressed the if statement conditions aren’t met, and the SwitchReset is then set to true in the else statement. Second time around and the if condition is met, so the light turns on.

Obviously I can’t test it to see if this is the cause as I don’t have your hardware available.

Pete.