Arduino Stops communicating with WIFI Randomly, Will Not Reconnect.

Hey all,

Working with a MKR1010, and using Blynk app to view readings from board. The problem I am having is about everyday the board loses connection with WiFI, the CHRG light on the board will be be blinking, and with a press of the reset button the board reconnects. I have tried adding code to have the board reconnect, but it seems unchanged. I have another WIFI connected device (Behyve sprinkler timer) on the wall next to the board, and it runs 99.99% with no connection issues. Any ideas on what I can do to get the board to reconnect when it drops WIFI, and why is it dropping WIFI in the first place?

#include <Smoothed.h> 	
#include <Blynk.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>

char ssid[] = "---------";
char pass[] = "---------";
int status = WL_IDLE_STATUS;

char auth[] = "--------";
BlynkTimer timer;

Smoothed <float> sensorData;
Smoothed <float> sensorData2;
float currentPreSensorValue;
float currentPostSensorValue;
float smoothedPreSensorValueExp;
float smoothedPostSensorValueExp;

float preVoltage;           
float postVoltage;          
float prePsi;               
float postPsi;              
float pressureDelta;
float preVoltageTotal;
float postVoltageTotal;

float orderThreshold = 3.0;
float changeThreshold = 4.0;

boolean beenNotified = false;

enum FilterStatus {FilterOk, OrderFilter, ChangeFilter};

FilterStatus FilterCondition = FilterOk;

int i;

WidgetLED ledGood(V1);
WidgetLED ledOrder(V2);
WidgetLED ledChange(V3);

byte preSensorPin = A1;   
byte postSensorPin = A2; 
const byte yellowLEDPin = 7;            
const byte redLEDPin = 6;    

void setup() {
  
  SerialUSB.begin(9600);
  
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   
    status = WiFi.begin(ssid, pass);

    delay(10000);
  }


  Blynk.begin(auth, ssid, pass);
    
  timer.setInterval(1000L, myTimerEvent);
  
  sensorData.begin(SMOOTHED_EXPONENTIAL, 10);
  sensorData2.begin(SMOOTHED_EXPONENTIAL, 10); 
  
  pinMode(preSensorPin, INPUT);        
  pinMode(postSensorPin, INPUT); 
  pinMode(yellowLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  
}


void loop() {
  
  Blynk.run();
  timer.run();
  
  // Read the value from the sensor
  currentPreSensorValue = analogRead(preSensorPin);
  currentPostSensorValue = analogRead(postSensorPin);
    
  //Add the new value to both sensor value stores
  sensorData.add(currentPreSensorValue);
  sensorData2.add(currentPostSensorValue);   
    
  // Get the smoothed values
  smoothedPreSensorValueExp = sensorData.get();
  smoothedPostSensorValueExp = sensorData2.get();
  
  Serial.print("  Pre-filter psi: ");
  Serial.println(prePsi);
  
  Serial.print("  Post-filter psi: ");
  Serial.println(postPsi);
   
  CheckFilter();
  ManageFilterNotify();
  ManageFilterLeds();
}

void myTimerEvent()
{
  
  preVoltage =  (5.0 / 1023.0) * smoothedPreSensorValueExp;
  prePsi = (preVoltage - 0.5) * (100.0) / (4.5 - 0.5);
  Blynk.virtualWrite(V5, prePsi);
  
  
  postVoltage =  (5.0 / 1023.0) * smoothedPostSensorValueExp;
  postPsi = (postVoltage - 0.5) * (100.0) / (4.5 - 0.5);
  Blynk.virtualWrite(V6, postPsi);
  
  pressureDelta = (prePsi - postPsi);
  Blynk.virtualWrite(V7, pressureDelta);

}

void CheckFilter()  // Filter condition state machine
{
  // All we can do is go from OK to order or from Order to change
  switch (FilterCondition)
  {
    case FilterOk:
      if (prePsi - postPsi > orderThreshold)      //  if the pressure drop is greater than Order threshold
      {
        FilterCondition = OrderFilter;
      }
      break;
    case OrderFilter:
      if (prePsi - postPsi > changeThreshold)        //if the pressure drop is greater than replace threshold
      {
        FilterCondition = ChangeFilter;
      }
      break;
    case ChangeFilter:  // Once we're in this state, only a reset will change it.
      break;
  }
}

void ManageFilterNotify()
{
  switch (FilterCondition)
  {
    case FilterOk:
    Serial.println("Filter ok");
      ledGood.on();
      ledOrder.off();
      ledChange.off();
      break;
    case OrderFilter:
    Serial.println("Order filter");
      if (!beenNotified){
      Blynk.notify("It is time to order filter");
      Blynk.email("-----------", "FilterLynk", "It is time to order the fitler.");
      beenNotified = true;
      }
      ledGood.off();
      ledOrder.on(); 
      break;
    case ChangeFilter:
    Serial.println("Replace filter");
      if(!beenNotified){
      Blynk.notify("It is time to replace fitler!");
      Blynk.email("---------", "FilterLynk", "It is time to change the fitler.");
      beenNotified = true;
      }
      ledOrder.off();
      ledChange.on(); 
      break;
  }
}

void ManageFilterLeds()
{
  switch (FilterCondition)
  {
    case FilterOk:
    Serial.println("Leds off - filter ok");
      digitalWrite(redLEDPin, LOW);
      digitalWrite(yellowLEDPin, LOW);
      break;
    case OrderFilter:
    Serial.println("Show yellow - order filter");
      digitalWrite(redLEDPin, LOW);
      digitalWrite(yellowLEDPin, HIGH);
      break;
    case ChangeFilter:
    Serial.println("Show red - replace filter");
      digitalWrite(redLEDPin, HIGH);
      digitalWrite(yellowLEDPin, LOW);
      break;
  }
}

