Blynk_Write stops working after several hours of running

Hello All,

I have been trying to create a project to control my Water pump based on sensor inputs and user inputs.

Hardware used is ESP32
Blynk Library version: 1.3.2

Issue:
When I run the hardware for several hours, the ESP32 stops getting commands from the blynk server (Like to turn on the motor or to turn on the lights) whereas the ESP32 keeps sending the sensed value to the server and also its uptime counter is seen to be updating correctly on the blynk dashboard.

I tried to add reconnection code but no luck.

Following is the code that is running on the ESP.

Any help would be greatly appreciated

//#define BLYNK_TEMPLATE_ID           "TMPxxxxxx"
//#define BLYNK_TEMPLATE_NAME         "Device"

/*************************************************************

Water Control App Light with L&T Controller v1.0

*************************************************************/

#define BLYNK_TEMPLATE_ID "TMPxxxxxx"
#define BLYNK_TEMPLATE_NAME "Device"

/*Uncomment the next line to turn ON Debug serial messages*/
//#define DebugON

#define MotorControlRelay   15
#define LnTControllerRelay  5
#define LightControlRelay   19

/* Comment this out to disable prints and save space */
#ifdef DebugON
#define BLYNK_PRINT Serial
#endif

#define CLEAR           0x00
#define UPDATED     0x01
#define ON                  0x01
#define OFF                0x00
#define RESET            0x02
#define RELAY_ON   0x00
#define RELAY_OFF 0x01

#define LNT_CONTROLLER_ON  0x00
#define LNT_CONTROLLER_OFF 0x02

#define MOTOR_MODE_AUTO 0x02
#define MOTOR_MODE_OFF  0x01
#define MOTOR_MODE_ON   0x00


#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <HardwareSerial.h>

/*A02YYUW Waterproof Ultrasonic Distance Sensor (3~450cm, UART, IP67)*/
HardwareSerial SerialPort(2); // use UART2

#define TankHeight   212 // in cm
#define TankWidth    182 //in cm
#define TankLength   335 //in cm
#define SensorHeight 20 // Dead zone of sensor in cm

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


int   prevDistance;
float UG_WaterLevel;
float UG_WaterLevel_Percentage;
int UG_WaterInLitre;

int LightSwitchState_u8 = 0x00;
int LnTSwitchState_u8 = 0x00;
int MotorSwitchState_u8 = 0x00;

int InvaliCount = 0x00;

byte isUpdate_LightSwitch = 0x00;
byte isUpdate_LnTSwitch = 0x00;
byte isUpdate_MotorSwitch = 0x00;

int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter

BlynkTimer timer;

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

  SerialPort.begin(9600, SERIAL_8N1, 16, 17);

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);

  Serial.println("Water Control App Light with L&T Controller v1.0");

  timer.setInterval(1000L, CyclicFunc_1);

  timer.setInterval(250L, CyclicFunc_2);

  timer.setInterval(1000, CyclicFunc_3);
  
  pinMode(LightControlRelay, OUTPUT);

  pinMode(LnTControllerRelay, OUTPUT);

  pinMode(MotorControlRelay, OUTPUT);

  digitalWrite(LightControlRelay, HIGH);

  digitalWrite(LnTControllerRelay, HIGH);

  digitalWrite(MotorControlRelay, HIGH);

  Serial.println("Setup Complete");

}

// This function is called every time the device is connected to the Blynk.Cloud
BLYNK_CONNECTED()
{
  Serial.println("Device D0 connected to Server");

  Blynk.syncVirtual(0);

  Blynk.syncVirtual(1);

  Blynk.syncVirtual(10);
}

/*This function will be called every 1 second cyclically*/
void CyclicFunc_1()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V18, millis() / 1000);
}

/********************************************************************************************************************************/

