/*
Watchdog Timer Demonstration
Arduino Uno / Nano (ATmega328P)
LED blinks normally.
Every 15 seconds the program intentionally locks up.
The watchdog resets the MCU after 2 seconds.
Demonstrates:
- Enabling the watchdog
- Resetting ("kicking") the watchdog
- Detecting watchdog resets
- Recovering from software hangs
*/
#include <avr/wdt.h>
#include <avr/io.h>
const byte LED_PIN = 13;
unsigned long startTime;
bool watchdogResetOccurred = false;
void checkResetCause()
{
byte resetFlags = MCUSR;
watchdogResetOccurred = resetFlags & (1 << WDRF);
// Clear reset flags
MCUSR = 0;
// Disable watchdog after reset
wdt_disable();
}
void setup()
{
checkResetCause();
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
Serial.println();
Serial.println("Watchdog Timer Demo");
if (watchdogResetOccurred)
{
Serial.println("*** Previous reset caused by WATCHDOG ***");
}
else
{
Serial.println("Normal power-on reset");
}
// Enable watchdog with 2-second timeout
wdt_enable(WDTO_2S);
startTime = millis();
}
void loop()
{
static unsigned long lastBlink = 0;
// Feed watchdog
wdt_reset();
// Blink LED every second
if (millis() - lastBlink >= 1000)
{
lastBlink = millis();
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
Serial.print("Running for ");
Serial.print(millis() / 1000);
Serial.println(" seconds");
}
// Simulate a software lockup after 15 seconds
if (millis() - startTime > 15000)
{
Serial.println();
Serial.println("*** Simulating software hang ***");
Serial.println("*** Watchdog should reset MCU in ~2 seconds ***");
while (true)
{
// Intentionally do nothing
// No wdt_reset() calls
}
}
}