Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By GregryCM
#62722 I have Ticker setup to give me an interrupt every 1 sec. In the attached Ticker ISR, I increment a counter, and if the counter exceeds a limit, I issue ESP.restart(). I am trying to implement a loop watchdog.

Code looks like this:
Code: Select all#define LOOP_WATCHDOG_RESET_TIME 30 //  Reset uC if Loop does not execute for 30 Seconds

/****************************   Local Variables   *****************************/
Ticker LoopWatchDog;  //  Loop WatchDog Timer
static unsigned long LoopWatchDogTimer = 0;

void setup( void )
{
  //  Start the Loop WatchDog ISR, and assign a callback function
  LoopWatchDog.attach_ms( 1000, LoopWatchDogISR );
}

void ICACHE_RAM_ATTR LoopWatchDogISR( void )
{
  if( ++LoopWatchDogTimer >= LOOP_WATCHDOG_RESET_TIME )
  {
    ESP.restart();  // normal reboot
    //ESP.reset();    //  hard reset 
  }
}

void loop( void )
{
  //  Reconnect wifi if not connected
  if( WiFi.status() != WL_CONNECTED )
  {
    delay(10);
    StartWiFiSTA();
    UtilityWiFiReconnectInc();
    return;
  }
 
//  LoopWatchDogReset();

  server.handleClient();
}

void LoopWatchDogReset( void )
{
  LoopWatchDogTimer = 0;
}


The code works... ESP8266 restarts every 30 seconds, because the timer is not getting reset in loop().

However, an Exception(28) is generated on each restart, and a stack dump occurs.
Is this expected?
Can it be silenced?

If I execute a ESP.reset() instead, then no exception and no dump occurs.

Code: Select allException (28):
epc1=0x4000df2f epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000033 depc=0x00000000

ctx: cont
sp: 3fff1ae0 end: 3fff1f60 offset: 01a0

>>>stack>>>
3fff1c80:  00000000 3fff350c 40238390 40107014 
3fff1c90:  4021400b 00000000 00000000 4020e489 
3fff1ca0:  00000033 00000010 402148a5 3ffeed9c 
3fff1cb0:  3fff350c 00000000 3ffeed9c 3fff2b14 
3fff1cc0:  3fff350c 402147f1 3ffeed9c 00000000 
3fff1cd0:  3ffea772 3fff00dc 3ffef548 00000064 
3fff1ce0:  3fff2f56 3ffef4bc 3ffea772 3ffea772 
3fff1cf0:  00000033 3ffeedc8 3fff286c 00000008 
3fff1d00:  40216357 3ffef470 3ffef548 0000010f 
  :
  :
  :
3fff1f10:  3fffdad0 3fff0f34 4020a2a4 3fff0f40 
3fff1f20:  402016c6 0000000a 0000000a 3fff0f34 
3fff1f30:  3fffdad0 00000000 3fff0f2c 40203b41 
3fff1f40:  3fffdad0 00000000 3fff0f2c 4020a2f0 
3fff1f50:  feefeffe feefeffe 3fff0f40 40100718 
<<<stack<<<



Thanks,
GregryCM
User avatar
By danbicks
#62735 Use a flag in the timer interrupt routine, set this to true once interrupt occurs and do the processing of the flag in the main loop for a given reset of the ESP.

Add to your loop something like this:

Code: Select all if (FL_Watchdog)
           {
           FL_Watchdog = false; // set flag to false for next interrupt
              if (Count >= 30) // check for 30 seconds here
                 {
                 ESP.restart(); 
                 }
           }


good luck Dans
User avatar
By GregryCM
#62737 Hi Dans,

Thanks for the response. The purpose of this code is to reset/restart the uC if the loop() stops running for some reason. I do not understand why the Exception (28) and stack dump occurs with ESP.restart().

If the ESP.restart() is executed from loop(), rather than the ISR, then no exception and dump occurs. So that is a good clue.

Thanks
User avatar
By GregryCM
#62868 I added debug messages and noticed that we were returning from the ISR after ESP.restart() was executed. It seems that we always returned to the beginning of loop(). WiFi was no longer connected, so WiFi was started again, which seemed to cause the exception. I even added a delay(1000) in the ISR after ESP.restart(), but we still exited the ISR.

I changed the delay if not connected from 10mS to 100mS, and this seems to allow time for the ESP.restart() to complete.

Code: Select allvoid loop( void )
{
  //  Reconnect WiFi if not connected
  if( WiFi.status() != WL_CONNECTED )
  {
    delay(100);   //  Wait 100mS.  Allows time for ESP.restart() to complete
    StartWiFiSTA();
    UtilityWiFiReconnectInc();
    return;   //  return from loop(), allow OS to run
  }
 
  //LoopWatchDogKick();

  server.handleClient();
  yield();


I have also added the WiFi.persistent(false); statement to disable rewriting the ssid and password to FLASH on every reconnection.

Code: Select allstatic void StartWiFiSTA( void )
{
  Serial.print( "\r\nAttempting connection with " ); Serial.println( ssid );

  WiFi.persistent(false); // Do not write new connections to FLASH
  WiFi.mode( WIFI_STA );   
  WiFi.begin( ssid, password );

  // Set fixed IP Address
  IPAddress ip(192, 168, 1, 125);
  IPAddress gateway(192, 168, 1, 1);
  IPAddress subnet(255, 255, 255, 0);
  WiFi.config(ip, gateway, subnet);

  //  Wait for WiFi connection
  while( WiFi.status() != WL_CONNECTED )
  {
    Serial.print( "." );
    delay( 500 );
  }


I can now get a clean restart when the Loop WatchDog times out.