void CyclicFunc_2()
{
  /*Check if light switch state has been updated*/
  if(UPDATED == isUpdate_LightSwitch)
  {
    /*Check if Switch was turned ON*/
    if(ON == LightSwitchState_u8)
    {
      #ifdef DebugON
      Serial.println("Light ON request Received");
      #endif

      digitalWrite(LightControlRelay, RELAY_ON);
    }
    else
    {
      #ifdef DebugON
      Serial.println("Light OFF request Received");
      #endif

      digitalWrite(LightControlRelay, RELAY_OFF);
    }
    isUpdate_LightSwitch = CLEAR;
  }

/********************************************************************************************************************************/

  /*Check if L&T Controller switch state has been updated*/
  if(UPDATED == isUpdate_LnTSwitch)
  {
    /*L&T controller is connected to NC terminal of relay, So keeping the relay off means Controller is ON*/
    /*0x00 - Keep relay OFF means L&T controller is ON
      0x01 - Safe state do nothing
      0x02 - Reset the L&T Controller OR turn theL&T Controller OFF by turning ON the relay*/
    if(LNT_CONTROLLER_ON == LnTSwitchState_u8)
    {
      #ifdef DebugON
      /*Make Relay OFF as L&T Controller is connected to NC*/
      Serial.println("L&T Controller ON request Received - Relay State OFF");
      #endif

      digitalWrite(LnTControllerRelay, RELAY_OFF);

    }
    else if (LNT_CONTROLLER_OFF == LnTSwitchState_u8)
    {
      #ifdef DebugON
      /*Make Relay ON so L&T controller turns OFF*/
      Serial.println("L&T Controller OFF request Received - Relay State ON");
      #endif

      digitalWrite(LnTControllerRelay, RELAY_ON);

    }
    else
    {
      /*Do Nothing*/
    }

    isUpdate_LnTSwitch = CLEAR;
  }

  /*Check if Motor Control switch state has been updated*/
  if(UPDATED == isUpdate_MotorSwitch)
  {
      if(MOTOR_MODE_OFF == MotorSwitchState_u8)
      {
          #ifdef DebugON
          Serial.println("Motor OFF request Received");
          #endif

          digitalWrite(MotorControlRelay, RELAY_OFF);

          Blynk.virtualWrite(V3, OFF);
      }
      else if(MOTOR_MODE_ON == MotorSwitchState_u8)
      {
          #ifdef DebugON
          Serial.println("Motor ON request Received");
          #endif

          digitalWrite(MotorControlRelay, RELAY_ON);

          Blynk.virtualWrite(V3, ON);
      }
      else
      {
        /*Do Nothing*/
      }

      isUpdate_MotorSwitch = CLEAR;
  }

}

/********************************************************************************************************************************/


/*This function will be called every 1 second cyclically*/
void CyclicFunc_3()
{
  int distance; 
  byte startByte, h_data, l_data, sum = 0;
  byte buf[3];
  int cnt=0;

  while((SerialPort.read()==0xff) && (cnt < 50))
  {
    for(int i=0;i<3;i++)
    {
      buf[i]=SerialPort.read();
    }
    cnt++;
    startByte = 0xFF; //(byte)SerialPort.read();
  }

  #ifdef DebugON
  Serial.println(cnt);
  #endif

  if(startByte == 0xFF)
  {
    h_data = buf[0];
    l_data = buf[1];
    sum =    buf[2];

    distance = (h_data<<8) + l_data;

    /*Converting Distance to cm*/
    distance = distance/10;

    /*Check if checksum matches*/
    if(((startByte + h_data + l_data)&0xFF) != sum)
    {
      /*Checksum mismatch*/
      #ifdef DebugON
      Serial.println("Invalid result");
      Serial.println(startByte);
      Serial.println(h_data);
      Serial.println(l_data);
      Serial.println(sum);
      #endif      

      InvaliCount++;

      #ifdef DebugON
      Serial.print("Invalid count: ");
      Serial.println(InvaliCount); 
      #endif 

      //if (InvaliCount == 30)
      //{
      //  InvaliCount = 0x00;
      //}
    }
    else
    {
      //InvaliCount = 0x00;
      if(prevDistance != distance) 
      {
        prevDistance = distance;

        //Serial.print("Distance: ");
        //Serial.print(distance);
        //Serial.println(" mm");

        #ifdef DebugON
        Serial.print("Distance: ");
        Serial.print(distance);
        Serial.println(" cm");
        #endif 

        /*Calculate water height from the sensed hieght
        Sensed height is the empty part of the tank,
        so it is substracted from total height of the tank, 
        and the sensor dead zone or the height of the sensor from actual full tank
        is also substracted. Dead zone of A02YYUW is 3cm so sensor is places atleast 3cm above sensing height */

        UG_WaterLevel = TankHeight - (distance - SensorHeight);

        /* Calculate total water quantity % */
        UG_WaterLevel_Percentage = ((UG_WaterLevel/TankHeight)*100);

        /*Volume of a cube = L*W*H*/
        UG_WaterInLitre = TankLength * TankWidth * UG_WaterLevel;

        /*Convert cm3 to liter OR mm3 to liter 
        (multiply the given value of cubic centimeters cm3 by a factor of 0.001 OR divide by 1000)
        (multiply the given value of cubic Millimeters mm3 by a factor of 0.000001)*/
        UG_WaterInLitre = UG_WaterInLitre/1000;

        #ifdef DebugON
        Serial.println("Change detected");
        #endif

        Blynk.virtualWrite(V5, UG_WaterLevel_Percentage);

        Blynk.virtualWrite(V15, UG_WaterInLitre);

        #ifdef DebugON
        Serial.print("UG_WaterLevel_Percentage: ");
        Serial.println(UG_WaterLevel_Percentage);

        Serial.print("UG_WaterLevel: ");
        Serial.println(UG_WaterLevel);

        Serial.print("UG_WaterInLitre: ");
        Serial.println(UG_WaterInLitre);
        #endif

      }
      else
      {
        /*No Change in water level*/
      }
    }
  }
  else
  {
    #ifdef DebugON
    Serial.println("Missed");
    #endif
  }
}

