Nodemcu Using Blynk, Relays going back to the blynk app state after wifi connection to blynk server restored causing switches error

Okay, so here is my issue using nodemcu esp8266 with blynk.

i have installed a 4ch relay and 4 physical buttons to my nodemcu running blynk.

the problem i am facing is, lets say everything is working fine controlling my relays using physical buttons and blynk app and all 4 relays are turned on. But suddenly loose connection to the internet and nodemcu is still connected to the wifi router but not to the internet hence not connected to the blynk server.
i can still use the system with the physical buttons without any problem.
the problem comes when my internet connection is restored and nodemcu connects to the internet, rather than the relays staying in the state it should be when the internet was down, all 4 relays turn on (previous state in blynk app) as soon as blynk server connection is restored.

what i want is the relays to stay as it is rather than going back to the previous state.
( blynk app should update the buttons status from nodemcu rather than it updating the nodemcu button status when connection is restored )

here is my code.

//#define BLYNK_DEBUG
#define BLYNK_TIMEOUT_MS  750  // must be BEFORE BlynkSimpleEsp8266.h doesn't work !!!
#define BLYNK_HEARTBEAT   17   // must be BEFORE BlynkSimpleEsp8266.h works OK as 17s
#define BLYNK_PRINT Serial
#include <ESP8266WebServer.h>
#include <WiFiManager.h>      //https://github.com/tzapu/WiFiManager
#include <DNSServer.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxx";
char ssid[] = "xxxxxx"; // username or ssid of your WI-FI
char pass[] = "xxxxxx"; // password of your Wi-Fi
char server[]          = "blynk-cloud.com";
unsigned int port      = 8442;

// Your WiFi credentials.
// Set password to "" for open networks.

// Set your LED and physical button pins here
const int ledPin1 = 0;
const int ledPin2 = 13;
const int ledPin3 = 1;
const int ledPin4 = 2;
const int btnPin1 = 5;
const int btnPin2 = 4;
const int btnPin3 = 12;
const int btnPin4 = 14;

void checkPhysicalButton();

int led1State = LOW;
int btn1State = HIGH;

int led2State = LOW;
int btn2State = HIGH;

int led3State = LOW;
int btn3State = HIGH;

int led4State = LOW;
int btn4State = HIGH;

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V12);
  Blynk.syncVirtual(V13);
  Blynk.syncVirtual(V14);
  Blynk.syncVirtual(V15);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V12, led1State);
  //Blynk.virtualWrite(V13, led2State);
  //Blynk.virtualWrite(V14, led3State);
  //Blynk.virtualWrite(V15, led4State);

}

// When App button is pushed - switch the state
BLYNK_WRITE(V12) {
  led1State = param.asInt();
  digitalWrite(ledPin1, led1State);
}
  
 BLYNK_WRITE(V13) {
  led2State = param.asInt();
  digitalWrite(ledPin2, led2State);
 }
BLYNK_WRITE(V14) {
  led3State = param.asInt();
  digitalWrite(ledPin3, led3State);
}
BLYNK_WRITE(V15) {
  led4State = param.asInt();
  digitalWrite(ledPin4, led4State);
}

void checkPhysicalButton()
{
  if (digitalRead(btnPin1) == LOW) {
    // btn1State is used to avoid sequential toggles
    if (btn1State != LOW) {

      // Toggle LED state
      led1State = !led1State;
      digitalWrite(ledPin1, led1State);

      // Update Button Widget
      Blynk.virtualWrite(V12, led1State);
    }
    btn1State = LOW;
  } else {
    btn1State = HIGH;
  }

  if (digitalRead(btnPin2) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btn2State != LOW) {

      // Toggle LED state
      led2State = !led2State;
      digitalWrite(ledPin2, led2State);

      // Update Button Widget
      Blynk.virtualWrite(V13, led2State);
    }
    btn2State = LOW;
  } else {
    btn2State = HIGH;
  }

  if (digitalRead(btnPin3) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btn3State != LOW) {

      // Toggle LED state
      led3State = !led3State;
      digitalWrite(ledPin3, led3State);

      // Update Button Widget
      Blynk.virtualWrite(V14, led3State);
    }
    btn3State = LOW;
  } else {
    btn3State = HIGH;
  }

  if (digitalRead(btnPin4) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btn4State != LOW) {

      // Toggle LED state
      led4State = !led4State;
      digitalWrite(ledPin4, led4State);

      // Update Button Widget
      Blynk.virtualWrite(V15, led4State);
    }
    btn4State = LOW;
  } else {
    btn4State = HIGH;
  }
}

