Click here to Skip to main content
15,893,668 members
Articles / Internet of Things / Arduino

Arduino Software Reset

,
Rate me:
Please Sign up or sign in to vote.
4.60/5 (9 votes)
23 Jul 2015CPOL3 min read 103.5K   13   11
Three easy ways to programmatically reboot/reset an Arduino MCU.

Choosing an MCU with a small amount of RAM (e.g., the ATmega328p MCU has only 2KB RAM), and programming it by using dynamic memory allocation (e.g., by using malloc) may cause memory fragmentation having as side effect strange MCU behavior. In such cases, observing the "real free" amount of RAM and rebooting the device whenever a dangerously low level is detected may be the only (or the simplest) solution for having the project running for a long amount of time.

We present three currently available and simple methods which allow to programmatically reset an Arduino.

Watchdog Reset - The Recommended Method

Whenever possible, this is the method one should use. Not only that was designed and implemented by the chip manufacturer, but also produces a clean reset, with the same results as when you freshly power the Arduino (or the custom Arduino-brained project board). Think on a watchdog as on a kind of guardian for the micro-controller, able to power it off then back on. Once a watchdog was started, the program must emit signals (also named reset signals) within specified time slots, and in the absence of the correct signal, it simply produces a reset. The specific time periods are called prescallers and are normally defined as constants. For Atmel MCUs found in the Arduino boards, the following prescaller constants were defined: WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS, WDTO_250MS, WDTO_500MS, WDTO_1S, WDTO_2S, WDTO_4S, and WDTO_8S. Their names are suggestive, indicating possible time slots between 15 milliseconds and 8 seconds.

The following code shows how to use the watchdog to reset the Arduino on-demand:

C++
#include <avr/wdt.h>

void softwareReset( uint8_t prescaller) {
  // start watchdog with the provided prescaller
  wdt_enable( prescaller);
  // wait for the prescaller time to expire
  // without sending the reset signal by using
  // the wdt_reset() method
  while(1) {}
}