/********************************************************************************************************************************/

void resetMCU()
{
  ESP.restart();
  for (;;) {}
}

/********************************************************************************************************************************/

BLYNK_WRITE(InternalPinDBG) 
{
  if (String(param.asStr()) == "reboot") {
    Serial.println("Rebooting...");

    // TODO: Perform any neccessary preparation here,
    // i.e. turn off peripherals, write state to EEPROM, etc.

    // NOTE: You may need to defer a reboot,
    // if device is in process of some critical operation.

    resetMCU();
  }
}

/*This Function will be called when switch state is updated for Light Control*/
BLYNK_WRITE(V10)
{
  LightSwitchState_u8 = param.asInt();

  isUpdate_LightSwitch = UPDATED;
}

/*This Function will be called when switch state is updated for L&T Controller*/
BLYNK_WRITE(V1)
{
  LnTSwitchState_u8 = param.asInt();

  isUpdate_LnTSwitch = UPDATED;
}

/*This Function will be called when switch state is updated for L&T Controller*/
BLYNK_WRITE(V0)
{
  MotorSwitchState_u8 = param.asInt();

  isUpdate_MotorSwitch = UPDATED;
}

void loop() 
{
  timer.run();

  if (Blynk.connected())
  {
    Blynk.run();
  }
  else if (ReCnctFlag == 0)
  {
    ReCnctFlag = 1;  // Set reconnection Flag
    Serial.println("Starting reconnection timer in 15 seconds...");
    timer.setTimeout(15000L, []() {  // Lambda Reconnection Timer Function
    ReCnctFlag = 0;  // Reset reconnection Flag
    ReCnctCount++;  // Increment reconnection Counter
    Serial.print("Attempting reconnection #");
    Serial.println(ReCnctCount);
    Blynk.connect();  // Try to reconnect to the server
    });  // END Timer Functio
  }
  
}

Wow! That’s a lesson in how to take a simple task and make it ten times more complicated than it needs to be!

Well, first of all the device is still connected if it’s still updating the Blynk server with uptime information. And secondly, this makes no sense when you’re using Blynk,begin() as your connection method…

You should change your void loop to this…

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

I’d start your debugging process by adding a serial print statement into the very start of each of your BLYNK_WRITE(vPin) commands to prove beyond any doubt whether the BLYNK_BEGIN(vPin) command is being called or not.
Also, when you’re doing your debugging of this issue it makes sense to have
#define BLYNK_PRINT Serial enables so that you can see debug messages from the Blynk library.

