Un watchdog hardware que mantiene vivo un PLC ESP32 desatendido
esp_task_wdt durante 20 segundos, el PLC se reinicia solo y la máquina vuelve a estar operativa antes de que nadie suba a reiniciar un armario eléctrico.Tres líneas para volverse autorreparable
esp_task_wdt_init(20, true) arma el watchdog, esp_task_wdt_add(NULL) suscribe la tarea actual y un único esp_task_wdt_reset() al principio de cada iteración del loop lo alimenta. El flag true es el que importa: provoca un panic y un reinicio completo en lugar de limitarse a imprimir un aviso por un puerto serie que nadie está mirando. Elige un timeout holgadamente por encima de tu operación bloqueante legítima más larga, como escrituras en flash o reconexiones BLE.Saber por qué te has reiniciado
esp_reset_reason() y, cuando la causa fue el task watchdog, incrementa un contador persistente en NVS — el mismo patrón de Preferences usado para los contadores de ciclos de la máquina. Un contador de watchdog que crece en campo es tu alerta temprana de que algún camino del código necesita un arreglo antes de convertirse en una llamada a soporte.Demuestra que funciona antes de entregar
Un fragmento de la implementación
Tal cual del ejemplo desplegado en el ESP32 PLC 38R — cópialo libremente:
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");
}El ejemplo completo es un programa entero — cabecera de conexionado, setup y bucle principal — listo para adaptar a tu aplicación.
Preguntas frecuentes
¿Qué timeout de watchdog debo elegir?
Varias veces más largo que tu peor iteración legítima del loop, incluyendo escrituras en flash y operaciones BLE. Los 20 segundos usados aquí son conservadores para un controlador de máquina cuyo loop normalmente gira en milisegundos.
¿Protege el watchdog contra cualquier tipo de fallo?
No. Atrapa cuelgues software de la tarea monitorizada, no bugs de lógica que mantienen el loop girando, ni fallos de hardware. Combínalo con la detección de brownout, valores por defecto seguros en las salidas al arrancar y el registro del motivo de reset que se muestra aquí.
¿Vuelven las salidas a un estado seguro tras un reinicio por watchdog?
Sí, al reiniciar todos los GPIO vuelven a su estado por defecto y tu setup() se ejecuta de nuevo, así que diseña setup() para arrancar con todas las salidas de válvulas y motores apagadas — exactamente lo que hace la máquina de estados de válvulas de esta serie.