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.