Pete.

Hello @PeteKnight

Thanks for the quick response.

I have been debugging this issue for couple of days now, so I have tried few things which I would like to share with you.

In the beginning all the debug commands including serial prints were ON, but I thought that too many serial prints might be the root cause of this issue, so I disabled them.

The void loop was exactly the same as you mentioned, but I suspected that multiple disconnections was the root cause so I did some reading on the community and added the reconnect code. Also, I have seen that there are multiple reconnections happening maybe due to loss of internet connectivity.
Still do you want me to remove this code from the void loop?

I have put a serial print in all BLYNK_WRITE(vPin) to check if they are at least being called after this issue appears, but as mentioned this issue comes up after 8 to 10 hours of run, so I am waiting for it to reoccur.

Finally I want to share my today’s observation with you:
After 10 hours of run the ESP32 stopped receiving commands from Blynk server and the uptime was getting updated correctly, but this time I did not reset the ESP32 instead I turned off my Wifi router and then turned it back ON and to my surprise after reconnection the ESP32 started to receive the commands from Blynk server.

This makes me think if this issue is of the code or some kind of connection issue with Blynk server…

Also, the reboot command from Blynck Web app doesn’t work when this issue occurs.

Do you think 250ms timer is maybe over loading the ESP32?

Yes, reconnections will happen whether this code is there or not.

Sounds like an issue with your router or ISP.

TBH, it’s very difficult to work-out exactly what is happening every 250ms, mostly because of the way that you’ve structured your code in the CyclicFunc_2 and the way that you’ve employed all of these nonesense aliases.
From a quick glance it seems that you’re doing a maximum of one Blynk.virtualWrite() in this function, which won’t be an issue.

Pete.

Hello @PeteKnight

I tried to simplify the code.
As suggested I did put serial print commands in Blynk_Write directly and there are printed during normal operation, but when the issue occurs the serial prints do not appear on the serial window, confirming that Blynk_Write is not being called.

all the other functionality of ESP32 are working correctly as mentioned earlier the uptime and sensor values are being sent to Blynk server periodically even when the issue is present

I also tried checking the RSSI value of WIFI and that also seems to be in normal range (-19 to -35 dbm)

Also I have observed that this issue occurs during 1530hrs to 1700hrs and once it occurs we are never able to recovers from it without router or ESP32 reset.

/*************************************************************

Water Control App Light with L&T Controller v1.0

*************************************************************/

#define BLYNK_TEMPLATE_ID           "TMPxxxxxx"
#define BLYNK_TEMPLATE_NAME         "Device"

/*Uncomment the next line to turn ON Debug serial messages*/
#define DebugON

#define MotorControlRelay   15
#define LnTControllerRelay  5
#define LightControlRelay   19

/* Comment this out to disable prints and save space */
//#ifdef DebugON
#define BLYNK_PRINT Serial
//#endif

#define CLEAR     0x00
#define UPDATED   0x01
#define ON        0x01
#define OFF       0x00
#define RESET     0x02
#define RELAY_ON  0x00
#define RELAY_OFF 0x01

#define LNT_CONTROLLER_ON  0x00
#define LNT_CONTROLLER_OFF 0x02

#define MOTOR_MODE_AUTO 0x02
#define MOTOR_MODE_OFF  0x01
#define MOTOR_MODE_ON   0x00


#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <HardwareSerial.h>

/*A02YYUW Waterproof Ultrasonic Distance Sensor (3~450cm, UART, IP67)*/
HardwareSerial SerialPort(2); // use UART2

#define TankHeight   212 // in cm
#define TankWidth    182 //in cm
#define TankLength   335 //in cm
#define SensorHeight 20 // Dead zone of sensor in cm

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

int   prevDistance;
float UG_WaterLevel;
float UG_WaterLevel_Percentage;
int UG_WaterInLitre;

int LightSwitchState_u8 = 0x00;
int LnTSwitchState_u8 = 0x00;
int MotorSwitchState_u8 = 0x00;

int InvaliCount = 0x00;

int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter

int aliveStatus = 0x00;

