Resetting an Arduino via Software

Hello, From researching, I have found that many people wish to know how to reset an Arduino Microcontroller through software rather than having to push the reset button on board, and that it is very difficult in doing it. With a few Arduino Microcontrollers (Arduino Nano) that I own, they actually do it very well as I only have to set the pin low from another digital pin. But in one of my projects (with an Arduino Due) that relies on resetting it when needed and that one just wouldn't do nothing when I just set the reset pin LOW.

A thing to Note: Note that, when setting up for your own projects, that I am making a direct connection from a digital pin to the reset pin without any resistors or anything attached to the wire.

How to do it: Most of us will know that to reset an Arduino there needs to be a switch attached to ground, which makes the Reset pin go LOW and the Arduino reset. And as I've said before, with some Arduino Controllers this works. Simple. Here's an example:

#define resetPin 12       //This is connected DIRECTLY to the Reset pin on the Arduino.
#define LED 3             //For the Positive pin of the LED,
#define LEDnegative 2     //For the Negative pin of the LED.

void setup()
{
  pinMode(LED, OUTPUT);               //Must be set as an OUTPUT to send full power to LED,
  pinMode(LEDnegative, OUTPUT);       //Must be set as an OUTPUT to allow direct connection to Ground (or Negative),
  digitalWrite(LEDnegative, LOW);     //"Attaches" the Negative pin on the LED to ground.

  //This is a mini blinking sequence, (just for quick demonstration), to show the state of the Arduino and that the SETUP has worked:
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  //(shouldn't take too long...)
}

void loop()
{
  digitalWrite(13, HIGH);           //Turning on the debug LED to show that the Main Loop has started.
  digitalWrite(LED, HIGH);          //And the LED's are on to show us whether anything actually happens
  delay(1000);                      //So we can see the LED's are on.
  
  //--------------------------------THE RESET------------------------------------//
  pinMode(resetPin, OUTPUT);        //This "Activates" pin 12,
  delay(250);                       //To allow each mode to change
  digitalWrite(resetPin, LOW);      //Puts the Reset pin LOW (as it needs),
  
}

But for more complex boards like the Arduino Due, I had to add an extra line at the end of the Loop:

pinMode(resetPin, INPUT);

On a Due, as I found out, the Reset pin has to be "Disconnected" in some way before the board would reset. And changing the "pinMode()" of the "resetPin" I found was the best way to do it without having to physically remove the wire from the reset pin. After adding it it'll look like this:

#define resetPin 12       //This is connected DIRECTLY to the Reset pin on the Arduino.
#define LED 3             //For the Positive pin of the LED,
#define LEDnegative 2     //For the Negative pin of the LED.

void setup()
{
  pinMode(LED, OUTPUT);               //Must be set as an OUTPUT to send full power to LED,
  pinMode(LEDnegative, OUTPUT);       //Must be set as an OUTPUT to allow direct connection to Ground (or Negative),
  digitalWrite(LEDnegative, LOW);     //"Attaches" the Negative pin on the LED to ground.

  //This is a mini blinking sequence, (just for quick demonstration), to show the state of the Arduino and that the SETUP has worked:
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  //(shouldn't take too long...)
}

