Soft reset and arduino

Is it possible to reset an arduino from the program? I was looking for something like reset() to simply re-start the program as-if you just pressed the reset button. I noticed it will reset every time you open the serial monitor, but cant find a way to do it myself.

Trigger the watchdog - it's what it's there for.

But before you do, ask yourself why you're resetting the processor.

AWOL: Trigger the watchdog - it's what it's there for.

But before you do, ask yourself why you're resetting the processor.

How do I actually do that? Nothing I can find explains what the watchdog is, how it works, or how I would actually use it. everyone just says "use the watchdog".... not very helpful to someone that hasn't used it befor...

1 Like

It's described in the datasheet. I always just set the registers directly. You turn on the wdt, and then do something like while(1){;} so it doesn't get reset and times out and resets the chip.

How do I actually do that?

How do you ask yourself why you think that resetting the processor is a good idea? If you have to ask...

I found it a little hard to understand when I first read about it, perhaps it is just the way I learn. I rarely have a reason to reset from software, but every now and then there is a good reason to do so. Here is an example sketch that flashes an LED a few times, then waits one second, and reboots using the watchdog timer.

#include <avr/wdt.h>

void setup() {
  pinMode(13, OUTPUT);
}


void loop() {
  // flash slowly a few times
  for (int i = 0; i < 10; i++) {
    digitalWrite(13, !digitalRead(13));
    delay(500);
  }
  // reset the Arduino
  delay(1000);
  reboot();
}

void reboot() {
  wdt_disable();
  wdt_enable(WDTO_15MS);
  while (1) {}
}

dmjlambert:
I found it a little hard to understand when I first read about it, perhaps it is just the way I learn. I rarely have a reason to reset from software, but every now and then there is a good reason to do so. Here is an example sketch that flashes an LED a few times, then waits one second, and reboots using the watchdog timer.

#include <avr/wdt.h>

void setup() {
 pinMode(13, OUTPUT);
}

void loop() {
 // flash slowly a few times
 for (int i = 0; i < 10; i++) {
   digitalWrite(13, !digitalRead(13));
   delay(500);
 }
 // reset the Arduino
 delay(1000);
 reboot();
}

void reboot() {
 wdt_disable();
 wdt_enable(WDTO_15MS);
 while (1) {}
}

Thank you. I mostly wanted to add reset functionality to the command structure I have going, so sending “1:reset/” over serial resets the device (‘1:’ for device addressing, ‘/’ termination char)

dmjlambert: I found it a little hard to understand when I first read about it, perhaps it is just the way I learn. I rarely have a reason to reset from software, but every now and then there is a good reason to do so. Here is an example sketch that flashes an LED a few times, then waits one second, and reboots using the watchdog timer.

... and the good reason is... ?

It's very easy to implement a program restart using an inner loop inside loop().

It has been a while so I would have to guess my reason was to do some experimentation with initiating a sketch upload without using DTR reset, perhaps from one Arduino to another. I’m sure there are a thousand various reasons to reset via software, and each reason could be individually picked apart. For example, I know I could just jump to the bootloader address instead of resetting. Sometimes a problem is only worth thinking about for a limited time. I’m not clear on the OP’s reason. But I am sure there are multiple ways to accomplish whatever it is.

aarg: ... and the good reason is... ?

It's very easy to implement a program restart using an inner loop inside loop().

In the Arduino I imagine the most common reason is when someone writes an application and they want to include a command to enter the bootloader. They know the bootloader is the first thing to launch after reset, and even if they did know how to jump to it they shouldn't assume it was designed to run with the HW in any state but reset. Almost all of my "start the bootloader" commands are a reset instruction.

Using the watchdog to do it sounds like a hack since I'm used to micros resetting in a single instruction, but I guess it's functionally equivalent.

This should do a clean restart (untested)