BlynkTimer timer;

/********************************************************************************************************************************/

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

  SerialPort.begin(9600, SERIAL_8N1, 16, 17);

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass,"blynk.cloud",8080);

  Serial.println("Water Control App Light with L&T Controller v1.0");

  timer.setInterval(1000L, CyclicFunc_1);

  timer.setInterval(1000, CyclicFunc_3);
  
  pinMode(LightControlRelay, OUTPUT);

  pinMode(LnTControllerRelay, OUTPUT);

  pinMode(MotorControlRelay, OUTPUT);

  digitalWrite(LightControlRelay, HIGH);

  digitalWrite(LnTControllerRelay, HIGH);

  digitalWrite(MotorControlRelay, HIGH);

  Serial.println("Setup Complete");
}

/********************************************************************************************************************************/

// This function is called every time the device is connected to the Blynk.Cloud
BLYNK_CONNECTED()
{
  Serial.println("Device D0 connected to Server");

  Blynk.syncVirtual(0);

  Blynk.syncVirtual(1);

  Blynk.syncVirtual(V4);

  Blynk.syncVirtual(10);

  Blynk.virtualWrite(V9, 0);
}
/********************************************************************************************************************************/

/*This function will be called every 1 second cyclically*/
void CyclicFunc_1()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V18, millis() / 1000);

  //Serial.print("WiFi.RSSI");
  //Serial.println(WiFi.RSSI());
  Blynk.virtualWrite(V12, WiFi.RSSI());
  Blynk.virtualWrite(V14, ReCnctCount);

}

/********************************************************************************************************************************/


/*This function will be called every 1 second cyclically*/
void CyclicFunc_3()
{
  int distance; 
  byte startByte, h_data, l_data, sum = 0;
  byte buf[3];
  int cnt=0;

  while((SerialPort.read()==0xff) && (cnt < 50))
  {
    for(int i=0;i<3;i++)
    {
      buf[i]=SerialPort.read();
    }
    cnt++;
    startByte = 0xFF; //(byte)SerialPort.read();
  }

  #ifdef DebugON
  Serial.println(cnt);
  #endif

  if(startByte == 0xFF)
  {
    h_data = buf[0];
    l_data = buf[1];
    sum =    buf[2];

    distance = (h_data<<8) + l_data;

    /*Converting Distance to cm*/
    distance = distance/10;

    /*Check if checksum matches*/
    if(((startByte + h_data + l_data)&0xFF) != sum)
    {
      /*Checksum mismatch*/
      #ifdef DebugON
      Serial.println("Invalid result");
      Serial.println(startByte);
      Serial.println(h_data);
      Serial.println(l_data);
      Serial.println(sum);
      #endif      

      InvaliCount++;

      #ifdef DebugON
      Serial.print("Invalid count: ");
      Serial.println(InvaliCount); 
      #endif 

      //if (InvaliCount == 30)
      //{
      //  InvaliCount = 0x00;
      //}
    }
    else
    {
      //InvaliCount = 0x00;
      if(prevDistance != distance) 
      {
        prevDistance = distance;

        //Serial.print("Distance: ");
        //Serial.print(distance);
        //Serial.println(" mm");

        #ifdef DebugON
        Serial.print("Distance: ");
        Serial.print(distance);
        Serial.println(" cm");
        #endif 

        /*Calculate water height from the sensed hieght
        Sensed height is the empty part of the tank,
        so it is substracted from total height of the tank, 
        and the sensor dead zone or the height of the sensor from actual full tank
        is also substracted. Dead zone of A02YYUW is 3cm so sensor is places atleast 3cm above sensing height */

        UG_WaterLevel = TankHeight - (distance - SensorHeight);

        /* Calculate total water quantity % */
        UG_WaterLevel_Percentage = ((UG_WaterLevel/TankHeight)*100);

        /*Volume of a cube = L*W*H*/
        UG_WaterInLitre = TankLength * TankWidth * UG_WaterLevel;

        /*Convert cm3 to liter OR mm3 to liter 
        (multiply the given value of cubic centimeters cm3 by a factor of 0.001 OR divide by 1000)
        (multiply the given value of cubic Millimeters mm3 by a factor of 0.000001)*/
        UG_WaterInLitre = UG_WaterInLitre/1000;

        #ifdef DebugON
        Serial.println("Change detected");
        #endif

        Blynk.virtualWrite(V5, UG_WaterLevel_Percentage);

        Blynk.virtualWrite(V15, UG_WaterInLitre);

        #ifdef DebugON
        Serial.print("UG_WaterLevel_Percentage: ");
        Serial.println(UG_WaterLevel_Percentage);

        Serial.print("UG_WaterLevel: ");
        Serial.println(UG_WaterLevel);

        Serial.print("UG_WaterInLitre: ");
        Serial.println(UG_WaterInLitre);
        #endif

      }
      else
      {
        /*No Change in water level*/
      }
    }
  }
  else
  {
    #ifdef DebugON
    Serial.println("Missed");
    #endif
  }
}

