This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Key de-bouncing in 4x4 matrix keypad

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);

delay(FRAME_PERIOD);

}

else {

left_val = right_val;

right_val = next_val;

}

}
}

  • 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); delay(FRAME_PERIOD); } else { left_val = right_val; right_val = next_val; } }}

    Code is WAY too complicated for my simple brain to comprehend.

  • Have readKeyPad() wait for the key signal to stabilize and turn off. If you have micro-second level jitter, you might want to loop for milli-second identifying a clear press and release event.

  • 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;
    }