Has anyone tried software reset of an Arduino?
-
I'm doing some research on how to reset an Arduino from within a Sketch. My first choice would be to do this without connecting a wire to the reset pin.
Here is an example. But I've read that it's not always the best way to perform a rest. I gues I have to try if the NFR accepts it ;-)
-
I'm doing some research on how to reset an Arduino from within a Sketch. My first choice would be to do this without connecting a wire to the reset pin.
Here is an example. But I've read that it's not always the best way to perform a rest. I gues I have to try if the NFR accepts it ;-)
I used it in a test sketch.
void(* resetFunc) (void) = 0; //declare reset function @ address 0 void loop() { if ( Serial.available() ) { // read the incoming byte: char incomingByte = Serial.read(); // say what you got: Serial.print("I received: "); Serial.println(incomingByte, DEC ); if ( incomingByte == 115 ) { Serial.println( "Resetting??" ); gw.wait(50 ); // give serial some time to complete it's printing resetFunc(); //call reset } } gw.process(); }And the Serial output is:
Resetting?? send: 17-17-0-0 s=255,c=3,t=15,pt=2,l=2,sg=0,st=ok:0 send: 17-17-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.4 send: 17-17-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0 read: 0-0-17 s=255,c=3,t=6,pt=0,l=1,sg=0:M sensor started, id=17, parent=0, distance=1So on my Uno it seems to wok fine. Looks promissing
-
I used it in a test sketch.
void(* resetFunc) (void) = 0; //declare reset function @ address 0 void loop() { if ( Serial.available() ) { // read the incoming byte: char incomingByte = Serial.read(); // say what you got: Serial.print("I received: "); Serial.println(incomingByte, DEC ); if ( incomingByte == 115 ) { Serial.println( "Resetting??" ); gw.wait(50 ); // give serial some time to complete it's printing resetFunc(); //call reset } } gw.process(); }And the Serial output is:
Resetting?? send: 17-17-0-0 s=255,c=3,t=15,pt=2,l=2,sg=0,st=ok:0 send: 17-17-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.4 send: 17-17-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0 read: 0-0-17 s=255,c=3,t=6,pt=0,l=1,sg=0:M sensor started, id=17, parent=0, distance=1So on my Uno it seems to wok fine. Looks promissing
-
@TheoL another way to reset is to enable the watchdog, but don't kick it. When it times out, it will reset the avr.
Have to look up an example if you want. -
@Yveaux Thank you for your quick reply. Don't ask why, but I need to be able to reset a node by sending a message to it ;-). It's desired functionality not because of hardware problems.
-
-
@Yveaux That would be awesome. Saves me from code that might not be cross Arduino compatible. As I read somewhere during my research.
-
@tekka Thank you. Not yet sure how to do that. If you have an example for that I would be much obliged. Otherwise I'll spend some time on that later on. Either way, thanx again.
Edited: Found it will update this answer later on with code
Edit 2. My test didn't work, but I will try again tomorrow
-
@TheoL another way to reset is to enable the watchdog, but don't kick it. When it times out, it will reset the avr.
Have to look up an example if you want.@Yveaux
Watchdog is used by sleep() function in mysensors, so it is not possible to use it. Also it is not safe to use it on arduino boards with standard bootloader. If I need watchdog on standard arduino boards (without mysensors library) with standard bootloader I use next ISR to handle WDT interrupt// Watchdog Timer interrupt service routine. This routine is required // to allow automatic WDIF and WDIE bit clearance in hardware. ISR (WDT_vect) { // WDIE & WDIF is cleared in hardware upon entering this ISR wdt_disable(); asm volatile (" jmp 0"); }This ISR prevents bootloop.
If I need just soft reset arduino I use the technique very similar to TheoL'sasm volatile (" jmp 0"); //call anywhere -
@Yveaux
Watchdog is used by sleep() function in mysensors, so it is not possible to use it. Also it is not safe to use it on arduino boards with standard bootloader. If I need watchdog on standard arduino boards (without mysensors library) with standard bootloader I use next ISR to handle WDT interrupt// Watchdog Timer interrupt service routine. This routine is required // to allow automatic WDIF and WDIE bit clearance in hardware. ISR (WDT_vect) { // WDIE & WDIF is cleared in hardware upon entering this ISR wdt_disable(); asm volatile (" jmp 0"); }This ISR prevents bootloop.
If I need just soft reset arduino I use the technique very similar to TheoL'sasm volatile (" jmp 0"); //call anywhere -
@TheoL
In general - no. Only for such tricks :) Of course these tricks are not invented by me. -
@Yveaux
Watchdog is used by sleep() function in mysensors, so it is not possible to use it. Also it is not safe to use it on arduino boards with standard bootloader. If I need watchdog on standard arduino boards (without mysensors library) with standard bootloader I use next ISR to handle WDT interrupt// Watchdog Timer interrupt service routine. This routine is required // to allow automatic WDIF and WDIE bit clearance in hardware. ISR (WDT_vect) { // WDIE & WDIF is cleared in hardware upon entering this ISR wdt_disable(); asm volatile (" jmp 0"); }This ISR prevents bootloop.
If I need just soft reset arduino I use the technique very similar to TheoL'sasm volatile (" jmp 0"); //call anywhere@Koresh said:
Watchdog is used by sleep() function in mysensors, so it is not possible to use it.
Not sure what you are referring to, sleep() uses WDIE (wdt interrupt before reset, see here) whereas the reboot functionality is implemented via wdt reset (see here).
Also it is not safe to use it on arduino boards with standard bootloader.
Can you elaborate why?
-
@Koresh @TheoL i use wdt with mysensors..but i cheated a bit :)
- you can use your own sleep and then handle wdt, but then careful if really need mysensors sleep(x ms) as it resets wdt.
- or as i do too, i have added a weak empty function in mysensors lib to have isr wdt available from sketch ;), temporarily I will submit a pr for the few features i have added locally..
-
@Koresh said:
Watchdog is used by sleep() function in mysensors, so it is not possible to use it.
Not sure what you are referring to, sleep() uses WDIE (wdt interrupt before reset, see here) whereas the reboot functionality is implemented via wdt reset (see here).
Also it is not safe to use it on arduino boards with standard bootloader.
Can you elaborate why?
@tekka
Standard bootloader can fail to switch off wdt after reboot (on the boards with most chips) and it will cause bootloop. After rebooting watchog is still working and it is very important to disable it. We can use modified bootloader or bootloader like optiboot. -
@tekka I am not sure I will let answer, but if i remember well it was related to a problem that some old bootloader version were not handling properly wdt irq resulting in bootloader loop.
ISR (WDT_vect) is used by mysensors lib if using mysensors sleep.
but you can do something like:
in MyHwATMega328.hvoid MY_WDT_Callback() __attribute__((weak));in MyHwATMega328.cpp, just add this in the wdt isr function
if (MY_WDT_Callback) MY_WDT_Callback();and finally in your sketch you can use MY_WDT_Callback() which will be fired at every wdt irq. Something like
void MY_WDT_Callback() { wdt_reset(); // or do what you want irqWdt = true; }maybe there are better ways. another note, is I don't advice to do too much change locally without pr because then..arrghh :pensive: :scream:
-
I when you thought you finally knew a bit about the Arduino, there comes a topic like this ;-) Thanx to you all. I understand to I have still much to learn.
-
Hi, as I remember about watchdog is to set it to 8S, so there is enough time to upload an sketch (8 seconds) before the Arduino will reboot. WDT0_time_in_seconds. If using WDT08S Always call the wdt_reset() no later than 7 seconds to avoid reset/reboot. This is usually used in case that the Arduino/avr is "hanging" in an infinite loop and stopped responding to actions, then this will automatically reset/reboot
Include this in your sketch:
#include <avr/wdt.h>setup ();{
// WDTO_1S
// WDTO_2S
// WDTO_4S
// WDTO_8S
wdt_enable(WDTO_8S);
}loop (){
wdt_reset(); // You must call this within less seconds set as WDT0_8S
} -
Hey Buddy,
[spam post removed by moderator]