Some notes on the Arduino Watchdog Latest change 2017-02-09
In short:void setup()
{
WDwakeUps = EEPROM.read(12);
if((MCUSR & 0x08) == 0x08) // we woke up from watchdog reset
{
EEPROM.write(12, ++WDwakeUps);
MCUSR &= ~0x08; // clear the WDRF flag
}
#ifdef USEWATCHDOG
cli(); // disable interrupts
WDTCSR = 0x18; // Start timed sequence to change watchdog timeout
WDTCSR = 0x29; // Enable watchdog for system reset after 8 seconds not kicked
sei(); // re-enable interrupts
#endif
// other setup...
}Now the watchdog reset worked fine but the check for waking up from watchdog reset did not, bit 3 in MCUSR was always zero.
Later I found out that in most? many? all? bootloaders this bit is inspected and if set, the wait time for expecting a new download is skipped. This surely makes sense, but the register is cleared too and that prevented my application to find out if it started from a watchdog reset.
And I did not want to dive into modifying the bootloader. What to do?
Well, the watchdog circuit can also give a special interrupt. In that interrupt I increment WDwakeUps in EEPROM and then do a system reset.
ISR(WDT_vect) // Watchdog interrupt handler
{
EEPROM.write(12, ++WDwakeUps);
__asm__ ("jmp 0"); // jump to the reset start address.
}
// other setup...
}
Resetting the Arduino from your program:
ISR(WDT_vect) // Watchdog interrupt handler
{
EEPROM.write(12, ++WDwakeUps);
PORTC = 0;
DDRC = 0x04; // make pin D2 an output so it pulls the reset pin low.
}