void setup() { // add setup code here...}

void loop() {
  // ... various code...

  // restart in 60 milliseconds
  softwareReset( WDTO_60MS);
}

We have discussed about how use a watchdog for auto-reset purposes, but it has many other use cases, such as waking-up the MCU from power-down states or debugging.

Program Restart - The Unclean Method

This method does not really perform a MCU reboot, but rather a program restart. The obvious negative effect is that the MCU hardware states remains mostly unchanged. This includes the pin modes, their current HIGH or LOW states and so on. The following code shows how to implement the softwareReset method by using assembly language and executing a jump to the address where the program starts:

C++
void softwareReset( unsigned long delayMillis) {
  uint32_t resetTime = millis() + delayMillis;
  while ( resetTime > millis()) { 
    /* wait and do nothing until the required delay expires... */
  }
  // jump to the start of the program
  asm volatile ( "jmp 0");  
}

Enforce Hardware Reset - The Hacker's Method

This method requires to connect one of the digital pins (e.g., digital pin 7) to the reset pin of the Arduino via a 1kOhm or 2.2kOhm resistor. Then set the digital pin as OUTPUT and keep it HIGH as long as no reboot/reset is required. Once a reboot is needed, just set the digital pin to LOW. This method works because by putting the reset pin to a LOW state, the micro-controller receives a "hardware reset signal". The following Arduino sketch code shows how to implement and use this method:

C++
void softwareReset( uint8_t prescaller) {
  uint32_t resetTime = millis() + delayMillis;
  while ( resetTime > millis()) { /* wait and do nothing... */}
  // set digital pin 7 to LOW - reset the MCU
  digitalWrite( 7, LOW);
}

void setup() { 
  // set digital pin 7 mode to OUTPUT 
  // it is connected to reset pin via 1kOHM resistor 
  pinMode( 7, OUTPUT);
  digitalWrite( 7, HIGH);
}

void loop() {
  // ... various code...

  // restart in 60 milliseconds
  softwareReset( 60);
}

Unfortunately, this method can't be used on all Arduino boards and also not with every Atmel MCU. The main problem is that the digital pins goes in a LOW state when set to OUTPUT thus resulting in a reset loop which may require to remove the connection with the reset pin before being able to reprogram the MCU. We confirm that Arduino UNO and Arduino MEGA2560 boards can be safely used with this method.

While Arduino was mostly in our discussion (so, Atmel MCUs), there are many other MCUs designed and produced by various manufacturers where the above presented methods work in the same way. However, different code may be required and in case of using "the hacker method", one may need also to study the chip datasheet for being able to correctly use the reset and I/O pins and even may have to use a different resistor value.

This article was originally posted at http://web-engineering.info/blog-feed.xml

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Instructor / Trainer
Germany Germany
Researcher, developer, instructor and cat lover.

Co-Founder of web-engineering.info and the educational simulation website sim4edu.com.

Written By
Technical Lead
Germany Germany
Researcher, developer, WoT/IoT enthusiast
Co-founder of http://web-engineering.info.

Comments and Discussions

 
QuestionWatchdog Reset - The Recommended Method not working Pin
Member 1480503617-Apr-20 3:36
Member 1480503617-Apr-20 3:36 
QuestionI was wondering Pin
Member 1475615026-Feb-20 4:16
Member 1475615026-Feb-20 4:16 
QuestionHi, I would like to ask this question Pin
americoAC8830-Oct-18 5:23
americoAC8830-Oct-18 5:23 
QuestionWatchdog stays enabled after reset? Pin
stepe19-Mar-17 9:38
stepe19-Mar-17 9:38 
AnswerRe: Watchdog stays enabled after reset? Pin
stepe19-Mar-17 10:02
stepe19-Mar-17 10:02 
QuestionInfinite Loop? Pin
Member 1216709525-Nov-15 10:35
Member 1216709525-Nov-15 10:35 
AnswerRe: Infinite Loop? Pin
Mircea Diaconescu25-Nov-15 11:06
Mircea Diaconescu25-Nov-15 11:06 
GeneralRe: Infinite Loop? Pin
Member 121670951-Dec-15 8:28
Member 121670951-Dec-15 8:28 
GeneralRe: Infinite Loop? Pin
Mircea Diaconescu1-Dec-15 8:53
Mircea Diaconescu1-Dec-15 8:53 
QuestionMalloc and New Pin
ThomasZJ24-Jul-15 3:54
ThomasZJ24-Jul-15 3:54 
AnswerRe: Malloc and New Pin
Mircea Diaconescu24-Jul-15 5:20
Mircea Diaconescu24-Jul-15 5:20 
Yes, you are right, this is generally preferred with low resources devices. In general, I also use stack whenever possible. The example I gave there is one possible test case for peoples which use dynamic memory allocation, and the internet is full of such examples. Not everyone knows how to deal with embedded devices, for many (specially beginners) a MCU is a kind of small computer.

However, there are still edge use cases when even an advanced user can think of using dynamic memory allocation. For example, I am on the way of deploying a COAP-enabled project with an ATmega328P MCU (so, 2KB RAM), because I really want a non-smd device (prototype and home-production reasons). It runs serial communication (for ESP8266 WiFi module), I2C for an OLED display, and also have sensors such as humidity, temperature, soil moisture and so on. In this case, the free memory I get is under 250 Bytes. If I don't use dynamic memory management for the COAP message, the free RAM goes below 50Bytes, that not being enough for reading the sensors, performing actions, and so on. Therefore, when I have to create the COAP message (this only happens from time to time), I dynamically allocate the memory, then send the message and then free up the memory so it can be reused for the the other purposes.

In my project I managed to re-implement parts of the code so that the reboot of MCU is not required by now, but wanted to share the reboot solutions with the community, maybe others can benefit from it.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.