Again I'm looking for advice on the most efficient algorithm or the best practice for accomplishing a task. In this case it is debouncing a set of push buttons and setting a bit in a state variable if the button has been pressed. The design is for a navigator type keypad with up, down, left, right, and center momentary pushbuttons. The algorithm uses a timer interrupt to check the pin state every 5 mS and if the pin is set for 5 consecutive intervals 25mS then we say that it really is pressed and properly debounced.
In words:
Timer interrupt checks pin state every 5 mS.
If button is released and the count for that button is > 0 decrement that button's count.
If button is pressed and the count for that button is < max, increment that button's count.
If button is pressed and the count for that button is >= max then set button state to pressed and set that button count to 0.
Note that we do not set the button state to released "“ that is done by the user code once the button press has been processed.
And the defines and interrupt used are:
// This gives us 25mS debounce #define MAX_COUNT 5 // Define bit positions for each of the buttons #define LFT 0 #define RGT 1 #define UP 2 #define DWN 3 #define CTR 4 volatile uint8_t nav_state; volatile uint8_t lft_count; volatile uint8_t rgt_count; volatile uint8_t up_count; volatile uint8_t dwn_count; volatile uint8_t ctr_count; //Timer2 Compare A interrupt vector handler ISR(TIMER2_COMPA_vect) { if(nav_lft()) { if( lft_count < MAX_COUNT ) lft_count++; else { bit_set(nav_state,LFT); lft_count = 0; } } else // not pressed { if (lft_count > 0) lft_count--; } if(nav_rgt()) { if( rgt_count < MAX_COUNT ) rgt_count++; else { bit_set(nav_state,RGT); rgt_count = 0; } } else // not pressed { if (rgt_count > 0) rgt_count--; } if(nav_up()) { if( up_count < MAX_COUNT ) up_count++; else { bit_set(nav_state,UP); up_count = 0; } } else // not pressed { if (up_count > 0) up_count--; } if(nav_dwn()) { if( dwn_count < MAX_COUNT ) dwn_count++; else { bit_set(nav_state,DWN); dwn_count = 0; } } else // not pressed { if (dwn_count > 0) dwn_count--; } if(nav_ctr()) { if( ctr_count < MAX_COUNT ) ctr_count++; else { bit_set(nav_state,CTR); ctr_count = 0; } } else // not pressed { if (ctr_count > 0) ctr_count--; } }
So can anyone suggest a much better (either faster or less code or both) to do this?
Smiley