
UPDATE (06/12/2019): After quite a bit of testing it seems like the good old and tested wire connected to the reset pin does the job amazingly well. You can safely ignore my relay idea despite how much fun it would actually be (the cost outweighs the benefits). I will write a short post with a demo showing the difference between "hard" and soft reset.
This is for anyone who is serious about keeping their project(s) running 24/7/365 on the Arduino platform. Part 1 is going to cover the watchdog capabilities and use case scenarios. Most of the ideas I found on google are quite old, repetitive and not original (personal opinion). So I have decided to take some of those ideas and spiced them up a notch (and make some up myself as well). Before we dive any deeper below is a source code that will be used as a base sketch for all of the examples:
#include <avr/wdt.h> unsigned long time; // When watchdog kicks in it will run whatever is in here + do a normal watchdog reset ISR(WDT_vect) { } void setup() { cli(); // disable all interrupts wdt_reset(); // reset the WDT timer MCUSR &= ~(1<<WDRF); // Enter Watchdog Configuration mode: WDTCSR = (1<<WDCE) | (1<<WDE); // Set Watchdog settings: interrupt enable, 8 second timeout ! // To enable an interrupt and reset mode just add this " | (1<<WDE) " WDTCSR = (1<<WDIE) | 1<<WDP0 | 1<<WDP3 | (1<<WDE); sei(); Serial.begin(9600); Serial.println("Finished watchdog setup"); // just here for testing } // the loop routine runs over and over again forever: void loop() { Serial.print("Time: "); time = millis(); Serial.println(time); //prints time since program started delay(1000); // wait a second so as not to send massive amounts of data }
#include <avr/wdt.h> int resetPin = 12; unsigned long time; // When watchdog kicks in it will run whatever is in here + do a normal watchdog reset ISR(WDT_vect) { digitalWrite(resetPin, LOW); // hit the reset pin hard ! } void setup() { digitalWrite(resetPin, HIGH); // so we don't end up in an ever lasting loop pinMode(resetPin, OUTPUT); cli(); // disable all interrupts wdt_reset(); // reset the WDT timer MCUSR &= ~(1<<WDRF); // Enter Watchdog Configuration mode: WDTCSR = (1<<WDCE) | (1<<WDE); // Set Watchdog settings: interrupt enable, 8 second timeout ! // To enable an interrupt and reset mode just add this " | (1<<WDE) " WDTCSR = (1<<WDIE) | 1<<WDP0 | 1<<WDP3 | (1<<WDE); sei(); Serial.begin(9600); Serial.println("Finished watchdog setup"); // just here for testing } // the loop routine runs over and over again forever: void loop() { Serial.print("Time: "); time = millis(); Serial.println(time); //prints time since program started delay(1000); // wait a second so as not to send massive amounts of data }

#include <avr/wdt.h> unsigned long time; int Pin8 = 8; // When watchdog kicks it will run whatever is in here + do a // normal watchdog reset just to be sure ISR(WDT_vect) { digitalWrite(Pin8, HIGH); // so we don't end up in an ever lasting loop } void setup() { digitalWrite(Pin8, LOW); // so we don't end up in an ever lasting loop pinMode(Pin8, OUTPUT); // sets the digital pin 13 as output pinMode(LED_BUILTIN, OUTPUT); for (int x = 0; x <= 2; x++) { digitalWrite(LED_BUILTIN, HIGH); // on delay(1500); digitalWrite(LED_BUILTIN, LOW); // off delay(1500); } cli(); // disable all interrupts wdt_reset(); // reset the WDT timer MCUSR &= ~(1<<WDRF); // Enter Watchdog Configuration mode: WDTCSR = (1<<WDCE) | (1<<WDE); // Set Watchdog settings: interrupt enable, 8 second timeout ! // To enable an interrupt and reset mode just add this " | (1<<WDE) " WDTCSR = (1<<WDIE) | 1<<WDP0 | 1<<WDP3 | (1<<WDE); sei(); Serial.begin(9600); Serial.println("Finished watchdog setup"); // just here for testing } // the loop routine runs over and over again forever: void loop() { digitalWrite(LED_BUILTIN, HIGH); // on delay(100); digitalWrite(LED_BUILTIN, LOW); // off delay(100); Serial.print("Time: "); time = millis(); Serial.println(time); //prints time since program started delay(1000); // wait a second so as not to send massive amounts of data }
