22

Is it possible to reset an Arduino (i.e., to reboot it) from code (i.e from the sketch itself)? I know that is possible with a special circuit but is there a chance to make it just with code?

Below is my code and the comment //reset is where I want to force a reset.

#include <TrueRandom.h>

int i;
int randSeed;
long randNumber;

void setup(){
  Serial.begin(9600);
  Serial.println("20 pseudo Zufallszahlen:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println();
  //randomSeed(TrueRandom.random());
  randSeed = analogRead (A0);
  randomSeed(randSeed);
  Serial.print("Der 'seed' Wert: ");
  Serial.println(randSeed);
  Serial.println();
  Serial.println("20 Zufallszahlen mit analogem 'seed' Wert:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println("---------------------------");
  Serial.println();
  delay(500);
  //reset  
}

void loop() {
}

I want to reset the micro-controller at the end of the setup function to show the effect of random numbers with and without a seed.

dda
  • 1,553
  • 1
  • 12
  • 17
kimliv
  • 541
  • 1
  • 4
  • 15

2 Answers2

24

There three ways to accomplish this. (last is my favorite)

1) Jumper an unused IO to the RESET pin. Leave it as INPUT for normal run, As it is externally pulled high. And when desired to reset set it as LOW and Output. (bang its rebooting).

setup() {
  ...
  pinMode(PINtoRESET, INPUT);    // Just to be clear, as default is INPUT. Not really needed.
  digitalWrite(PINtoRESET, LOW); // Prime it, but does not actually set output. 
  ...                            // Does disable 10K pull Up, but who cares.

then when desired...

...
  pinMode(PINtoRESET, OUTPUT);   // lights out. Assuming it is jumper-ed correctly.
  while(1);                      // never gets here.

2) Jump to beginning of the code.

void(* resetFunc) (void) = 0;  // declare reset fuction at address 0
...
resetFunc(); //call reset

But be careful, this does not perform a true reset, in that all the registers ARE NOT DEFAULTED. Rather they and the IO are left as is. Where somethings from the bootloader and then the heap will be initialized. And reset are not!

3) Use the watchdog. The SoftReset library makes it easy. Although it is not difficult to implement directly. Shown below..

#include <avr/wdt.h>
...
setup() {
  ...
  MCUSR = 0;  // clear out any flags of prior resets.
  ...

then when desired...

...
wdt_enable(WDTO_15MS); // turn on the WatchDog and don't stroke it.
for(;;) { 
  // do nothing and wait for the eventual...
} 
...
mpflaga
  • 2,443
  • 11
  • 13
  • 2
    From everything I've read, the first option is not recommended. Options 2 and 3 are fine. – sachleen May 10 '14 at 05:01
  • 2
    @sachleen: Please say more about that (opt-1). – JRobert May 19 '14 at 14:14
  • 2
    Option 1. or a variant can be a clean enough way to do this as long as power on transient conditions are designed for. – Russell McMahon Feb 25 '15 at 12:32
  • @RussellMcMahon - [How does one design for the Power on transient conditions](http://arduino.stackexchange.com/questions/13416/how-does-one-design-for-the-power-on-transient-conditions)? – Greenonline Jul 13 '15 at 15:10
  • 1
    It should be noted that option 2 does not run the bootloader. – Edgar Bonet Aug 13 '16 at 19:57
  • Wouldn't calling `resetFunc()` not reset the stack? So calling it repeatedly would overflow the stack. – Kevin Smyth Aug 19 '16 at 17:15
  • Option 1 is not recommended by the chip designer, Atmel. They do not recommend performing a reset with the chip's pins. – Javier Jan 20 '17 at 19:44
  • 2
    Option 3 works only with bootloaders that have WDT enabled. It puts board into reset loop otherwise. – zgoda Mar 28 '17 at 15:22
  • Option 2 executes the same code that runs when you do a hardware reset or a power-up: the chip always begins at address 0. – SDsolar Dec 15 '17 at 09:55
  • Option 2 should be edited to add the fact that not every chip begins at address `0`. A pointer to the function to be called should be used instead `void(* resetFunc) (void) = &setup;` (in this case setup should be called to begin again, or even main if it makes sense) I just had the case with stm32 where it begins later in the memory. – Dardan Iljazi Dec 26 '19 at 13:12
  • Option 2 is a null pointer assignment of a function pointer that actually points to nothing when calling the function. Calling this is illegal, cause a null pointer exception and without exception handling results in a reboot. That is a dirty trick and unreliable to recommend. For all believers, the pointer is a pointer to a VOLATILE memory location, not a program memory (flash) location. @Dardanboy, calling setup() is not a reset and yes all memory start at location 0 however it could be possible not all lower memory is accessible – Codebeat Jan 31 '20 at 07:50
  • @Codebeat Nope, this is an actual valid memory address in the program flash, where the embedded program begins. – Dmitry Grigoryev Apr 20 '21 at 15:31
  • @DmitryGrigoryev Nope, it is a valid offset you can jump to, not a valid address. Do not confuse these two. – Codebeat Apr 21 '21 at 00:12
  • I'm laughing at the comment, "lights out" — thanks. Wish I had a spare I/O pin. – Eric Nelson May 18 '21 at 18:48
3

In case you have the original Arduino bootloader which you want to execute as a part of the reset, you can do a SW reset by jumping to the bootloader reset address (0x7800 on ATmega328p boards)

void reset() { asm volatile ("jmp 0x7800"); }

The watchdog reset approach will not work because of a bug in the bootloader. Here's a note from ATmega328P Datasheet page 45:

Note: If the watchdog is accidentally enabled, for example by a runaway pointer or brown-out condition, the device will be reset and the watchdog timer will stay enabled. If the code is not set up to handle the watchdog, this might lead to an eternal loop of time-out resets. To avoid this situation, the application software should always clear the watchdog system reset flag (WDRF) and the WDE control bit in the initialization routine, even if the watchdog is not in use.

This is exactly what will happen after a watchdog reset on a system with Arduino bootloader.

Dmitry Grigoryev
  • 1,248
  • 9
  • 30
  • Yes, I have observed the eternal loop of timeouts, while answering the question, "I wonder if the boot loader resets the WDT" Why not just do "jump 0x0" ? – Eric Nelson May 18 '21 at 18:44
  • @EricNelson Jumping to 0x0 will not run the bootloader, which is one of the two major use cases for a software reset. The second use case, resetting the system to a known state, is not possible without a bootloader with WD support or connecting the reset pin to a GPIO. – Dmitry Grigoryev May 19 '21 at 11:16