6

I am trying to make a circuit using an ATmega328, that has a reset button that behaves like many consumer devices:

  1. A short press just restarts the micro-controller
  2. A long press (5 seconds?) causes the settings to be restored to default

What is the best way to achieve this behaviour? I imagine it is going to require two pins? Can it be done just using passive components?

Thanks!

njh
  • 253
  • 3
  • 7

3 Answers3

7

It can be done with one button, one resistor, one capacitor and one GPIO pin (in addition to the RESET pin):

schematic

simulate this circuit – Schematic created using CircuitLab

Pressing the button causes a LOW pulse on the RESET pin (in the exact same way as the USB interface does).

During your startup procedure you read the GPIO pin you have chosen. If it's LOW the button is still being pressed in. If it's HIGH it has been released.

If you are using an Arduino with the normal bootloader the bootloader itself imposes a 2 second delay (which may be enough for you). Alternatively you will need to have your own delay in your program before reading the button to ensure that you have plenty of time to release the button so you don't accidentally reset your settings.

Majenko
  • 105,851
  • 5
  • 82
  • 139
1

You can set the RSTDISBL (bit 7 on the HIGH fuse) to disable the external reset and use the reset pin as PC6 to manage the reset behavior from your program.

RSTDISBL ATmega328P

The second part is to capture when reset button is pressed: put some code in the ISR for PCINT1 handler when the pin changes (PCINT14 pin function). If you are programming an Arduino board, the reset button is pulled up (press becomes LOW and release becomes HIGH).

Detecting long press or short press is a timer affair. According to your requirements, you will restore some EEPROM values or external state to factory defaults before the microcontroller resets with a long press.

This C snippet will reset the microcontroller after the short or long press (watchdog timer feature):

#include <avr/wdt.h>

    // ...
    wdt_enable(WDTO_15MS);
    for (;;) {}
caligari
  • 221
  • 1
  • 9
0

Use a state machine to detect thee king presses. Once done, you can either trigger a hardware or a software reset, or to simulate one by jumping to the reset vector - you will need to write the code to support that, like an explicit initialization of variables, etc.

dannyf
  • 2,813
  • 11
  • 13