/********************************************************************************************************************************/

void resetMCU()
{
  ESP.restart();
  for (;;) {}
}

/********************************************************************************************************************************/

BLYNK_WRITE(InternalPinDBG) 
{
  if (String(param.asStr()) == "reboot") {
    Serial.println("Rebooting...");

    // TODO: Perform any neccessary preparation here,
    // i.e. turn off peripherals, write state to EEPROM, etc.

    // NOTE: You may need to defer a reboot,
    // if device is in process of some critical operation.

    resetMCU();
  }
}

/********************************************************************************************************************************/

/*This Function will be called when switch state is updated for Light Control*/
BLYNK_WRITE(V10)
{
  Serial.println("Light Switch update received");

  LightSwitchState_u8 = param.asInt();

  //isUpdate_LightSwitch = UPDATED;

  if(ON == LightSwitchState_u8)
    {
      #ifdef DebugON
      Serial.println("Light ON request Received");
      #endif

      digitalWrite(LightControlRelay, RELAY_ON);

      Blynk.virtualWrite(V17, ON);
    }
    else
    {
      #ifdef DebugON
      Serial.println("Light OFF request Received");
      #endif

      digitalWrite(LightControlRelay, RELAY_OFF);

      Blynk.virtualWrite(V17, OFF);
    }
}

/********************************************************************************************************************************/

/*This Function will be called when switch state is updated for L&T Controller*/
BLYNK_WRITE(V1)
{
  Serial.println("L&T Switch update received");

  LnTSwitchState_u8 = param.asInt();

    /*L&T controller is connected to NC terminal of relay, So keeping the relay off means Controller is ON*/
    /*0x00 - Keep relay OFF means L&T controller is ON
      0x01 - Safe state do nothing
      0x02 - Reset the L&T Controller OR turn theL&T Controller OFF by turning ON the relay*/
    if(LNT_CONTROLLER_ON == LnTSwitchState_u8)
    {
      #ifdef DebugON
      /*Make Relay OFF as L&T Controller is connected to NC*/
      Serial.println("L&T Controller ON request Received - Relay State OFF");
      #endif

      digitalWrite(LnTControllerRelay, RELAY_OFF);

    }
    else if (LNT_CONTROLLER_OFF == LnTSwitchState_u8)
    {
      #ifdef DebugON
      /*Make Relay ON so L&T controller turns OFF*/
      Serial.println("L&T Controller OFF request Received - Relay State ON");
      #endif

      digitalWrite(LnTControllerRelay, RELAY_ON);

    }
    else
    {
      /*Do Nothing*/
    }  

  //isUpdate_LnTSwitch = UPDATED;
}

/********************************************************************************************************************************/

/*This Function will be called when switch state is updated for Motor Controller*/
BLYNK_WRITE(V0)
{
  Serial.println("Motor Switch update received");

  MotorSwitchState_u8 = param.asInt();

  if(MOTOR_MODE_OFF == MotorSwitchState_u8)
      {
          #ifdef DebugON
          Serial.println("Motor OFF request Received");
          #endif

          digitalWrite(MotorControlRelay, RELAY_OFF);

          Blynk.virtualWrite(V3, OFF);
      }
      else if(MOTOR_MODE_ON == MotorSwitchState_u8)
      {
          #ifdef DebugON
          Serial.println("Motor ON request Received");
          #endif

          digitalWrite(MotorControlRelay, RELAY_ON);

          Blynk.virtualWrite(V3, ON);
      }
      else
      {
        /*Do Nothing*/
      }

  //isUpdate_MotorSwitch = UPDATED;
}

