LowPowerLab Forum

Hardware support => General topics => Topic started by: Felix on September 05, 2014, 04:10:09 PM

Title: Button debouncing in an interrupt
Post by: Felix on September 05, 2014, 04:10:09 PM
Say you want to use a hardware interrupt (INT1 = D3 on Moteino) to read a momentary tactile button.
The button is hooked like this:     VCC ---> button ---> D3
To debounce a button press you can do it like this:

1) Software method:

#define BUTTON_INT    1 //user button on interrupt 1
#define BUTTON_PIN    3 //user button on interrupt 1

void setup() {
  attachInterrupt(BUTTON_INT, handleButton, RISING);
}

#define FLAG_INTERRUPT 0x01
volatile int mainEventFlags = 0;
boolean buttonPressed = false;
void handleButton()
{
  mainEventFlags |= FLAG_INTERRUPT;
}

void loop() {
  if (mainEventFlags & FLAG_INTERRUPT)
  {
    delay(20);
    mainEventFlags &= ~FLAG_INTERRUPT;
    if (digitalRead(BUTTON_PIN)) {
      buttonPressed=true;
    }
  }
   
  if (buttonPressed)
  {
    buttonPressed = false;
    // do something to celebrate the button press!
  }
}


Idea picked up here:
https://docs.google.com/document/d/1mFNauOS8eQgzZuBae3Ga-EyMB_Jq1q20fayBSYHq8SU/edit
https://docs.google.com/document/d/1ES7hYUs__Rd26RTFlmWYcVBZejb1dW0vRagwZBV2kEM/edit

2) Hardware method:
Using an RC circuit with schmitt trigger:
http://www.youtube.com/watch?v=CRJUdf5TTQQ

Debouncing using delay() only works in the loop when you are non-concerned about sleeping or using interrupts. This method is good for nodes that sleep and need to be waken up by the button press and do something, then immediately go back to sleep. I will share the complete code where I do this in the coming Moteino Motion/OLED Shield.