A hardware watchdog that keeps an unattended ESP32 PLC alive
esp_task_wdt for 20 seconds, the PLC reboots itself and the machine is operational again before anyone climbs up to power-cycle a cabinet.Three lines to become self-healing
esp_task_wdt_init(20, true) arms the watchdog, esp_task_wdt_add(NULL) subscribes the current task, and a single esp_task_wdt_reset() at the top of every loop iteration feeds it. The true flag is the one that matters: it triggers a panic and a full reboot instead of just printing a warning to a serial port nobody is watching. Pick a timeout comfortably above your longest legitimate blocking operation, such as flash writes or BLE reconnections.Know why you rebooted
esp_reset_reason() and, when the cause was the task watchdog, increments a persistent counter in NVS — the same Preferences pattern used for the machine's cycle counters. A rising watchdog count in the field is your early warning that some code path needs fixing before it becomes a support call.Prove it works before you ship
A snippet from the implementation
Straight from the example as deployed on the ESP32 PLC 38R — copy it freely:
void setup() {
Serial.begin(115200);
pinMode(BTN_HANG, INPUT);
pinMode(LED_ALIVE, OUTPUT);
// 1. Diagnostics: why did we boot?
esp_reset_reason_t reason = esp_reset_reason();
Serial.print("Reason of the last reboot: ");
Serial.println(resetReasonText(reason));
// 2. Persistent counter of watchdog reboots (NVS pattern)
prefs.begin("nvdata", false);
wdtResets = prefs.getInt("wdt_resets", 0);
if (reason == ESP_RST_TASK_WDT) {
wdtResets++;
prefs.putInt("wdt_resets", wdtResets);
}
prefs.end();
Serial.println("Accumulated watchdog reboots: " + String(wdtResets));
// 3. Arm the watchdog: 20 s and panic=true (reboots instead of just warning)
esp_task_wdt_init(WDT_TIMEOUT, true);
esp_task_wdt_add(NULL); // watches the current task (loop)
Serial.println("Watchdog armed: " + String(WDT_TIMEOUT) + " s");
}The full example is a complete program — wiring header, setup and main loop — ready to adapt to your application.
Frequently asked questions
What watchdog timeout should I choose?
Several times longer than your worst-case legitimate loop iteration, including flash writes and BLE operations. The 20 seconds used here is conservative for a machine controller whose loop normally turns in milliseconds.
Does the watchdog protect against every kind of failure?
No. It catches software hangs of the monitored task, not logic bugs that keep the loop spinning, nor hardware faults. Combine it with brownout detection, sane output defaults on boot and the reset-reason logging shown here.
Do outputs reset to a safe state after a watchdog reboot?
Yes, on reboot all GPIO return to their default state and your setup() runs again, so design setup() to start with every valve and motor output off — exactly what the valve state machine in this series does.