/*
HOW TO RESET AN ARDUUINO USING CODE: HARDWARE RESET
By: TheGeekPub.com
More Arduino Tutorials: https://www.thegeekpub.com/arduino-tutorials/
*/
// https://www.instructables.com/two-ways-to-reset-arduino-in-software/
// https://www.mysensors.org/apidocs/group__avr__watchdog.html
/*
int ResetPin = 4;
void setup() {
digitalWrite(ResetPin, HIGH); // Set digital pin to 5V
pinMode(ResetPin, OUTPUT); // Set the digital pin to an OUTPUT pin
Serial.begin(115200);
while(!Serial);
Serial.println("Arduino Nano Ready");
}
void loop() {
// A little fun countdown! 3..2..1
Serial.print("3... ");
delay(1000);
Serial.print("2... ");
delay(1000);
Serial.print("1... ");
delay(1000);
Serial.println("We are now resetting Arduino programmatically");
Serial.println();
delay(1000);
digitalWrite(ResetPin, LOW); // This command grouunds the reset pin and reboots the Arduino
Serial.println("If it worked, the Arduino will never output this line!");
}
*/
#include <avr/wdt.h> //should be in any adruino IDE
// https://passionelectronique.fr/watchdog-arduino/
// WDTO_15MS 16ms
// WDTO_30MS 32ms
// WDTO_60MS 64ms
// WDTO_120MS 128ms
// WDTO_250MS 256ms
// WDTO_500MS 512ms
// WDTO_1S 1,024s
// WDTO_2S 2,048s
// WDTO_4S 4,096s
// WDTO_8S
void setup() {
wdt_disable(); //always good to disable it, if it was left 'on' or you need init time
//do some stuff here
Serial.begin(115200);
while (!Serial);
if (bitRead(MCUSR, WDRF)) {
Serial.println("System was reset due to watchdog timeout!");
}
Serial.println("Arduino Nano Ready");
wdt_enable(WDTO_8S); //enable it, and set it to 8s
wdt_reset();
}
void loop() {
//do some stuff here
if (Serial.available() && Serial.read() == 'r') {
char wdtString[4];
uint16_t wdtDelay;
if (Serial.available()) {
int bytesRead = Serial.readBytes(wdtString, 3);
wdtString[bytesRead] = '\0'; // Null-terminate the string
wdtDelay = atoi(wdtString);
Serial.print("Received: r");
Serial.println(wdtDelay);
}
wdt_overflow(wdtDelay);
}
wdt_delay(5000); //instead of delay, i made my own delay to reset the WDT
}
//this makes sure the WDT is reset immediately when entering the
//function, but we can still benefit from a real 'delay'.
//upon leaving the function, we reset it again.
//i realize timing will be loose, you can always do something with
//millies() if you need strict timing.
//you might also need to adjust the '1000' if you WDT is shorter
void wdt_delay(unsigned long msec) {
wdt_reset();
while (msec > 1000) {
wdt_reset();
delay(1000);
msec -= 1000;
Serial.print(msec / 1000);
Serial.print("... ");
}
delay(msec);
Serial.println("0");
wdt_reset();
}
//to reload the board, you only have to delay > WDT
//another option is to set the WDT very short, and do a short delay
void wdt_overflow(uint16_t wdtDelay) {
Serial.println("Reseting Now!");
Serial.println();
Serial.flush();
wdt_enable(WDTO_15MS); //enable WDT, and set it to 15ms
wdt_reset();
// delay(8001);
delay(wdtDelay); // while(true); should be safer
Serial.println("Didn't work!!!");
wdt_enable(WDTO_8S); //enable WDT, and set it to 8s
}