ESP8266: Watchdog functions

The objective of this post is to analyse some of the watchdog functions available on the Arduino IDE libraries for the ESP8266.


Introduction

The objective of this post is to analyse some of the watchdog functions available on the Arduino IDE libraries for the ESP8266.

A watchdog is a timer that, when not reset before expiring, triggers the reset of the system [1] that is monitoring. In our case, the system will be the ESP8266 microcontroller.

So, the main program needs to periodically reset the watchdog timer, to prevent the reset of the CPU and keep working normally.

The watchdog should be configured with a time greater that the worst case scenario delay in the program [1], so it only triggers in error / unpredicted problems that may make the main program to be locked and not recover on its own [2]. In those locking cases, the watchdog is not reset and, when it expires, resets the system.

This concept is of extreme importance, specially in microcontrollers, which may be affected by environmental conditions such as electrical noise, which can cause hardware malfunction that locks the execution. Additionally, it is  useful for problem in the code that may put the execution in an undesired infinite loop.

The ESP8266 has 2 watchdogs, one implemented in hardware and another in software [3].

The tests were performed using a NodeMCU board, a very cheap and easy to use ESP8266 board. The board can also be bought at eBay here.


The software watchdog functions

In order to access the watchdog functions on the ESP8266, we have the EspClass, which can be analysed in more detail here. We can access the functionality of this class by using an extern variable called ESP, which is declared here in the libraries.

In order to disable the software watchdog, we just need to call the wdtDisable method on the ESP object, as indicated bellow.

ESP.wdtDisable();

Although this disables the software watchdog, the hardware watchdog will still remain active, causing a reset after some time. As indicated in the comments of the wdtDisable method, if we stop the software watchdog by more that 6 seconds, the hardware watchdog will trigger. This is approximately what I got when testing it.

We can re-enable the software watchdog by calling the wdtEnable method, as indicated bellow.

ESP.wdtEnable(1000);

It’s important to note that an integer value needs to be passed as input argument of this method, which would correspond to the number of milliseconds for the watchdog to trigger. Nevertheless, this value makes no effect and it is not used in the internal call of the SDK ESP8266 functions, as can be seen by the source code here.

Additionally, in the header file, it’s clearly stated that, at the time, setting the timeout is not implemented. Unfortunately, it’s not clear what is the default value of the watchdog timer when we call this function, and neither it is documented in the SDK of the ESP8266.

In order to explicitly restart the watchdog, we can call the wdtFeed method, specified here. Fortunately, the ESP libraries implicitly reset the watchdog in many of the functions, so most of the time we don’t need to worry about feeding the watchdog. Nevertheless, it’s important to know that it exists, in order to troubleshoot spontaneous reboots of our programs.

ESP.wdtFeed();


Triggering the hardware watchdog

To trigger the hardware watchdog, we just need to disable the software watchdog timer and do an infinite loop. We can do all of these actions in the setup function, as indicated bellow. Note that we will do an infinite loop with a while loop.

void setup() {

 ESP.wdtDisable();
 while (1){};

}

void loop(){}

After uploading the code, open the serial port to check the output. When the watchdog fires, a crash log is printed to the serial port, as indicated in the figure 1.

esp8266-hardware-watchdog-reset

Figure 1 – Crash log of the hardware watchdog reset.

As indicated in the figure, there is a mention to the cause (wdt reset) and the reset cause has the number 4, which corresponds to the hardware watchdog reset [4]. You can check other reset code here. This result is consistent with the indicated in this document.


Triggering the software watchdog

In order to trigger the software watchdog reset, we just use the same code as before and remove the disabling of the software watchdog (enabled by default).

void setup() {

 while (1){};

}

void loop(){}

In this case, after uploading the code and opening the serial port, we will just get the result illustrated in figure 2, when the software watchdog triggers.

esp8266-software-watchdog-reset

Figure 2 – Crash log of the software watchdog reset.

The result is also coherent with the one shown here.


Feeding the watchdog

Finally, we will use the code indicated bellow to test the function of restarting the watchdog. So, we will call the wtdFeed method inside our infinite loop, which will ensure the reset of the watchdog.

It works both for the software and hardware watchdog, so if we uncomment the call to the wdtDisable method, the program will still keep running without being reset by the hardware watchdog.

void setup() {

 //ESP.wdtDisable();
 while (1){ESP.wdtFeed();};

}

void loop(){}


