Skip to content
Tags

Resetting the Arduino through software for fun and profit

February 26, 2012

For some time now the Arduino boards (since two years ago?) have had a nice hands-free sketch upload process that is driven by the Arduino IDE in contrast with old boards where you had to reset the board manually and then go back to the IDE to transfer the sketch.

The upload process is explained at a high level here but basically this is achieved by resetting the board through the serial port DTR line. The DTR-controlled reset is all nice (and hacky) but if for any reason you don’t have a way to control it from software then there’s no way to auto-reset the board and no way of auto-uploading new sketches without manual intervention!

Arduino reset circuit

Implementing the hands-free upload required a hardware change to be able to trigger a board reset (or to be more a microcontroller reset) from software.

This was done by coupling the microcontroller reset circuit to the DTR serial pin: when a user requests to upload a new sketch the IDE will drive the DTR line down for a few milliseconds (the reset pin is active low) to trigger the reset starting the upload process.

image

After the reset the bootloader kicks in and by then the IDE has launched avrdude to negotiate the upload of the new sketch.

Once the sketch is uploaded it is started immediately by the bootloader.

But what if there’s no way to control the DTR line?

As mentioned if the DTR line can’t be controlled from software then there’s no way to reset the board and no way of auto-uploading new sketches without manual intervention i.e. resetting the board manually.

And why would you care? Because there are some Bluetooth modules out there where the DTR line can’t be driven directly either by limitations in the BT module’s firmware or limitations in the breakout board. It would be very convenient to be able to wirelessly update the sketch (a post is coming about this).

Introducing the Watchdog timer

Fortunately the ATMega family of microcontrollers (and maybe any decent microcontroller out there) has a Watchdog timer that can be programmed to reset the microcontroller after it expires. Details about it can be found in Section 11.8 of the spec

Below is a simple sketch that will reset the Arduino 1s after you send the character ‘R’ through the serial port.

But wait! Before you run and try this there’s a little problem: after a watchdog reset there’s some cleanup to do otherwise the board will keep resetting on you until you power cycle the board.

#include <avr/io.h> 
#include <avr/wdt.h>

int ledPin = 3;

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

void loop() 
{ 
  if (Serial.available() > 0) 
  {    
    char cmd = Serial.read(); 
    if (cmd == 'R') 
    { 
      wdt_enable(WDTO_1S); 
    } 
  }

// Blink the LED
digitalWrite(ledPin, HIGH);   
delay(500);                 

digitalWrite(ledPin, LOW); 
delay(500); 
}

Now you could do the cleanup in the setup() function since there should be enough time for the cleanup to be executed after a reset. However it seems that until you clear the WDRF bit in the MCUSR register the board will keep restarting. This is not clearly documented in the spec but I think that’s what’s happening.

So what we need to do is to change the bootloader code to cleanup the Watchdog registers right at the very beginning which is actually recommended by the ATMega spec. The ATMega 328 bootloader code shipped with the Arduino IDE 1.0

arduino-1.0\hardware\arduino\bootloaders\atmega\ATmegaBOOT_168.c

already contains some Watchdog-related code to take care of this but is disabled by default (Originally developed by Limor from Adafruit Industries).

However the code does more than just clearing the Watchdog register which is all we need. So here’s just the bare cleanup code.

int main(void) {

// Clear the reset bit

MCUSR &= ~_BV(WDRF);

// Disable the WDT

WDTCSR |= _BV(WDCE) | _BV(WDE);

WDTCSR = 0;

Just edit the bootloader, recompile and upload.

Enjoy!

Advertisements

From → Arduino

4 Comments
  1. Dan permalink

    Fine tip but I have a doubt: it’s necessary to add the #define ‘WATCHDOG_MODS’ in the Makefile and recompile the bootloader or not?

    • Dan
      If you define WATCHDOG_MODS you’ll get more than what’s actually needed and IIRC (I have not touched this code for a while) that will actually not work as expected. So just add the lines I mentioned.

      Regards

Trackbacks & Pingbacks

  1. Uploading Arduino sketches wirelessly using a Bluetooth breakout board « aRiver's pad
  2. Arduino Bluetooth Firmware Upload

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: