ESP32 wifi getting disconnected once within 3-4 days

I integrated ESP32 (ESP32 DEVKITC V4) with the Blynk IoT platform. I observed that my ESP32 is getting disconnected once in a while from Wifi. I added a patch to restart ESP (ESP.restart()) if it is not connected to Wifi for the last 30 minutes. Sometimes this works but not always. I have to turn off the power supply and then turn it on. And then it gets to connect to Wifi within a few seconds.

I tried with esps, but no luck.

  1. ESP32 DEVKIT V1 (ESP32-Wroom-32) and
  2. ESP32 DEVKITC V4 (ESP32-Wroom-32U)

I'm not sure what is the reason.

Here is the program:

//#define BLYNK_DEBUG        // Optional, this enables more detailed prints
//#define BLYNK_PRINT Serial // Defines the object that is used for printing
#define BLYNK_TEMPLATE_ID "<<Replace-me>>"
#define BLYNK_DEVICE_NAME "<<Replace-me>>"
#define BLYNK_AUTH_TOKEN "<<Replace-me>>"
#define BLYNK_FIRMWARE_VERSION "0.1.2"


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


#define WIFI_LED   26
#define SENSOR_PIN 36
#define VPIN_0    V0  
#define RELAY_PIN 5
#define PUMP_IDEAL  0
#define PUMP_RUNNING  1
#define PUMP_FORCE_KILL_IN_MINS  15 // IN MINS
#define HARD_RESTART_AFTER  30 // IN MINS
 
char auth[] = BLYNK_AUTH_TOKEN;
int wifiFlag = 0;
int pumpState =0; //PUMP_IDEAL, PUMP_RUNNING 
int pumpStartTime =0; //In millis

int lastConnected = 0;

bool forceKilled = false;
int pumpRunDurationInMinsInFroceKill = 0; 

char ssid[] = "<<Replace-me>>";
char pass[] = "<<Replace-me>>";


BlynkTimer timer; 


BLYNK_WRITE(VPIN_0)
{
 
  int val = param.asInt();  
  
  if(val ==1){
    
    pumpState=PUMP_RUNNING; 
    pumpStartTime=millis();
        
    Serial.println("Pump Started ");
    Blynk.logEvent("pump_start", String("Pump Started."));

    digitalWrite(RELAY_PIN, LOW);
            
  }else {
    
    digitalWrite(RELAY_PIN, HIGH);  

    double totalTimePumpRun = (double) (millis() -  pumpStartTime)/(1000.0*60.0); //mins 
    pumpStartTime = 0;
    
    if(pumpState == PUMP_RUNNING) {
      Serial.println(String("Pump runs  (Mins) : ") + totalTimePumpRun);   
      Blynk.logEvent("pump_stopped", String("Pump runs (in Mins): ") + totalTimePumpRun) ;
      Blynk.virtualWrite(V1, totalTimePumpRun);  
    }else {
      Serial.println(String("Pump runs  (Mins) : ") + totalTimePumpRun);   
      Blynk.logEvent("pump_stopped", String("[Without Start Data] Pump runs (in Mins): ") + totalTimePumpRun) ;
    }
    
    pumpState=PUMP_IDEAL;    
  }
}

void checkBlynkStatus() { 
  // HARD RESTART 
  if(millis() - lastConnected > HARD_RESTART_AFTER*60*1000){      
      lastConnected = millis();
      ESP.restart();
      
  }  

  // FORCE KILL;   
  if(pumpState == PUMP_RUNNING){   
    pumpRunDurationInMinsInFroceKill = (millis() - pumpStartTime) /(1000*60) ;       
    
    if(pumpRunDurationInMinsInFroceKill >= PUMP_FORCE_KILL_IN_MINS){                   
        digitalWrite(RELAY_PIN, HIGH);
        pumpState=PUMP_IDEAL;    
        forceKilled  = true;
        
        Serial.println("Force Killed Pump after (in mins) : " + pumpRunDurationInMinsInFroceKill);                       
    }
  }

  float sensorValue = analogRead(SENSOR_PIN);
  int moisture = (int) (100 -(sensorValue/4095)*100);  
  
  bool isconnected = Blynk.connected();
  
  if (isconnected == false) {
    wifiFlag = 1;    
    WiFi.reconnect();
    digitalWrite(WIFI_LED, LOW);
  
  } else  {   
    wifiFlag = 0;    
    lastConnected = millis();   
    
    digitalWrite(WIFI_LED, HIGH);     
    Blynk.virtualWrite(V2, moisture); 
    
    if(forceKilled){      
      Blynk.virtualWrite(VPIN_0, 0);  
      
      pumpRunDurationInMinsInFroceKill = (pumpRunDurationInMinsInFroceKill <= 0)?1:pumpRunDurationInMinsInFroceKill;
      Blynk.virtualWrite(V1, pumpRunDurationInMinsInFroceKill);
      
      Blynk.logEvent("force_kill", String("Foce Killed pump after (in mis)" )+ pumpRunDurationInMinsInFroceKill);
      
      pumpRunDurationInMinsInFroceKill = 0;         
      forceKilled = false;       
    }
  }
}

BLYNK_CONNECTED() {
  Blynk.syncVirtual(VPIN_0);   
}

void setup(){
  Serial.begin(9600);
  Serial.println("Planto-Hydra is starting.");
  
  lastConnected = millis();
    
  pinMode(RELAY_PIN, OUTPUT);  
  pinMode(WIFI_LED, OUTPUT);

  timer.setInterval(2000L, checkBlynkStatus);

  digitalWrite(WIFI_LED, LOW);
  digitalWrite(RELAY_PIN, HIGH);
  
  Blynk.begin(auth, ssid, pass); 
  Serial.println("Planto-Hydra Setup completed.");
 
}

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

Here is code I use to connect to WiFi.

void connectToWiFi()
{
  int TryCount = 0;
  while ( WiFi.status() != WL_CONNECTED )
  {
    TryCount++;
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    vTaskDelay( 4000 );
    if ( TryCount == 10 )
    {
      ESP.restart();
    }
  }
  WiFi.onEvent( WiFiEvent );
}

I check for a valid WiFi connection 4 times a second.

here is the code that calls the WiFi connection test.

void MQTTkeepalive( void *pvParameters )
{
  sema_MQTT_KeepAlive   = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
  MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 250; //delay for ms
  for (;;)
  {
    //check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // whiles MQTTlient.loop() is running no other mqtt operations should be in process
      MQTTclient.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
    }
    else {
      log_i( "MQTT keep alive found MQTT status % s WiFi status % s", String(wifiClient.connected()), String(WiFi.status()) );
      if ( !(wifiClient.connected()) || !(WiFi.status() == WL_CONNECTED) )
      {
        connectToWiFi();
      }
      connectToMQTT();
    }
    //log_i( " high watermark % d",  uxTaskGetStackHighWaterMark( NULL ) );
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete ( NULL );
}

Hope it helps.

I use freeRTOS and run those as a freeRTOS task on a ESP32.

I did quite similar thing.
Restarting the ESP after 30 minutes.

  if(millis() - lastConnected > HARD_RESTART_AFTER*60*1000){      
      lastConnected = millis();
      ESP.restart();
      
  } 

//// ------------- Remove in between code -------- ///// 

 if (isconnected == false) {
    wifiFlag = 1;    
    WiFi.reconnect();
    digitalWrite(WIFI_LED, LOW);
  
  } else  {   
    wifiFlag = 0;    
    lastConnected = millis();  
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.