void setup() { // leave empty }
void loop()
{
  mySetup();
  while (//  test application exit condition here )
  {
    // application loop code here
  }
}
void mySetup()  { //... init here }

You can also leave the while loop at any time with "break;".

aarg:
This should do a clean restart (untested)

void setup() { // leave empty }

void loop()
{
  mySetup();
  while (//  test application exit condition here )
  {
    // application loop code here
  }
}
void mySetup()  { //… init here }



You can also leave the while loop at any time with "break;".

That is gorgeous code and everyone should code that way.

But be honest with yourself, did mySetup() really replicate everything that occurs with a RESET? Even with the peripherals you don’t use?

The only place that I have seen this be a problem is jumping to bootloaders with a peripheral enabled that the bootloader expected to be disabled due to RESET, but I’ve seen that many times now. I’ll never jump to a bootloader ever, and in general you should never jump to code that wasn’t built expecting for you to jump to it.

Theoretically, given pointer bugs and cosmic ray errors, you should never jump to re-init code unless you seriously did write all of the code necessary to imitate a RESET instruction. At that point, however, you might want to be asking yourself why you’re writing all of that code to avoid using a single instruction.

BigBobby: In the Arduino I imagine the most common reason is when someone writes an application and they want to include a command to enter the bootloader.

You're overestimating the average skill level in this environment. Based on requests that I've seen in this forum in the time I've been around, the most common reason is to restart a game, or something elementary like that. The code I posted is intended to do that, in a safe, easy way. But I think that it should be simplified by putting the setup functions inline, like:

void setup() { // leave empty }
void loop()
{
  // ... initialize application here
  while (//  test application exit condition here )
  {
    // application loop code here
  }
}

Discounting the bootloader, I can't think of anything (other than gross incompetence) that would create a situation where a hard reset would be necessary in place of this.

For reasons, I can cite clarity, portability, maintainability... building character :)

Seriously, though, the idea of resetting to fix bugs in your code is really retrograde.

arduino_lcd_button_with_SoftReset

1:files to include
arduino_lcd_button_with_SoftReset.TXT RENAME TO ZIP

#include <SoftReset.h>

2:code to include in void loop()

lcd.print(“SoftReset”);
delay(5000);
soft_restart();

FULL CODE AND FILE IN ZIP FILE

MINE WORKS FINE WITHOUT PROBLIMES

INCLUDED IN OTHER PROJECTS AS AN EXIT TO LINE O

//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

/*******************************************************

This program will test the LCD panel and the buttons
Mark Bramwell, July 2010

********************************************************/

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#include <SoftReset.h>
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
// For V1.1 us this threshold
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;

// For V1.0 comment the other threshold and use the one below:
/*
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
*/

return btnNONE; // when all others fail, return this…
}

void setup()
{
lcd.begin(16, 2); // start the library
lcd.setCursor(0,0);
lcd.print(“Push the buttons”); // print a simple message
}

void loop()
{
lcd.setCursor(9,1); // move cursor to second line “1” and 9 spaces over
lcd.print(millis()/1000); // display seconds elapsed since power-up

lcd.setCursor(0,1); // move to the begining of the second line
lcd_key = read_LCD_buttons(); // read the buttons

switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnRIGHT:
{
lcd.print("RIGHT ");
break;
}
case btnLEFT:
{
lcd.print("LEFT ");
break;
}
case btnUP:
{
lcd.print("UP ");
break;
}
case btnDOWN:
{
lcd.print("DOWN ");
break;
}
case btnSELECT:
{
lcd.print(“SoftReset”);
delay(5000);
soft_restart();
break;
}
case btnNONE:
{
lcd.print("NONE ");
break;
}
}

}

AWOL: Trigger the watchdog - it's what it's there for.

But before you do, ask yourself why you're resetting the processor.

I am using the millis() function so I need to reset the processor because of the danger of overflow

Instead of using the watchdog, you could simply use a "JMP 0" instruction:

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

There is a simple way to reset the Arduino from a software view point.
You can view it at you tube Arduino Watch Dog tutorial. - YouTube
And you can download the library from GitHub - sodcore/WatchDogReset: Watch dog timer reset for arduino

Sometimes when a device will not connect to wifi for say 20 times, I put in a delay and then reset and start over. Sometimes it then connects. This stuff has gotten to a level of complication that nobody knows the whole story of everything about it.

1 Like