/********************************************************************************************************************************/

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

As I said earlier, this sounds like a router or ISP issue.

Pete.

Hello @PeteKnight,

I have another ISP provider and I tried to run the ESP32 on that and it still has the same issue.

Also, I tried different ESP32 board’s but no luck.

Also, I tried to run a simple code that only sends a sensor data through a timer function at 1 second periodicity and has a reboot functionality via internal debug pin, even this code faces the same issue with both the ISP’s.

Is there a way to get some help from Blynk? As I have almost run out of all options and I have an annual plan for Blynk, which makes it more difficult for me to move to some other IoT platform.

Which type of subscription plan?

Pete.

Hi @PeteKnight

I have a Maker Plan.

In that case your support plan is via this forum…

It would certainly help if you provided more detail about whether you are using the same modem for each of your ISPs, and what type of internet connection you are using.

Pete.

Hello @PeteKnight ,

I have used 2 different routers with the 2 different ISP’s.

Both the connections are optic fiber based internet connections (FTTH) with speed of 60 Mbps and 200Mbps each.

Hello @PeteKnight ,

Dis you get a chance to see why would this behavior might be happening?

Or might be redirect me to someone who faced this in the past?

I’m out of ideas with this one I’m afraid.

I’m sure that if anyone has had, and resolved, a similar issue in the past then they’ll add their advice.

Pete.

Hello @PeteKnight,

Thanks for the help so far!

I found one clue, my public ip is getting changed every day once around the same time when my blynk write command stops working.

It seems that I dont have a static ip address.

Is it necessary to ha e a static public ip address for blynk to run correctly? Or is there a way to use DDNS LINE noip to get around it?

No.

A DDNS service won’t help with this.

My guess is that when the public IP address changes your router has an issue forwarding incoming packets to the correct internal IP address. Assigning a static internal IP address to the device, rather than using DCHP might help. Checking if there a firmware update available for your router may also help solve the issue.

Pete.

Hello @PeteKnight,

I tried assigning static IP address to my ESP32 but it did not fix the issue.

One more point that I feel might be causing this issue:
There are 2 ESP32 connected to the same auth code sending different data to the blynk, can this be posing a problem?

1 ESP is sending overhead tank water level status only and second ESP is sending underground water level status and also the second ESP controls 2 water pumps via blynk app input.

Why I felt that this might be the issue is: when I sent a reboot command via blynk the the 1st ESP did a reboot and the second ESP which is not responding to button changes did not reboot.

Yes, 100%.
The Blynk cloud servers will only allow one device to be connected with a particular Auth token. If another device tries to connect then the first device will be disconnected and the second devices connected in its place.

Pete.

Hello @PeteKnight ,

Can we generate 2 Auth code for the same template?

I want to display all the data in one dashboard.

Yes, by creating a second device, but I’m not sure that will help you.
Dashboard format is defined at template level, but you will need to switch devices to show the two different data sources.

You can use Automations to send data from one device to another, or you can use the HTTP(S) API.

Pete.

Hello @PeteKnight,

Thank you so much for the all the help.

Now the device always receives the the Blynk_Write when it is online.

So the root cause of the issue was 2 ESP32 devices using same auth codes, I was not aware previously that auth code needs to be unique per device.

But still I am left with one issue:

Every 24 hours my global IP changes and when this happens, my both the devices connected with 2 different auth codes go offline for 18 to 30 mins.
I can confirm that the devices do not reset as the up timer keeps running after they are back online.
Also the internet connectivity is not lost when the global IP change happens, my other devices like CCTV camera smart switch’s still work.

I am tracking this issue for last 1 week and the behavior is exactly the same.

I have made my local IP static as per our last discussion.

Do you know of any such issue where global IP change causes lost of connection with blynk server?

Best Regards,
Kamran Pathan