Two Ways to Reset Arduino in Software

758,129

182

72

Introduction: Two Ways to Reset Arduino in Software

If you want to RESET Arduino from the beginning without manually pressing the RESET button, there are a few ways. Here are two ways, using minimal wiring / circuitry. 

Step 1: Using 1 Wire Connected to the RESET Pin

1. electronically, using only 1 wire connecting an OUTPUT pin (12 in this example) to the RESET pin. (see the circuit)

In this example, pin 13, connected to the internal LED pin 13 is blinking. Pin 12 gets connected to the RESET pin by one wire.
-Typically, this would be a problem because when the application starts up, all pins get pulled LOW. This would therefore disable Arduino from every running. BUT, the trick is: in setup() function, the FIRST thing that happens is we write HIGH to the pin 12, which is called our reset pin (digitalWrite(resetPin, HIGH), thereby pulling the Arduino RESET pin HIGH. 

Step 2: Using Just Software

In this example, you do not need any extra wiring. We initialize the reset function, then call reset.

void(* resetFunc) (void) = 0;//declare reset function at address 0
...
resetFunc(); //call reset 
Hack It! Contest

Participated in the
Hack It! Contest

1 Person Made This Project!

Recommendations

  • Game Design: Student Design Challenge

    Game Design: Student Design Challenge
  • Make It Bridge

    Make It Bridge
  • Big and Small Contest

    Big and Small Contest

72 Comments

0
hausofpayne17
hausofpayne17

1 year ago

Thanks for your help. I've spent all day trying to get a bunch of char arrays to reset and finally gave up. Your software method did the trick!

0
anisharma598
anisharma598

Question 1 year ago on Introduction

When i supply power with usb cable to my arduion its green light , tx ,rx and ledbuilting light up but after 2 or 3 seconds its slowly turn off automatically and when i suplly power with 12 v adapter green light start blinking and adapter light also started blinking

0
guilhem victorion
guilhem victorion

Question 2 years ago

j'ai fais une fausse manip avec une clé arduino léonardo, je n'arrive pas a la re téléverser avec un nouveau programe vide. Est t'il possible de faire un reset manuelle ou un reset à
l'aide de l'IDE

0
rohmat.cadangan
rohmat.cadangan

Question 2 years ago on Step 2

hey, so, if i use this code will it also reset the variable I've changed?
I'm creating a code that change the SSID and the password through bluetooth, with default value.. can i use this?

0
italex33
italex33

2 years ago on Step 2

I have a Personal Weather Station (PWS) up and running using the MKR1010, once in a while I cannot access it via WiFi, so I need to manual reset it. The PWS is still working fine, still reporting weather, but from my computer I dont see it, that's when I need to manual reset it. Well, thank you to your tip: "BUT, the trick is: in setup() function, the FIRST thing that happens is we write HIGH to the pin" pin 7 in my case, and I wired this pin to the MKR1010 reset pin , and bingo! It works, yahoo! Oh, by the way, I am using Blynk, so I added this peace of code, V4 is my virtual button that I tap on my iPhone to reset the MKR1010:

int resetIn;
int resetPin = 7;
BLYNK_WRITE(V4)
{
resetIn = param.asInt();
if (resetIn == LOW)
{
digitalWrite(resetPin, HIGH);
}
else
{
digitalWrite(resetPin, LOW);
}
}

Thank you,
Alex

P.S. Very nice to see a girl playing with these things, nothing wrong with that, my daughter is in the computer field as well.

0
codebeat
codebeat

5 years ago

resetFunc is a pointer to an invalid address! That's the reason the device 'resets', in fact it crashes. Don't rely on this malfunction method and maybe it can damage your device at the long run.

0
swordmound
swordmound

Reply 3 years ago

If you take a look at arduino's bootloader, it's just doing so to start the app. It uses wdt reset to signal soft reset the hardware after programming and then jump to address 0x00 if wdt reset flag raised on boot.

Screenmemo_2020-01-18-10-26-30.pngScreenmemo_2020-01-18-10-28-12.png
0
codebeat
codebeat

Reply 3 years ago

There is a main difference, you call a function pointer at address 0 (which is an invalid address), it is a null pointer assignment. You don't jump to address 0, you call it ( take a look at code - resetFunc(); <- you call a function at memory address 0 ) and there is nothing to execute. This results in a fatal exception (NullPointerException) and cause a reboot because of a crash (no exception handling). Google it if you want to, null is nothing (with use of pointers) in addressing memory locations.

Also there is a difference between program memory and volatile memory. The soft reset jumps to program memory location 0, that is where the program starts, the beginning of the program. The code use registers to achieve this, not pointers to memory locations, it is not a function! The volatile memory will be reset to non allocated, it start from scratch. You declared a function pointer to volatile memory location 0 that doesn't have a function allocated. It is a pointer to a function however there is no function. In fact you calling *resetFunc without any valid content.

Sound a bit complicated however I want you to know your code is not an example (maybe a bad example) and you need to change it. Program memory (flash), volatile memory and registers are different beasts. Also take a look at pointers, what they are and how they work, most people find it very difficult because it is logic. Maybe I should do an instructable on this.

0
swordmound
swordmound

Reply 3 years ago

That's a really good explanation. I'm now curious about some things.
1. what if resetFunc was declared using PROGMEM or something similar (flash, i think? obviously not EEPROM), would it still crash?
2. From what I read from your explanation, variables declared from programs located in bootloader area is located in program memory(flash), which is treated the same way as literal strings, and variables declared from programs outside the flash (user program area?) is allocated later on volatile memory. Is my comprehension true?
3. what happen if i use inline assembly to long jump/short jump to 0x00 from user code space?

I am trying to modify arduino's bootloader to fit my needs, so I am really wondering if bootloader space and user code space is treated differently and I should change the modifications so the chip won't break.

0
codebeat
codebeat

Reply 3 years ago

Thanks. Your questions:
1. The define and macro PROGMEM (PROGram MEMory) tells the compiler to store the contents of the variable in program space, which has its own address (in order of declaration) and values. By storing the value of 0 doesn't mean address 0. You cannot access the program memory/space directly. There is allot going on behind the define and macro PROGMEM. To get content of PROGMEM variables you need to use dedicated functions (directly access such variables produce rubish). Take a look at this example of Arduino:
https://www.arduino.cc/reference/tr/language/varia...

2. The memory space is divided into segments with specific functions, for example you cannot access the bootloader without special rights and instructions. That is why burning a bootloader is different to the method to upload a sketch. The program is on top of the bootloader, the bootloader is the first thing to start before any program. The bootloader makes it also possible to be able to upload a sketch. You cannot access the bootloader from a program. Take a look at this to understand the different segments (it is not really specific related to AVR or Arduin stuff however it is the same 'idea'):
https://en.wikipedia.org/wiki/Data_segment

3. Yes, you can use a jmp 0 instruction to restart the program however mostly all registers will stay the same. That is why when a pin is set HIGH (by specific condition) it will stay HIGH until you press the reset button or reconnect power. This can have some (dangerous) side effects and is not recommended. It could be possible that you create a short or your project starts to misbehave.

Take a look at this article about performing a reset:
https://www.codeproject.com/Articles/1012319/Ardui...

The is no golden method for Arduino to perform a reset because there are many different types of MCU's and boards identified as Arduino. The title: "Two ways to reset your Arduino" in fact isn't correct because you cover only AVR's.

Be careful with (modifying) the bootloader because when you screw it up, your Arduino could be history. Better learn first all of the internals before starting to mess around with bootloaders.

0
ELLV
ELLV

3 years ago on Introduction

Without a proper resistor it'll work, but the controller won't be able to be flashed with new sketch and also might get damaged on the long run. I suggest to add a 4.7k resistor instead of a direct wire.

0
Antony21
Antony21

Question 4 years ago

Estou tentando fazer pelo Arduíno mega um botão de reset por um botão, para resetar um tempo quando apertado, porém a programação não esta funcionando.

0
stevenk37
stevenk37

7 years ago

Well.. #1 is not really a software solution, is it, if you have to wire pins.. Also, this is not an advised solution, according to what I've read before.

#2 Is just a hack that anyone could come up with, but still doesn't provide a real watchdog functionality (you have to trigger it, and thus can only be used as a reset method, not a WD (which seems to be what sme of you guys need).

Let me give some details on the built-in arduino WD (yes, really) that can be used both as WD or as a reset device.

You can set it from 15ms to 8s range. You need to reset it in software or otherwise it will trigger a reset (reverse to #2 method).

Here's how to use it;

#include <avr/wdt.h> //should be in any adruino IDE

void setup() {
wdt_disable(); //always good to disable it, if it was left 'on' or you need init time
//do some stuff here
wdt_enable(WDTO_8S); //enable it, and set it to 8s
}

void loop() {
//do some stuff here
wdt_delay(5000) //instead of delay, i made my own delay to reset the WDT
}

//this makes sure the WDT is reset immediately when entering the
//function, but we can still benefit from a real 'delay'.
//upon leaving the function, we reset it again.
//i realize timing will be loose, you can always do something with
//millies() if you need strict timing.
//you might also need to adjust the '1000' if you WDT is shorter

void wdt_delay(unsigned long msec) {
wdt_reset();

while(msec > 1000) {
wdt_reset();
delay(1000);
msec -= 1000;
}
delay(msec);
wdt_reset();
}

//to reload the board, you only have to delay > WDT
//another option is to set the WDT very short, and do a short delay

void wdt_reload() {
delay(8001);
}

0
AndreC115
AndreC115

Reply 4 years ago

I did that, by using the WDT approach, and the board got stuck; I'm even unable to program the original code with Pololu USB programmer. Unfortunatelly, the board is battery powered and designers did not provide a RESET button, therefore it seems I'm in a big trouble. Did I miss something, or there are another way to put it to work again?

0
stevenk37
stevenk37

Reply 4 years ago

what kind of board is this? it seems not a 'standard' arduino? eitherway if it uses the same ATmega328P-like chip, you should be able to find the reset pin on the processor and use that..? if you're stuck, and cannot program it, try the icsp connectors, which also have a reset pin..

0
AssiniH2
AssiniH2

Reply 5 years ago

It is not working...

After few seconds, LED on pin13 is blinking...

0
stevenk37
stevenk37

Reply 5 years ago

Please make sure the board (and the bootloader!) support watchdog.