I needed a simple debounce for a push button wired directly to a digital input on an ATMega. I’m sure there are more advanced techniques but this is working well for me.
1 2 3 4 5 6 7 8 9 10 |
int ButtonPressed() { /* the button is pressed when BUTTON_BIT is clear */ if (bit_is_clear(BUTTON_PIN, BUTTON_BIT)) { delay_ms(DEBOUNCE_TIME); if (bit_is_clear(BUTTON_PIN, BUTTON_BIT)) return 1; } return 0; } |
Where bit_is_clear is defined in AVR-LIBC IO.H as
1 |
#define bit_is_clear ( sfr, bit ) (!(_SFR_BYTE(sfr) & _BV(bit))) |
and when I actually use this to detect a press I incorporate a timer to prevent another detection (double press). The timer is started and a blocking flag cleared upon completion, which will then allow a second detection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
BOOL buttonWaiting = FALSE; int buttonCounter = 0; void ProcessCurrentState() { // Check buttons here if (!buttonWaiting && ButtonPressed()) { buttonWaiting = TRUE; buttonCounter = 0; timerAttach(TIMER2OVERFLOW_INT, ClearButtonWait); // Process button press // or take appropiate action } } void ClearButtonWait() { buttonCounter++; if(buttonCounter > BUTTON_OVERFLOW_COUNT) { buttonWaiting = FALSE; timerDetach(TIMER2OVERFLOW_INT); } } |