void setup()
{
  // Debug console
  Serial.begin(115200);
  Serial.println();

  WiFiManager wifiManager;
  wifiManager.autoConnect("MCU1", "1397");

  // line below is blocking code, consider regular WiFi connection with timeout if you have router problems
  Blynk.connectWiFi(ssid, pass); // used with Blynk.connect() in place of Blynk.begin(auth, ssid, pass, server, port);

  // line below needs to be BEFORE Blynk.connect()
  timer.setInterval(11000L, CheckConnection); // check if still connected every 11s  
  
  Blynk.config(auth, server, port);
  Blynk.connect();    

  pinMode(ledPin1, OUTPUT);
  pinMode(btnPin1, INPUT_PULLUP);
  digitalWrite(ledPin1, led1State);
  

  pinMode(ledPin2, OUTPUT);
  pinMode(btnPin2, INPUT_PULLUP);
  digitalWrite(ledPin2, led2State);
  

  pinMode(ledPin3, OUTPUT);
  pinMode(btnPin3, INPUT_PULLUP);
  digitalWrite(ledPin3, led3State);
  

  pinMode(ledPin4, OUTPUT);
  pinMode(btnPin4, INPUT_PULLUP);
  digitalWrite(ledPin4, led4State);

  // Setup a function to be called every 100 ms
  timer.setInterval(500L, checkPhysicalButton);
}

void CheckConnection(){    // check every 11s if connected to Blynk server
  if(!Blynk.connected()){
    Serial.println("Not connected to Blynk server"); 
    Blynk.connect();  // try to connect to server with default timeout
  }
  else{
    Serial.println("Connected to Blynk server");     
  }
}

void loop()
{
    Blynk.run();
  timer.run();
}

Any Help Would be Appreciated…!

The answer is in this piece of code

BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V12);
  Blynk.syncVirtual(V13);
  Blynk.syncVirtual(V14);
  Blynk.syncVirtual(V15);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V12, led1State);
  //Blynk.virtualWrite(V13, led2State);
  //Blynk.virtualWrite(V14, led3State);
  //Blynk.virtualWrite(V15, led4State);

}

If you read the comments, you will see that one sets the devices to the server state, that is the state of the app buttons, when the device connects to BLYNK. The other (the ones commented out) will override the sever state, that it make the app buttons match the current device state, when the device connects to BLYNK.

You probably are looking for the second option, and thus this section of code should look like this

BLYNK_CONNECTED() {
  // Request the latest state from the server
  //Blynk.syncVirtual(V12);
  //Blynk.syncVirtual(V13);
  //Blynk.syncVirtual(V14);
  //Blynk.syncVirtual(V15);

  // Alternatively, you could override server state using:
  Blynk.virtualWrite(V12, led1State);
  Blynk.virtualWrite(V13, led2State);
  Blynk.virtualWrite(V14, led3State);
  Blynk.virtualWrite(V15, led4State);

}
2 Likes

Wow… U are awesome… Thank you soo much… Will change the same in code and let u know how it went… Damn That was right there staring at me…
Thanks again… Really appreciate it…!

1 Like

okay…i tried the solution given by you…and that problem is super solved regarding the blynk server…now a new problem came up.

as soon as i turn off my Nodemcu ( complete power off including relays and all ). all relays automatically turn ON when power is restored to nodemcu…even though the relays were never turned on before power cut or are not even ON in app…!

here is the changes i made…

//#define BLYNK_DEBUG
#define BLYNK_TIMEOUT_MS  750  // must be BEFORE BlynkSimpleEsp8266.h doesn't work !!!
#define BLYNK_HEARTBEAT   17   // must be BEFORE BlynkSimpleEsp8266.h works OK as 17s
#define BLYNK_PRINT Serial
#include <ESP8266WebServer.h>
#include <WiFiManager.h>      //https://github.com/tzapu/WiFiManager
#include <DNSServer.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxx";
char ssid[] = "Net"; // username or ssid of your WI-FI
char pass[] = "1234"; // password of your Wi-Fi
char server[]          = "blynk-cloud.com";
unsigned int port      = 8442;

