Arduino Electronics ESP32 Tutorials

How to enable hardware WDT on ESP32 using Arduino IDE

Watchdog timer (WDT) is an important feature for hardware devices like ESP32 or Arduino that need to auto recover from all kind of unexpected failures. On a previous post I wrote about how WDT works and how to set WDT on a Raspberry Pi, to make sure it stays up and running 24/7.

If we look at the esp-idf documentation about ESP32 WDT we can see that ESP32 comes with an interrupt watchdog and a task watchdog timer api. What many people are looking for is the task watchdog timer and I will show you in this article how to implement it using Arduino IDE. 

Implementing ESP32 hardware watchdog timer using Arduino IDE

On ESP32, many people implement manually some sort of watchdog timer using flags and loops. This is NOT how it should be done, especially since ESP32 comes with a hardware watchdog timer.

This code shows you how to properly implement WDT on ESP32 using Arduino IDE: 

#include <esp_task_wdt.h>

//3 seconds WDT
#define WDT_TIMEOUT 3

void setup() {
  Serial.begin(115200);
  Serial.println("Configuring WDT...");
  esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
  esp_task_wdt_add(NULL); //add current thread to WDT watch

}

int i = 0;
int last = millis();

void loop() {
  // resetting WDT every 2s, 5 times only
  if (millis() - last >= 2000 && i < 5) {
      Serial.println("Resetting WDT...");
      esp_task_wdt_reset();
      last = millis();
      i++;
      if (i == 5) {
        Serial.println("Stopping WDT reset. CPU should reboot in 3s");
      }
  }
}

Now let’s look at the code. First of all you need to include the esp_task_wdt.h header. This should be available if you have properly installed arduino-esp32.

In the setup block we need to call two functions: esp_task_wdt_init(uint32_t timeoutSeconds, bool panic) and esp_task_wdt_add(TaskHandle_t handle).

  • esp_task_wdt_init is used to initialise WDT with a timeout of timeoutSeconds and with a panic mode set. If panic is set to true, when WDT times out, it will throw a hardware panic and reboot.
  • esp_task_wdt_add is used to add a task to WDT. If handle is NULL, the current task is used. 

Now, the watchdog timer need to be reset BEFORE it times out! This is done with esp_task_wdt_reset() executed in the current task. 

You can see that in this example I am initialising the WDT with a timeout of 3 seconds and then inn the main loop I am resetting it every 2 seconds. After five resets, I stop the reset call and let it timeout. As expected, it reboots my ESP32 after 3 seconds.  

13:01:49.965 -> Configuring WDT...
13:01:51.919 -> Resetting WDT...
13:01:53.918 -> Resetting WDT...
13:01:55.916 -> Resetting WDT...
13:01:57.917 -> Resetting WDT...
13:01:59.915 -> Resetting WDT...
13:01:59.915 -> Stopping WDT reset. CPU should reboot in 3s
13:02:02.917 -> E (26113) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
13:02:02.917 -> E (26113) task_wdt:  - loopTask (CPU 1)
13:02:02.951 -> E (26113) task_wdt: Tasks currently running:
13:02:02.951 -> E (26113) task_wdt: CPU 0: IDLE0
13:02:02.951 -> E (26113) task_wdt: CPU 1: loopTask
13:02:02.951 -> E (26113) task_wdt: Aborting.
13:02:02.951 -> abort() was called at PC 0x400d35b3 on core 0
13:02:02.951 -> 
13:02:02.951 -> Backtrace: 0x4008b560:0x3ffbe170 0x4008b78d:0x3ffbe190 0x400d35b3:0x3ffbe1b0 0x400845ed:0x3ffbe1d0 0x400e8f07:0x3ffbbff0 0x400d3d43:0x3ffbc010 0x40089706:0x3ffbc030 0x40088215:0x3ffbc050
13:02:03.008 -> 
13:02:03.008 -> Rebooting...

I hope this example helps you keep your ESP32 connected to WiFi and internet all the time and prevent it from being stuck. 

13 thoughts on “How to enable hardware WDT on ESP32 using Arduino IDE”

  1. Thanks, this is a great solution – thank you for sharing.

    This is a good idea for remote projects that are not easy to get to. I am building a LoRa ESP32 based weather station and this will provide stability in the case of any issues

  2. Hi !! thanks for this nice and simple howto code!
    Would it be possible to add a way to disable properly the watchdog (after enabling it as per your example) ? for example right before going to deepsleep.

  3. The TWDT can be initialized by calling esp_task_wdt_init() which will configure the hardware timer. A task can then subscribe to the TWDT using esp_task_wdt_add() in order to be watched. Each subscribed task must periodically call esp_task_wdt_reset() to reset the TWDT. Failure by any subscribed tasks to periodically call esp_task_wdt_reset() indicates that one or more tasks have been starved of CPU time or are stuck in a loop somewhere.

    A watched task can be unsubscribed from the TWDT using esp_task_wdt_delete(). A task that has been unsubscribed should no longer call esp_task_wdt_reset(). Once all tasks have unsubscribed form the TWDT, the TWDT can be deinitialized by calling esp_task_wdt_deinit().

Leave a Reply