Go Down

Topic: Detecting RESET button presses via modified bootloader (Read 1 time) previous topic - next topic


I just made a small change to the Optiboot bootloader, which allows sketches to detect the source of a reset.  This means the reset button can be used as a control input.

Because of the way Optiboot works there are limitations: it's not possible to distinguish an external reset (pushing the reset button) from a watchdog reset.  But it does allow a sketch to distinguish a power-on event from other reset sources.

The change is to optiboot.c, and consumes an extra 4 bytes of bootloader memory.  With v4.5 compiled for an ATmega328 this still fits in the 512 bytes available, with 2 bytes free:
Code: [Select]
<   MCUSR = 0;
>   MCUSR &= ~(1<<WDRF | 1<<EXTRF);

And an example sketch looks like this:
Code: [Select]
void setup() {
  int startup = MCUSR;

  pinMode(13, OUTPUT);

  if (startup == 0) {
    // ----- flash LED twice quickly after external reset
    digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW);
    digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW);
  } else {
    // ----- flash LED once slowly after power-up
    digitalWrite(13, HIGH); delay(1000); digitalWrite(13, LOW);

void loop() {


Okay,.... How do you get it to load a new sketch if the reset has been disabled?


The modification does not disable reset, or change the bootloader operation in any way.  The only difference is that it leaves the reset status register (partially) intact rather than wiping it completely.  Why would you want to do this?  There are a few possibilities:

For example, you might want your program to go to sleep after changing batteries, but use the external reset as a power-on button.  Now that you can distinguish external resets from power-on resets, this is possible.

Alternatively, you might use the reset button to change the operating mode of your program, but require that after a power cycle it does not change mode.

Of course there are other ways of doing these things.  This one could be useful if you're short of pins, or don't want to connect extra buttons.


Well, I use the reset button as a mode switch: http://blog.blinkenlight.net/experiments/counting-resets/multiple-modes/. IMHO it is not very helpful to be able to distinguish external resets from power on resets unless you are running a standalone chip. The reason is that I usually power my stuff from a laptop. This I always get some external resets whenever the laptop boots or Arduine IDE starts up or whatever piece of software things it wants to mess with the ports.

This happens more often than you would expect. Still I think this extension is a good idea.
Check out my experiments http://blog.blinkenlight.net

Go Up