// Your WiFi credentials.
// Set password to "" for open networks.

// Set your LED and physical button pins here
const int ledPin1 = 0;
const int ledPin2 = 13;
const int ledPin3 = 1;
const int ledPin4 = 2;
const int btnPin1 = 5;
const int btnPin2 = 4;
const int btnPin3 = 12;
const int btnPin4 = 14;

void checkPhysicalButton();

int led1State = LOW;
int btn1State = HIGH;

int led2State = LOW;
int btn2State = HIGH;

int led3State = LOW;
int btn3State = HIGH;

int led4State = LOW;
int btn4State = HIGH;

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  //Blynk.syncVirtual(V12);
  //Blynk.syncVirtual(V13);
  //Blynk.syncVirtual(V14);
  //Blynk.syncVirtual(V15);

  // Alternatively, you could override server state using:
  Blynk.virtualWrite(V12, led1State);
  Blynk.virtualWrite(V13, led2State);
  Blynk.virtualWrite(V14, led3State);
  Blynk.virtualWrite(V15, led4State);

}

// When App button is pushed - switch the state
BLYNK_WRITE(V12) {
  led1State = param.asInt();
  digitalWrite(ledPin1, led1State);
}
  
 BLYNK_WRITE(V13) {
  led2State = param.asInt();
  digitalWrite(ledPin2, led2State);
 }
BLYNK_WRITE(V14) {
  led3State = param.asInt();
  digitalWrite(ledPin3, led3State);
}
BLYNK_WRITE(V15) {
  led4State = param.asInt();
  digitalWrite(ledPin4, led4State);
}

void checkPhysicalButton()
{
  if (digitalRead(btnPin1) == LOW) {
    // btn1State is used to avoid sequential toggles
    if (btn1State != LOW) {

      // Toggle LED state
      led1State = !led1State;
      digitalWrite(ledPin1, led1State);

      // Update Button Widget
      Blynk.virtualWrite(V12, led1State);
    }
    btn1State = LOW;
  } else {
    btn1State = HIGH;
  }

  if (digitalRead(btnPin2) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btn2State != LOW) {

      // Toggle LED state
      led2State = !led2State;
      digitalWrite(ledPin2, led2State);

      // Update Button Widget
      Blynk.virtualWrite(V13, led2State);
    }
    btn2State = LOW;
  } else {
    btn2State = HIGH;
  }

  if (digitalRead(btnPin3) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btn3State != LOW) {

      // Toggle LED state
      led3State = !led3State;
      digitalWrite(ledPin3, led3State);

      // Update Button Widget
      Blynk.virtualWrite(V14, led3State);
    }
    btn3State = LOW;
  } else {
    btn3State = HIGH;
  }

  if (digitalRead(btnPin4) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btn4State != LOW) {

      // Toggle LED state
      led4State = !led4State;
      digitalWrite(ledPin4, led4State);

      // Update Button Widget
      Blynk.virtualWrite(V15, led4State);
    }
    btn4State = LOW;
  } else {
    btn4State = HIGH;
  }
}

void setup()
{
  // Debug console
  Serial.begin(115200);
  Serial.println();

  WiFiManager wifiManager;
  wifiManager.autoConnect("MCU1", "1397");

  // line below is blocking code, consider regular WiFi connection with timeout if you have router problems
  Blynk.connectWiFi(ssid, pass); // used with Blynk.connect() in place of Blynk.begin(auth, ssid, pass, server, port);

  // line below needs to be BEFORE Blynk.connect()
  timer.setInterval(11000L, CheckConnection); // check if still connected every 11s  
  
  Blynk.config(auth, server, port);
  Blynk.connect();    

  pinMode(ledPin1, OUTPUT);
  pinMode(btnPin1, INPUT_PULLUP);
  digitalWrite(ledPin1, led1State);
  

  pinMode(ledPin2, OUTPUT);
  pinMode(btnPin2, INPUT_PULLUP);
  digitalWrite(ledPin2, led2State);
  

  pinMode(ledPin3, OUTPUT);
  pinMode(btnPin3, INPUT_PULLUP);
  digitalWrite(ledPin3, led3State);
  

  pinMode(ledPin4, OUTPUT);
  pinMode(btnPin4, INPUT_PULLUP);
  digitalWrite(ledPin4, led4State);

  // Setup a function to be called every 100 ms
  timer.setInterval(500L, checkPhysicalButton);
}

void CheckConnection(){    // check every 11s if connected to Blynk server
  if(!Blynk.connected()){
    Serial.println("Not connected to Blynk server"); 
    Blynk.connect();  // try to connect to server with default timeout
  }
  else{
    Serial.println("Connected to Blynk server");     
  }
}

void loop()
{
    Blynk.run();
  timer.run();
}

Thanks…!

That’s because it’s what you’ve told the code to do!
led1State to led4State are all set to LOW by your code at startup. Presumably you’re using Active LOW relays, that energise with a LOW signal, so all the relays are being energised when Blynk connects (at startup).

Pete.

1 Like

okay…got it…thanks for clearing that out…i did think that was the issue, but wasn’t sure…(as i have clearly defined the relays and button state on startup…! silly me)
Kindly help me to know if there is a way to store the previous switch state before power off in the esp/nodemcu…so that when power is connected it will go back to the last known state for the relays (ON/OFF ) rather than turning on…?
or any other thing i can do to acheive the desired result ( without connecting to blynk servers ).

Thanks :slight_smile:

To restore the previous settings, you have to store them somewhere.
There are two options:

  1. on the Blynk server, but this obviously requires an internet connection to be available when the NodeMCU starts up.

  2. in the non-volatile memory of your MCU. In the case of a NodeMCU this will be in SPIFFS memory. On something like an Arduino this would be in NVRAM. This non-volatile memory has a limited read-write life, so care has to be taken with the way that you handle the code logic.

However, there’s a potential issue with restoring the previous state. If you have a power cut while you’re at home, then leave home before the power is restored, the devices (lights in this case) will return to their previous state. You won’t be able to update the SPIFFS in the NodeMCU until power is restored, so you can’t override this behaviour. You could use Blynk to turn the lights off when the power comes back on, but that’s not necessary the best approach. If you were controlling something more dangerous than lights then you would certainly want them to ‘fail safe’.

You need to give some thought to the scenarios you’re likely to encounter.

If you want to use SPIFFS then simply google some examples.

Pete.

1 Like

yes…i did go through the community searching for the answer and found an old discussion & the same issue was discussed and solved using blynk server sync…
the reason i want this is cause…of the same scenario as you mentioned but a lil different…if there is a power cut when nobody is home and the power comes back before anybody is home so all lights / relays would turn ON and stay ON till i dont come home and turn it off either physically or have to check app every few hours and turn off that too depending if my wifi is properly working to let the nodemcu sync to blynk servers…( as there is a lott of wifi issue in my whole area…! )
The reason this came up is cause i also have a sonoff Device at home and they behave exactly like remembering the previous state (if OFF before power cut will Stay OFF after power restored and vice a versa even if not connected to the internet / wifi ).
so thought that can be acheived here also (since both use esp).

Thanks.:slight_smile:

Your devices won’t turn on automatically after a power cut, unless you’ve programmed them badly.

I’m not familiar with the standard Sonoff firmware, as I always re-flash them with Blynk firmware as soon as I get them.
However, having a device return to its pre power cut state isn’t always a great idea, for the reasons I stated earlier. My devices are generally programmed in a ‘sale safe’ state, with the exception of a few controllers for devices like CCTV cameras, routers and servers, which default to an On state at startup and require positive action to power them off (to reboot these devices).

Pete.

1 Like

okay so got your point…honestly it would be better if the switches stay OFF after powercycle.
so for that i will have to change the Ledstate in Code to High right…?

int led1State = LOW;
int btn1State = HIGH;

int led2State = LOW;
int btn2State = HIGH;

int led3State = LOW;
int btn3State = HIGH;

int led4State = LOW;
int btn4State = HIGH;

this part i need to change right…?

@swapnilkute2777 Yup!

1 Like

Okay…Did that and its working great now…! Now all Relays are OFF during Boot Up State.

Thank You all for helping me out…!

1 Like