Have you tried to add some code like

  while (WiFi.status() != WL_CONNECTED) {
    WiFi.end();
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   
    WiFi.begin(ssid, pass);

    delay(2000);
  }

to your loop()?

I hade code very similar to that, but in setup(). I will try that code in my loop() and report back. Thanks!

You can write a watchdog routine that checks to see if the WiFi is connected and if not have the ESP8266 reset.

The ESP8266 can be reset with the command ESP.reset().

I figure the watchdog will keep your system in operation whiles you figure out the issue or maybe as a solution that you accept.

I had an issue with a TFMini not giving info every once in a while so I created several tasks in setup related to the watchdog.
In setup().

 xTaskCreatePinnedToCore ( fResetWatchDogVariables, "fResetWatchDogVariables", TaskStack10K, NULL, Priority3, NULL, TaskCore0 ); // assigned to core 0
  xTaskCreatePinnedToCore ( fBlinkBuiltIn, "fBlinkBuiltIn", TaskStack10K1, NULL, Priority2, NULL, TaskCore0 ); //assigned to core 0
  xTaskCreatePinnedToCore (  fLIDAR_Watchdog_Inc, "fLIDAR_Watchdog_Increment", TaskStack10K, NULL, Priority4, NULL, TaskCore0 );
  sema_LIDAR_Watchdog_Counter = xSemaphoreCreateMutex();
  xSemaphoreGive ( sema_LIDAR_Watchdog_Counter );
  xTaskCreatePinnedToCore ( fLIDAR_Watchdog, "fLIDAR_Watchdog", TaskStack10K, NULL, Priority5, NULL, TaskCore0 );

Here are the tasks:

void fResetWatchDogVariables ( void *pvParameters )
{
  for ( ;; )
  {
    xEventGroupWaitBits (eg1, evtResetWatchDogVariables, pdTRUE, pdTRUE, portMAX_DELAY) ;
    //    Serial.println( " triggered fResetWatchDogVariables " );
    //      // reset watchdog variables
    xSemaphoreTake ( sema_LIDAR_Watchdog_Counter, xSemaphoreTicksToWait );
    LIDAR_Watchdog_Counter = 1;
    xSemaphoreGive ( sema_LIDAR_Watchdog_Counter );
    xSemaphoreTake ( sema_LIDAR_OK, xSemaphoreTicksToWait );
    bLIDAR_OK = true;
    xSemaphoreGive ( sema_LIDAR_OK );
    //      // xEventGroupSetBits( eg, evtOpenReadSPIFF_FILE );

  }
  vTaskDelete ( NULL );
} // void fResetWatchDogVariables ( void *pvParameters )
////
void fLIDAR_Watchdog_Inc( void *pvParameters )
{
  for (;;)
  {
    xEventGroupWaitBits (eg, evtLIDAR_Watchdog_Inc, pdTRUE, pdTRUE, portMAX_DELAY );
    xSemaphoreTake ( sema_LIDAR_Watchdog_Counter, xSemaphoreTicksToWait );
    LIDAR_Watchdog_Counter = LIDAR_Watchdog_Counter << 1;
    if ( LIDAR_Watchdog_Counter < 0 )
    {
      // Serial.println ( LIDAR_Watchdog_Counter );
      // LIDAR_Watchdog_Counter = 1;
      ESP.restart();
    }
    //    else
    //    {
    xSemaphoreGive ( sema_LIDAR_Watchdog_Counter );
    //    }
  }
  vTaskDelete( NULL );
}
//////////////////////////////////////////////////////////////////////////////////////////
void fLIDAR_Watchdog( void *pvParameters )
{
  for (;;)
  {
    xEventGroupWaitBits (eg, evtLIDAR_Watchdog, pdTRUE, pdTRUE, portMAX_DELAY );
    Serial.println ( "fLIDAR_Watchdog" );
    xEventGroupSetBits( eg, evtfLIDAR_Power_Off ); // turn power to the LIDAR unit off.
    xSemaphoreTake ( sema_LIDAR_OK, xSemaphoreTicksToWait );
    // vTaskDelete( xHandle_ReceiveSerial_LIDAR );
    xHandle_ReceiveSerial_LIDAR = NULL;
    bLIDAR_OK = false; // begin timer count to turn LIDAR unit on
    xSemaphoreGive ( sema_LIDAR_OK );
  }
  vTaskDelete( NULL );
} //void fLIDAR_Watchdog( void *pvParameters )

Note the above code is for a ESP32 thus my use of ESP.restart(); instead of ESP.reset();. I, eventually figured out the problem, and the watchdog rarely triggers but I still keep the code for a just in case.


The ESP32 API has a watchdog timer module: Watchdogs - ESP32 - — ESP-IDF Programming Guide latest documentation, Perhaps the ESP8266 has a watchdog API as well.

You might, also consider that the ESp8266 has 2 hardware timers, one is available for your use.

Hey thanks for the reply Idahowalker, I have the ESP32 on my MKR1010. Are you inserting this WDT inside the loop()?

By the way, just curious, where are you located in Idaho?

RealHousewifeofIdaho:
Hey thanks for the reply Idahowalker, I have the ESP32 on my MKR1010. Are you inserting this WDT inside the loop()?

By the way, just curious, where are you located in Idaho?

I am not inserting any code inside the loop(). The ESP32 has freeRTOS as a native library. I use freeRTOS to take advantage of features of the ESP32; such as using both cores for my tasks.

Are you able to plug in a USB cable into the ESP32, when it seems to error, to see if an actual error message is produced by the ESP32 on the Arduino IDE Monitor screen?

If you have selected Debug under Tools|Core Debug Level, and upload code. The ESP32 will be able to capture quite of a number of errors and display them.