void loop()
{
  digitalWrite(13, HIGH);           //Turning on the debug LED to show that the Main Loop has started.
  digitalWrite(LED, HIGH);          //And the LED's are on to show us whether anything actually happens
  delay(1000);                      //So we can see the LED's are on.
  
  //--------------------------------THE RESET------------------------------------//
  pinMode(resetPin, OUTPUT);        //This "Activates" pin 12,
  delay(250);                       //To allow each mode to change
  digitalWrite(resetPin, LOW);      //Puts the Reset pin LOW (as it needs),
  #define resetPin 12       //This is connected DIRECTLY to the Reset pin on the Arduino.
#define LED 3             //For the Positive pin of the LED,
#define LEDnegative 2     //For the Negative pin of the LED.

void setup()
{
  pinMode(LED, OUTPUT);               //Must be set as an OUTPUT to send full power to LED,
  pinMode(LEDnegative, OUTPUT);       //Must be set as an OUTPUT to allow direct connection to Ground (or Negative),
  digitalWrite(LEDnegative, LOW);     //"Attaches" the Negative pin on the LED to ground.

  //This is a mini blinking sequence, (just for quick demonstration), to show the state of the Arduino and that the SETUP has worked:
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  //(shouldn't take too long...)
}

void loop()
{
  digitalWrite(13, HIGH);           //Turning on the debug LED to show that the Main Loop has started.
  digitalWrite(LED, HIGH);          //And the LED's are on to show us whether anything actually happens
  delay(1000);                      //So we can see the LED's are on.
  
  //--------------------------------THE RESET------------------------------------//
  pinMode(resetPin, OUTPUT);        //This "Activates" pin 12,
  delay(250);                       //To allow each mode to change
  digitalWrite(resetPin, LOW);      //Puts the Reset pin LOW (as it needs),
  #define resetPin 12       //This is connected DIRECTLY to the Reset pin on the Arduino.
#define LED 3             //For the Positive pin of the LED,
#define LEDnegative 2     //For the Negative pin of the LED.

void setup()
{
  pinMode(LED, OUTPUT);               //Must be set as an OUTPUT to send full power to LED,
  pinMode(LEDnegative, OUTPUT);       //Must be set as an OUTPUT to allow direct connection to Ground (or Negative),
  digitalWrite(LEDnegative, LOW);     //"Attaches" the Negative pin on the LED to ground.

  //This is a mini blinking sequence, (just for quick demonstration), to show the state of the Arduino and that the SETUP has worked:
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  //(shouldn't take too long...)
}

void loop()
{
  digitalWrite(13, HIGH);           //Turning on the debug LED to show that the Main Loop has started.
  digitalWrite(LED, HIGH);          //And the LED's are on to show us whether anything actually happens
  delay(1000);                      //So we can see the LED's are on.
  
  //--------------------------------THE RESET------------------------------------//
  pinMode(resetPin, OUTPUT);        //This "Activates" pin 12,
  delay(250);                       //To allow each mode to change
  digitalWrite(resetPin, LOW);      //Puts the Reset pin LOW (as it needs),
  delay(250);
  pinMode(resetPin, INPUT);
}

The majority of people would probably think "What's the point in posting this", but just in case someone is having a problem with Software Reset and wants a quick and very simple solution to it, here it is ;D.

The datasheet specifically cautions against connecting a pin to reset and driving it low to reset the chip - it is not guaranteed to produce a proper reset.

The suggested way to produce a software reset is using the WDT.

wills265: The majority of people would probably think "What's the point in posting this", but just in case someone is having a problem with Software Reset and wants a quick and very simple solution to it, here it is

Sigh. :roll_eyes:

DrAzzy: The datasheet specifically cautions against connecting a pin to reset and driving it low to reset the chip

Don't you hate it when that happens?

Better change the icon on this post, eh?

DrAzzy: The suggested way to produce a software reset is using the WDT.

Exactly! Have a read of the bootloader source code, OP.

DrAzzy: The datasheet specifically cautions against connecting a pin to reset and driving it low to reset the chip - it is not guaranteed to produce a proper reset.

The suggested way to produce a software reset is using the WDT.

Agreed, However, in this case it is isn't just an output pin being used to drive the AVR reset signal input pin. The reason being that an Arduino board has the Auto-Reset h/w hack on it. The Auto-reset cap can interact with the signal presented to the AVR reset input pin and slow down the risetime of the reset signal back to Vcc.

The far side of the cap is held at ground by the 16u2 (when the virtual serial port is open buy the host) but the other side of the cap is charged up to vcc by the 10k pullup. That charge will be drained by the output pin when it goes low. I'm guessing that the reset signal rise time will be stretched by the cap after the output pin driving the reset pin turns off when the AVR is actually reset.

It would be interesting to actually look at the timing of the AVR reset signal voltages to see if it is within spec when the Arduino reset is driven low by an AVR output pin.

Also, the behavior will vary depending on whether the host has a serial port open since the far side of the cap is only grounded when DTR is low which is only when the serial port is open.

I'm guessing that the cap would not stretch the reset signal when the virtual serial port is not open since the var side of cap would not be grounded.

--- bill

A lot of discussion, but it appears wills265 has done a hit-and run in the meantime! :roll_eyes:

Thanks for the share of these informations. voir etui galaxy grand prime & coque galaxy grand prime

DrAzzy: The datasheet specifically cautions against connecting a pin to reset and driving it low to reset the chip - it is not guaranteed to produce a proper reset.

The suggested way to produce a software reset is using the WDT.

wdt reset is not exactly the same as hardware reset. like many mfg "recommendations" there is probably no reason why pin reset wont work. specially with a cap to ground which would hold low for the required 2 cycles eliminating any restrictions on that method.

What makes you think a capacitor to ground will make it work better?

Hint: thresholds.

the only restriction is to hold low >2cycles. a cap will do that. with schmidt hysteresis the thresholds are not so relevant. that internal circuit is designed to handle slow rise/fall and in my experience does a great job.

simple jmp to reset location is probably best/easiest method in most cases with wdt a close second. neither will perform a true hardware reset in which case op concept of using a pin works a charm. ive only had to do it couple times though due to unique requirements.

Schmi*t*t trigger :grinning:

yes, in fact does not actually have to be differential. any non-inverting gate will function with appropriate ratio of feedback resistors. many are not even aware the avr reset pin has hysteresis.

what i often find amusing are the rube goldberg circuits noobs (and even some experts) hook up to that pin in the interest of "noise immunity". usually does more harm than good. in most cases best to leave well enough alone.

I am not sure if there are enough differences between an "external reset" via the RESET pin and an "internal reset" via watch dog timer to pick one source from the other. The MCU does know its reset source so in case of an "internal reset" the bootloader will just skip over to the sketch right away. If OP does need to run the bootloader to upload a sketch, then the "internal reset" is not enough. Otherwise, I vote the simpler way.

I don't think we should really call them hardware vs software since all reset sources trigger the same hardware reset circuit. You might call them all hardware reset. The fig. 11-1 on reset logic clearly indicates that "all roads lead to Rome".

in most cases what you say is true, the program always starts at the same place and users dont care what the source of the reset was. in some applications though it is critical to know if it was brown-out, jtag, wdt, ext (hardware), or por. in this case code must determine by reading mcucsr which one or more of these was the cause. not often but many cases in this forum and a few times for me too.

so the io pin method described by op is not the same as software reset and is the only solution in some rare cases.

Not sure why OP wanted pin reset since he has not revealed.

the only restriction is to hold low >2cycles.

Huh? Looks like 2.5us to me (for m328.)

Does the watchdog technique work on Due? I thought the SAM3X had some weirdness about only being able to configure the watchdog timer once (ie if you disable it on startup, you couldn't re-enable it to do a reset...)

westfw: Huh? Looks like 2.5us to me (for m328.)

looking at the datasheet you are right. my info probably comes from some very old 90s parts. i suspect it really is 2 clocks from internal rc (8mhz/8) allowing for process variation. no matter what there is some digital filtering necessary to avoid triggering on ns noise pulses.

regarding op i think like often happens on these forums he had a good idea but maybe didnt quite know why. there are rarely reasons for doing it that way so most would be better off with wdt or simple jmp to 0.

john1993: looking at the datasheet you are right. my info probably comes from some very old 90s parts. i suspect it really is 2 clocks from internal rc (8mhz/8) allowing for process variation. no matter what there is some digital filtering necessary to avoid triggering on ns noise pulses.

Maybe you were thinking of the minimum reset pulse when doing ISP serial programming and trying to sync/re-sync SCK? The spec for that is > two clocks.

--- bill

aha... thats most likely. so maybe im not quite as smart as i think i am after all. lol