Switch debounce is a common problem faced when playing with digital circuit. It is a condition where single pressed by user would appears multiple presses.
Usual software method used to avoid this is by taking multiple samples at certain time interval.
Usual software method used to avoid this is by taking multiple samples at certain time interval.
if (time_inverval == 10ms) // run this function every 10ms { if (pin1 == HIGH) // check the pin status { pin1_counter++; } else { pin1_counter--; } if (pin1_counter>=10) // confirm the samples for 10 times { pin1_counter = 0; // clear the pin1_counter after 10 samples pin1_flag = 1; } }
Or you can use extra diode and capacitor to filter out the debounce glitches as shown at labbookpages. The labbookpages actually shows solutions from A Switch Debouncer Circuit, Software Debouncing, to Digital Switch Debouncing, to Switch Debouncing ICs. Nevertheless, extra circuitry mean extra cost, it is better to settle everything in software. Only a few lines are needed.
This blog (or my osa rtos learning diary) is to show how to implement switch debounce in rtos. The solution is shown at osa rtos at "button" section but I never really understand it. So I decide to try it out.
From osa rtos website:
//------------------------------------------------------------------------------ // Wait for key press (with debounce) //------------------------------------------------------------------------------ do { OS_Cond_Wait(!pin_BUTTON); OS_Delay(40 ms); } while (pin_BUTTON);
The function use the OS_Cond_Wait to wait for button is pressed then delay it for 40ms to skip the debounce signal.
After that, wait for the key to be released.
//------------------------------------------------------------------------------ // Wait for key release //------------------------------------------------------------------------------ do { OS_Cond_Wait(pin_BUTTON); OS_Delay(40 ms); } while (!pin_BUTTON); }
The implementation is likely the same, so user source code should be placed in between "wait for key press" and "wait for key release" (I assume).
So I add one flag for button pressed, so my overall code for taskButton is as follow:
#ifndef TASK_BUTTON_H #define TASK_BUTTON_H #include <osa.h> #include <p18cxxx.h> #define mInitSW1() {TRISBbits.TRISB0=1;} #define mInitSW2() {TRISBbits.TRISB1=1;} #define mSW_1 PORTBbits.RB0 #define mSW_2 PORTBbits.RB1 extern unsigned char flag_button1; extern unsigned char flag_button2; void taskButton1(void); void taskButton2(void); #endif /* TASK_BUTTON_H */
The taskButton function is:
void taskButton1(void) { mInitSW1(); flag_button1 = 0; for (;;) { //------------------------------------------------------------------------------ // Wait for key press (with debounce) //------------------------------------------------------------------------------ do { OS_Cond_Wait(!mSW_1); OS_Delay(2); // delay 40 ms } while (mSW_1); //------------------------------------------------------------------------------ // Raise a flag //------------------------------------------------------------------------------ flag_button1 = 1; //------------------------------------------------------------------------------ // Wait for key release //------------------------------------------------------------------------------ do { OS_Cond_Wait(mSW_1); OS_Delay(2); } while (!mSW_1); } }
I put a video to show how the whole program is working. The led blinking, 16x2 display and button.
Project file is downloadable at here.