I'm using 4 x 4 keypad to send the output to 2 7-segment LED.
problem: key de bouncing problem
Summary problem: when I press key, it shows both digit on the left and right. For example, if I first press 1, it should show 1 on the right and blank on the left. If I press 3 next, it should show 1 on the left and 3 on the right. Right now, it I press 1 it shows 1 on the left and 1 on the right. I think this relate to key debouncing. Please check my code.
void read(void) {
char left_val = 'n';
char right_val = 'n';
char next_val = readKeyPad();
while(1){
next_val = readKeyPad();
if (right_val == next_val || next_val == 'n'){
printChar(left_val, Left);
delay(FRAME_PERIOD);
printChar(right_val, Right);
}
else {
left_val = right_val;
right_val = next_val;
} }
Hey,
There are plenty of denouncing strategies defined in textbooks, with solutions in hardware, digital logic, and software.
I suggest you scope the signal, and see a typical period of noise. This would make your solution inherently empirical, so I wouldn't feel the need to make beautiful code.
Simply assert stability a certain number of iterations. If you have an RTOS, poll it with a task. If you don't want to consume so much resources polling it, your option is applying a period of time where the result is unstable, and effectively, "dont care" 'X' in DLD :).
Example for a polling code:
//Uvision calls compiler with compiler defines. E.g. "C166.exe DEFINE(TDD)" #include <stdint.h> //XintY_t #include <stdbool.h> //bool #include <stdlib.h> //rand bool eg_mySwitch(void) { #ifdef TDD //Returns psuedo 1 or 0 return ((rand() >> 1) >= (32767 >> 1)); #else //Your hardware abstraction #endif } //Hardware abstraction layer #define FILTER_WINDOW_LEN 10 //length of my window for the debouncer, find experimentally #define FILTER_MAX_ITERATIONS 10000 // Arbitrary exit condition... #define FILTER_X_GETSTATE eg_mySwitch //callback function that returns 1 or 0 bool poll_switch(bool endState) { static uint8_t s_vals[FILTER_WINDOW_LEN]; static uint8_t s_index; static uint8_t s_total; //Start polling while(s_index != FILTER_WINDOW_LEN) { s_vals[s_index] = FILTER_X_GETSTATE(); if(s_vals[s_index] == endState) s_index++; else s_index = 0; if(s_total++ == FILTER_MAX_ITERATIONS) return !endState; } //done return endState; }
I have always done keys in a (typically 10ms) "debounce time" timer ISR. two identical reads and you are OK. It just works and is dead simple