Arduino Reset via Software

Dear Arduino Forum ,
Dear Stack Exchanger's,

I want to reset my Arduino and system in every 24h for preventing frozen software and also other connectivity stuffs.

I wrote a program which connects a digital pin to reset pin of Arduino and I want to reset with that way.

I have tried the watchdog timer but I cannot do it for 24 hours.
Because the WDT is working in 8secs max.
Could you help me with how can I reset via watchdog in 24 hours or If you have another solution for reset in 24h please tell me and send me the related article/book/link etc. I will check and implement into my code.

same question

1 Like

That is what a watch dog is for. The fact you can only get 8 seconds is irrelevant.
You should kick the watchdog every times round in the loop function.

Then use the millis timer to detect when you have 24 hours since the last reset, then simply call a delay for just over the time you need to set the watch dog to. The lack of kicking will trigger it.

1 Like

I see you've already had some answers on StackExchange.

I've done something very similar [AVR architecture] which I've adapted here:

void forceSystemReset() {
	//see http://www.embedds.com/using-watchdog-timer-in-your-projects/
	cli();
	wdt_reset();
	MCUSR = 0;                           // allow changes, disable reset
	WDTCSR = (1 << WDCE) | (1 << WDE);    //set up WDT interrupt
	WDTCSR = (1 << WDE) | (1 << WDP2);   //Start watchdog timer with 0.25s prescaler
	sei();
	delay( 2000 ) ;  // force WDT to reset system
}


void loop() {
   . . .
   if ( millis() > 86400000UL ) forceSystemReset() ;
   . . .
}
1 Like

why so complicated? why the interrupt?

I agree that there is some scope for optimisation. I got the basis of the solution from the link in the comment and have not given it much more attention in the mean time. It is extracted from a current working project.

It doesn't actually use an interrupt. One reason for some complexity is that it needs to deal with several slight variations in the way various bootloader versions handle the reset.

Here are some additional annotations:

void forceSystemReset() {
	//see http://www.embedds.com/using-watchdog-timer-in-your-projects/
// Manipulating the WDT settings has instruction sequences that "must be completed within 
//  four cycles.  Disable interrupts so that one won't show up at the wrong time.
	cli();
// Make sure that there is no WDT event currently pending
	wdt_reset();
// reset all previous reset causes, which are otherwise "sticky" between resets.
// having MCUSR zero is necessary for the Optiboot to recognize the WDT reset
// as a user request to enter the bootloader, rather than  WDT even caused by the
// bootloader itself (ie after external reset.)
	MCUSR = 0;                           // allow changes, disable reset
// set the WDT to reset the chip (NOT an interrupt as stated in the comment!)
// WDCE is "Change enable"; the thing that must be set less than 4 cycles before
// manipulating other things.
	WDTCSR = (1 << WDCE) | (1 << WDE);    //set up WDT interrupt
// set "system reset mode" and a short timeout.  (why not shorter than 0.25 s?  I dunno.)
	WDTCSR = (1 << WDE) | (1 << WDP2);   //Start watchdog timer with 0.25s prescaler
// re-enable interrupts since we're done wit h the time-critical stuff.  (Why bother?  I dunno.  Probably so delay() will work right.)
	sei();
// Wait for the reset ti actually occur.  Why delay() instead of an infinite loop?  I dunno.
	delay( 2000 ) ;  // force WDT to reset system
}
1 Like

Thanks for clearing that up. If I publish it again, I’ll ensure the comments, which I simply took over from the source, agree with the actual register settings.

@westfw is it not the same as wdt_enable() ?

Yeah, almost. The following would do about the same thing and be cleaner and more portable, probably, (although, "MCUSR" is not that portable. :frowning: ) (although, pretty much hiding what it's doing.)

void forceSystemReset() {
	MCUSR = 0;
	wdt_enable(WDTO_250MS)
	while (1)  ;  // force WDT to reset system
}

I sort-of wish that Arduino would add a "selfReset()" function of some kind to the core. Newer AVRs and most of the ARM chips have a hardware feature to do this, and it could fall back to this WDT technique on older AVRs.

The source of ther WDT functions/macros is here: avr-libc: wdt.h Source File just in case someone finds it interesting.

What I did notice was this in the documentation at avr-libc: <avr/wdt.h>: Watchdog timer handling was this:

What is not clear to me is what the consequences are of having the watch dog timer active after a system reset. I've certainly not come across a code block as suggested, even in code which was intended to run without the presence of a bootloader where, possibly?, some of that is handled.

When there is a reset on the classic AVR chips, the watchdog timer will stay on if either the relevant fuse is set, OR if the watchdog had caused the reset. But the Control register is zeroed, which causes the timeout period to be the minimum possible (about 16ms) If you don't do something else to the watchdog (disable it or change the timeout), the system will be reset again in 16ms.

This is the cause of the "boot loop" with the old ATmegaboot bootloader - if an application enables the watchdog and a WDT occurs, the chip resets, entering the bootloader. The bootloader does nothing with the watchdog, and then prepares to wait ~10s for possible upload commands on the serial port. 16ms into the wait, the watchdog resets the chip again, and this repeats, over and over again. (Even if there ARE upload commands "immediately", it will still take longer than 16ms to upload a sketch, so ... bootloader loop.)

1 Like

OK. Thanks. I didn’t understand that before. That then means that if you dispense with bootloader on say an ATmega328p and use the watchdog timer to reset the system, you have to take care to handle the restart explicitly, say by issuing a wdt_disable() in setup().

Well, presumably if your application uses the WDT, then the code is likely to have both WDT setup code AND wdt_reset() calls that will change things within the 16ms.
The problem with the bootloader is that LONG time of potentially wdt-unaware code executing before you get to the application.

1 Like

Of course that is true, but it is just a matter of being aware of it (to be able to take any necessary precautions) and, in general, to know what survives the various possible types of "system reset" and, indeed, what the bootloader (if present) propagates and what it cleans out. The datasheet is not too explicit on this matter but at least makes clear the IO registers don't survive any type of reset. For example, I just understood today, from another thread, that the pre-scaler would normally survive a WDT reset, however, at least some bootloaders revert that back to default. I actually assumed, until recently, that all the resets were more or less the equivalent of a power fail reset.