Final notes

As can be seen through this post, the documentation about the watchdogs of the ESP8266 is still scarce and the functionality to control them is still a work in progress.

Additionally, an easy way to control the hardware watchdog is still lacking, which is an important feature to give us more control over the device.


References

[1] https://developer.mbed.org/cookbook/WatchDog-Timer

[2] http://searchmobilecomputing.techtarget.com/definition/watchdog-timer

[3] https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/doc/faq/a02-my-esp-crashes.md

[4] http://www.esp8266.com/viewtopic.php?p=2096#p2112


Technical details

  • ESP8266 libraries: v2.3.0

70 thoughts on “ESP8266: Watchdog functions”

    1. Hi!

      As the name implies, one is implemented in hardware and the other is implemented in software.

      I’m not sure what is the actual implementation of these two variants in the ESP8266, but one place you can ask around about is on the GitHub page of the Arduino core, maybe some one there can explain how they are effectively implemented in the ESP8266.

      Here are some interesting resources on watchdogs:
      https://www.embedded.com/electronics-blogs/beginner-s-corner/4023849/Introduction-to-Watchdog-Timers
      -https://en.wikipedia.org/wiki/Watchdog_timer
      https://stackoverflow.com/questions/18845464/what-is-the-difference-between-hardware-watchdog-and-software-watchdog

      Best regards,
      Nuno Santos

    1. Hi!
      As the name implies, one is implemented in hardware and the other is implemented in software.
      I’m not sure what is the actual implementation of these two variants in the ESP8266, but one place you can ask around about is on the GitHub page of the Arduino core, maybe some one there can explain how they are effectively implemented in the ESP8266.
      Here are some interesting resources on watchdogs:
      https://www.embedded.com/electronics-blogs/beginner-s-corner/4023849/Introduction-to-Watchdog-Timers
      -https://en.wikipedia.org/wiki/Watchdog_timer
      https://stackoverflow.com/questions/18845464/what-is-the-difference-between-hardware-watchdog-and-software-watchdog
      Best regards,
      Nuno Santos

    1. Hi,

      The function of the watchdog is precisely restarting your program without the need for human intervention, in case it is unable to feed the watchdog with the periodicity it needs.

      Note that the code shown here is designed to trigger the watchdogs, so it is not very useful.

      Nonetheless, a watchdog is of extreme importance for applications where it is impractical to have human intervention in case the program crashes (ex: space ships or satellites). So, if the program crashes and it is no longer able to feed the watchdog, then it is automatically restarted.

      Hope this clarifies. 🙂

      Best regards,
      Nuno Santos

    1. Hi,
      The function of the watchdog is precisely restarting your program without the need for human intervention, in case it is unable to feed the watchdog with the periodicity it needs.
      Note that the code shown here is designed to trigger the watchdogs, so it is not very useful.
      Nonetheless, a watchdog is of extreme importance for applications where it is impractical to have human intervention in case the program crashes (ex: space ships or satellites). So, if the program crashes and it is no longer able to feed the watchdog, then it is automatically restarted.
      Hope this clarifies. 🙂
      Best regards,
      Nuno Santos

  1. Excellent article. I too have found documentation fairly light.

    I was having trouble with an ESP8266 set up program so to single step added code to flash an LED and then continuously loop using a while(1); statement – works with Arduino but in this case the LED continuously flashed indicating that the ESP8266 was continuously resetting.

    My internet readings then indicated that the watch dog timer would reset if ever the setup code or the loop code took greater than one second. (The one second may be too short but it indicates the idea.)

    Further reading indicated the function yield( ). This function allows ESP8266 background routines to perform actions – I suspect this would include resetting any watch dog timers.

    To flash the LED my code used the library function delay(mS); – normally delay( ) would block any user code (except for interrupts). Further investigation revealed delay() contained the function yield() – hence in my case using delay( ) as part of my routine to flash the LED would not cause the watch dog to time out.

    However while(1); did cause a problem. By including a yield( ) the issue was solved. That is while(1) { yield( ); } causes the program to loop as desired but still allows the watch dog to be reset in the background. In this case the yield( ) is equivalent to the library method ESP.wdtFeed(); used in your example.

    I hope this information is useful and not just added to the internet chatter.

    JK

    1. Hi!

      Thank you very much for your feedback, I’m very happy to know you found this article useful 🙂

      That was indeed one of the biggest gaps of the ESP8266 which is being worked on in the ESP32, since now there is much more documentation available. Still, I would really like to see much more documentation and examples available since some features are really hard to discover 🙂

      Thank you very much for sharing that information, it will definitely be very useful for others.

      What you mention makes perfect sense since there is plenty of stuff running under the hood and at some points the main code that is executing needs to give CPU time to those routines.

      I would really like to know more about what is done by all those routines, but unfortunately, at least at the time I was more actively working with the ESP8266, what happened under the hood was basically a black box and very few information was known.

      Again, thank you very much for the information and always feel free to share here new findings 🙂

      Best regards,
      Nuno Santos

      1. Following your reply I decided to do some more investigation. I am using a Mini ESP8266 Board from Duinotech – I suspect its the same as a WeMos D1 Mini Lite.

        The board contains a LED on pin D4 (GPIO2). I flash the LED once and once only at the beginning of the setup( ) routine:

        void setup() {
        pinMode(D4, OUTPUT);
        digitalWrite(D4,LOW); //LED active low
        digitalWrite(D4,HIGH);
        //delay(10000); //no problem
        // delayJK(10000); //a problem
        while(1) yield( );
        }
        Without the yield( ) the program continually exits the while(1) loop, resets itself and the flashes the LED. – While the flash is visible I used a logic analyser to measure the time between flashes as 3.2 seconds.

        Adding the yield( ) statement eliminates the flashing – ie the ESP8266 does not reset so I conclude the wdt does not time out.

        I added a 10 second delay which I have called delayJK( ).
        void delayJK(long wait){
        long start = millis();
        while (wait > (millis( ) – start))
        yield( ); //eliminates problem
        }

        Without the yield the LED flashes every 3 seconds as before. Adding a yield( ) and the processor does not reset. (LED does not flash – wdt does not time out)

        Testing with the library delay( ) routine did not cause the processor to reset. The library routine contains a yield( );

        These comments are just a little more detail on my previous but I have added the measurement of 3.2 seconds. I guess the conclusion is if your setup( ) or loop( ) routines are longer than 3 seconds be alert for unexpected resets due to the wdt timing out!

        JK

        1. Thank you very much for the additional information 🙂

          It’s very useful to know how much time to expect before the watchdog fires.

          Did you test it with both the Hardware and Software watchdogs enabled?

          Supposedly from the arduino core code comments, the hardware watchdog should trigger after around 6 seconds in case the software one is disabled:
          https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/cores/esp8266/Esp.cpp#L97

          At the time I’ve been testing this, I found that it was possible to disable the software watchdog, but did not find any way of disabling the hardware watchdog.

          It would also be nice if we could configure these timings for the hardware one. It is possible to configure it for the software watchdog, but I did not find any function for the hardware.

          I’ve been doing a lot of testing on the ESP32 but I haven’t yet dedicated any time to check how the watchdogs are working there.

          Hopefully they have improved and clarified how things operate, although I’ml curious how it works with the two cores of the ESP32.

          Need to find some time to look into it 🙂

          Thanks again for the info!

          Best regards,
          Nuno Santos

          1. Hi Nuno
            I modified my test code to investigate the hardware timeout:

            void setup() {
            ESP.wdtDisable( ); //new line to disable software watch dog
            pinMode(D4, OUTPUT);
            digitalWrite(D4,LOW); //LED active low
            digitalWrite(D4,HIGH);
            while(1);
            }

            Using a logic analyser I observed the LED to flash every 8.44 seconds so in summary with my system:
            By default the software watch dog timed out after 3.2 seconds (previous post)
            With the S/W wdt disabled the hardware watch dog timed out after 8.44 sec.

            The conclusion is as before – if your program spends up to 3 seconds in the setup( ) or loop( ) functions be aware that the watchdog timers may generate a reset.

            JK

          2. I did another test:

            Following reset my understanding is that the ESP8266 comes up in station mode and looks for the last access point to which was attached. If it cannot find that it comes up as an access point. In the the discussion below I would call these “under the hood” WiFi operations.

            In my experiment without the yield( ) function the WDT timed out. The program was continually resetting. In this situation my PC did not detect an AP.

            When the yield( ) function is included the WDT does not time out. My PC then detects an AP “ESP_1D9BAF”.

            My conclusion is that with the yield( ) function the ESP8266 is able to run in the background the necessary “under the hood” WiFi functions whereas without the yield( ) the “under the hood” WiFi functions are blocked.

            So with the yield( ) the WDT is continually reset and the WiFi functions (the radio part) continue to function. (I can attach my PC to the ESP8266 but will then need a user program to do anything useful).

            There maybe other “under the hood” operations.

            JK

            1. Sir can u tell me if I recieve data in continuous form in case of wireless but wdt reset problem occur (to connect one wi-fi board to hotspot) how can I resolve this problem

              1. First of all in micro-controller terms the data is not really continuous – one byte will arrive- there will be a lull – then the next byte will arrive. Its between these bytes that other things can be done.

                Note many arduino/ESP8266 operations are transparent/invisible to you.

                In more detail the Arduino code will be:

                setup( ); //you will write this code
                while (1) {
                under the hood operations
                loop( );
                }
                void loop(void) {
                your code for the loop.
                }

                In the example you give your code for the loop will be:

                if (new_data) take_action( );

                Your code for take_action( ) might be

                put data into a buffer
                if you have all the data you need
                handle_the_data( )

                Now provided the routine “handle_the_data( )” does not take longer than the watch dog timer timeout (about 3 seconds – see previous discussions) you do not have a problem. The watch dog timer will be reset in the “under the hood operations” – you do not need to know the watch dog even exists.

                If “handle_the_data( )” takes longer than about 3 seconds you may need to sprinkle it with a few yield( ) statements.

                Hope this helps

  2. Excellent article. I too have found documentation fairly light.
    I was having trouble with an ESP8266 set up program so to single step added code to flash an LED and then continuously loop using a while(1); statement – works with Arduino but in this case the LED continuously flashed indicating that the ESP8266 was continuously resetting.
    My internet readings then indicated that the watch dog timer would reset if ever the setup code or the loop code took greater than one second. (The one second may be too short but it indicates the idea.)
    Further reading indicated the function yield( ). This function allows ESP8266 background routines to perform actions – I suspect this would include resetting any watch dog timers.
    To flash the LED my code used the library function delay(mS); – normally delay( ) would block any user code (except for interrupts). Further investigation revealed delay() contained the function yield() – hence in my case using delay( ) as part of my routine to flash the LED would not cause the watch dog to time out.
    However while(1); did cause a problem. By including a yield( ) the issue was solved. That is while(1) { yield( ); } causes the program to loop as desired but still allows the watch dog to be reset in the background. In this case the yield( ) is equivalent to the library method ESP.wdtFeed(); used in your example.
    I hope this information is useful and not just added to the internet chatter.
    JK

    1. Hi!
      Thank you very much for your feedback, I’m very happy to know you found this article useful 🙂
      That was indeed one of the biggest gaps of the ESP8266 which is being worked on in the ESP32, since now there is much more documentation available. Still, I would really like to see much more documentation and examples available since some features are really hard to discover 🙂
      Thank you very much for sharing that information, it will definitely be very useful for others.
      What you mention makes perfect sense since there is plenty of stuff running under the hood and at some points the main code that is executing needs to give CPU time to those routines.
      I would really like to know more about what is done by all those routines, but unfortunately, at least at the time I was more actively working with the ESP8266, what happened under the hood was basically a black box and very few information was known.
      Again, thank you very much for the information and always feel free to share here new findings 🙂
      Best regards,
      Nuno Santos

      1. Following your reply I decided to do some more investigation. I am using a Mini ESP8266 Board from Duinotech – I suspect its the same as a WeMos D1 Mini Lite.
        The board contains a LED on pin D4 (GPIO2). I flash the LED once and once only at the beginning of the setup( ) routine:
        void setup() {
        pinMode(D4, OUTPUT);
        digitalWrite(D4,LOW); //LED active low
        digitalWrite(D4,HIGH);
        //delay(10000); //no problem
        // delayJK(10000); //a problem
        while(1) yield( );
        }
        Without the yield( ) the program continually exits the while(1) loop, resets itself and the flashes the LED. – While the flash is visible I used a logic analyser to measure the time between flashes as 3.2 seconds.
        Adding the yield( ) statement eliminates the flashing – ie the ESP8266 does not reset so I conclude the wdt does not time out.
        I added a 10 second delay which I have called delayJK( ).
        void delayJK(long wait){
        long start = millis();
        while (wait > (millis( ) – start))
        yield( ); //eliminates problem
        }
        Without the yield the LED flashes every 3 seconds as before. Adding a yield( ) and the processor does not reset. (LED does not flash – wdt does not time out)
        Testing with the library delay( ) routine did not cause the processor to reset. The library routine contains a yield( );
        These comments are just a little more detail on my previous but I have added the measurement of 3.2 seconds. I guess the conclusion is if your setup( ) or loop( ) routines are longer than 3 seconds be alert for unexpected resets due to the wdt timing out!
        JK

        1. Thank you very much for the additional information 🙂
          It’s very useful to know how much time to expect before the watchdog fires.
          Did you test it with both the Hardware and Software watchdogs enabled?
          Supposedly from the arduino core code comments, the hardware watchdog should trigger after around 6 seconds in case the software one is disabled:
          https://github.com/esp8266/Arduino/blob/4897e0006b5b0123a2fa31f67b14a3fff65ce561/cores/esp8266/Esp.cpp#L97
          At the time I’ve been testing this, I found that it was possible to disable the software watchdog, but did not find any way of disabling the hardware watchdog.
          It would also be nice if we could configure these timings for the hardware one. It is possible to configure it for the software watchdog, but I did not find any function for the hardware.
          I’ve been doing a lot of testing on the ESP32 but I haven’t yet dedicated any time to check how the watchdogs are working there.
          Hopefully they have improved and clarified how things operate, although I’ml curious how it works with the two cores of the ESP32.
          Need to find some time to look into it 🙂
          Thanks again for the info!
          Best regards,
          Nuno Santos

          1. Hi Nuno
            I modified my test code to investigate the hardware timeout:
            void setup() {
            ESP.wdtDisable( ); //new line to disable software watch dog
            pinMode(D4, OUTPUT);
            digitalWrite(D4,LOW); //LED active low
            digitalWrite(D4,HIGH);
            while(1);
            }
            Using a logic analyser I observed the LED to flash every 8.44 seconds so in summary with my system:
            By default the software watch dog timed out after 3.2 seconds (previous post)
            With the S/W wdt disabled the hardware watch dog timed out after 8.44 sec.
            The conclusion is as before – if your program spends up to 3 seconds in the setup( ) or loop( ) functions be aware that the watchdog timers may generate a reset.
            JK

          2. I did another test:
            Following reset my understanding is that the ESP8266 comes up in station mode and looks for the last access point to which was attached. If it cannot find that it comes up as an access point. In the the discussion below I would call these “under the hood” WiFi operations.
            In my experiment without the yield( ) function the WDT timed out. The program was continually resetting. In this situation my PC did not detect an AP.
            When the yield( ) function is included the WDT does not time out. My PC then detects an AP “ESP_1D9BAF”.
            My conclusion is that with the yield( ) function the ESP8266 is able to run in the background the necessary “under the hood” WiFi functions whereas without the yield( ) the “under the hood” WiFi functions are blocked.
            So with the yield( ) the WDT is continually reset and the WiFi functions (the radio part) continue to function. (I can attach my PC to the ESP8266 but will then need a user program to do anything useful).
            There maybe other “under the hood” operations.
            JK

  3. So which should be used? For example I wish to make sure an Esp8266 with a dht22 sensor reboot if it hangs and doesn’t post data to server regularly.

    Should I use the software or hardware timer?

    1. Hi!

      To be honest I’m not sure if there’s a “best” one to use, and the watchdog is there to reset if your program hangs.

      So, instead of using the watchdog, I would probably use the software reset feature:
      https://techtutorialsx.com/2017/12/29/esp8266-arduino-software-restart/

      That way, you have more control about when you want the ESP to reset. So, the watchdog would just be running in the background and ensure that if everything else fails, it will reset the ESP.

      Best regards,
      Nuno Santos

  4. So which should be used? For example I wish to make sure an Esp8266 with a dht22 sensor reboot if it hangs and doesn’t post data to server regularly.
    Should I use the software or hardware timer?

    1. Hi!
      To be honest I’m not sure if there’s a “best” one to use, and the watchdog is there to reset if your program hangs.
      So, instead of using the watchdog, I would probably use the software reset feature:
      https://techtutorialsx.com/2017/12/29/esp8266-arduino-software-restart/
      That way, you have more control about when you want the ESP to reset. So, the watchdog would just be running in the background and ensure that if everything else fails, it will reset the ESP.
      Best regards,
      Nuno Santos

Leave a Reply