We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have done software debounce logic with 2/3 voter logic and kindly verify the coding i don't no whether it is correct or not. Please help me
Coding:
void inputRoutine() { uint16_t temp; InputP1_Temp=P1&0x00; for(Index1=0;Index1<MAXINPUTS;Index1++) { temp=debounce(Index1); if(temp==1) { Input_TableP1[Index1]=1; } else if(temp==0) { Input_TableP1[Index1]=0; } } } /***************** -- Debounce Port P1 -- *****************/ bit debounce(uint16_t IN_INDEX) { uint16_t INDEX2,ONE=0,ZERO=0; char TEMP,SHIFT_RESULT[3]=0x00; for(INDEX2=0;INDEX2<3;INDEX2++) { TEMP= P1; SHIFT_RESULT[INDEX2]=(TEMP>>IN_INDEX)& 0x01; delay_10micro_sec(); } /* Comparision of 3 values retreived from same pin*/ for(INDEX2=0;INDEX2<3;INDEX2++) { if(SHIFT_RESULT[INDEX2]==1) ONE++; else if(SHIFT_RESULT[INDEX2]==0) ZERO++; } return (ONE>ZERO); }
With Thanks, G.Karthik Ragunath
[I was bored, again...]
This works just fine for debouncing mechanical contacts. This example uses eight samplings and is not exactly a 'majority vote' type, but rather a filter type.
This algorithm is not a new or original one. I don't remember where I got it, but its been around for a while...
//////////////////////////////////////////////////////////////////////////// // // // #define the world according to C // // // //////////////////////////////////////////////////////////////////////////// #define LEADING_ZERO 0x7F // 0111.1111 Used to caputure new-assertions #define ALL_ONES 0xFF // 1111.1111 Used to detect a 'held' state #define LOCK_INPUT (P1_0) // Ref: hardware definition of the button #define BEEP_INPUT (P1_1) // Ref: hardware definition of the button #define LOCK_ASSERTED 0 // Asserted means a logic low (0 volts) #define BEEP_ASSERTED 0 // Asserted means a logic low (0 volts) #define BUTTON_LOCK 1 // For the switch/case construct to access #define BUTTON_BEEP 2 // or select the state of the button #define SARDINE 0 // NOTE: after studying this fish, it #define ERIK (!SARDINE) // is basically impossible to hurt a // sardine's feelings: a hearty fish // that can handle the humor (!Humour). #define TRUE (ERIK) // per erik #define FALSE (!ERIK) // per others //////////////////////////////////////////////////////////////////////////// // // // Allocate the 'global' data-stores // // // //////////////////////////////////////////////////////////////////////////// bit Lock_Signal; // TRUE == Asserted Signal bit Beep_Signal; // TRUE == Asserted Signal bit New_Lock; // TRUE == Newly asserted & Sticky bit New_Beep; // TRUE == Newly asserted & Sticky /* **====================================================================== ** Scan_Buttons **====================================================================== ** ** Read in each bit and shift it into a data-store. This shall form ** a stream of bits representing the 1's and 0's as the signal is ** asserted--complete with the debouncing of the signal: ** ** Stream: 0001110101000111111111111111111111 ** ** The byte value '11010100' as the stream passed through it. ** ** Check for the value of 7Fh where the leading zero represents the ** 'off' state (or one of the last non-asserted value), and the ** 111.1111 part represents a 'steady-state' assertion. ** ** When this is captured (the 7Fh) it occurs once during the sampling ** of the stream and represents a fresh signal assertion. When the value ** is FFh, then it is a continuously asserted signal. ** ** 0001110101000111111111111111111111 ** 00011111 ** 00111111 ** 01111111 = 7Fh = match (newly pressed) ** 111111111 = on (statically held) ** 111111111 = on (statically held) ** ** This requires this routine to be called at an interval which ** can provide the timing resolution expected for system operations. ** **---------------------------------------------------------------------- ** ** Parameters Passed: <void> ** Parameters Returned: <void> ** Notes: ** 1) This is expected to be in an ISR called from a time-base ** ** 2) This algorithm is common and well known (nothing origional) ** ** 3) The lack of new-lines and open/close braces were ** imposed due to the easy addition/deletion of 'buttons' ** **---------------------------------------------------------------------- */ void Scan_Buttons( void ) { /*------------------------------------------------------------------. ; 8-bits of data store for each signal is used for the shifting ; ; process. 8 x (call interval) = max detect time. ; '------------------------------------------------------------------*/ static u8 lock_byte = 0x00; // (legit use of 'at-file-scope') static u8 beep_byte = 0x00; // /*------------------------------------------------------------------. ; Read in the buttons (Signal is #def'd as a port I/O pin) ; '------------------------------------------------------------------*/ if( LOCK_INPUT ^ (!LOCK_ASSERTED) ) lock_byte |= 1; if( BEEP_INPUT ^ (!BEEP_ASSERTED) ) beep_byte |= 1; /*------------------------------------------------------------------. ; Detect the first edge of signal assertion: declare a new signal ; ;-------------------------------------------------------------------; ; We are looking for the front 0 followed by the 1's: 0111.1111 ; '------------------------------------------------------------------*/ if( lock_byte == LEADING_ZERO ) New_Lock = TRUE; // These are sticky- if( beep_byte == LEADING_ZERO ) New_Beep = TRUE; // bits (reset manually) /*------------------------------------------------------------------. ; Check for static state signal ; ;-------------------------------------------------------------------; ; We are looking for all 1s. A static set of 1s = pressed for XmS ; '------------------------------------------------------------------*/ if( lock_byte == ALL_ONES ) Lock_Signal = TRUE; else Lock_Signal = FALSE; if( beep_byte == ALL_ONES ) Beep_Signal = TRUE; else Beep_Signal = FALSE; /*------------------------------------------------------------------. ; Shift them for next iteration ; '------------------------------------------------------------------*/ lock_byte <<= 1; beep_byte <<= 1; }
[continued]
/* **====================================================================== ** Check_Button [ ACCESSOR ] **====================================================================== ** ** Checks if the signal selected is asserted by simply accessing the ** Button_Scan assigned data-stores. ** **---------------------------------------------------------------------- ** ** Parameters Passed: (u8) button number #defined ** Parameters Returned: (bit) TRUE = Asserted ** Notes: ** 1) The lack of new-lines and open/close braces were ** imposed due to the easy addition/deletion of 'buttons' ** ** 2) Doesn't return TRUE upon detection of a new assertion. ** (modify if you need that included) ** **---------------------------------------------------------------------- */ bit Check_Button( u8 button ) { u8 pressed; pressed = FALSE; // although assigned in the switch( ), ensure it here /*------------------------------------------------------------------. ; If the selected input is TRUE, return TRUE (else FALSE) ; '------------------------------------------------------------------*/ switch( button ) { case BUTTON_LOCK: if( Lock_Signal == TRUE ) pressed = TRUE; break; case BUTTON_BEEP: if( Beep_Signal == TRUE ) pressed = TRUE; break; default: pressed = FALSE; break; } /*------------------------------------------------------------------. ; (bit) { TRUE | FALSE } ; '------------------------------------------------------------------*/ return( pressed ); } /* **====================================================================== ** main **====================================================================== ** ** The Ultra-Lame main-line routine to illustrate the [very common] ** debounce algorithm. ** **---------------------------------------------------------------------- ** ** Parameters Passed: <void> ** Parameters Returned: <void> ** Notes: ** ** This was extracted from prior artwork and NOT compiled, ** so if this doesn't compile without errors, I don't care: its ** an example of the algorithm and its usage. This algorithm ** as worked for me in the past, so it might work for you. ** **---------------------------------------------------------------------- */ void main( void ) { bit button; // for testing the state of the button /*------------------------------------------------------------------. ; Initialize the system's states ; '------------------------------------------------------------------*/ Lock_Signal = FALSE; Beep_Signal = FALSE; New_Lock = FALSE; New_Beep = FALSE; /*------------------------------------------------------------------. ; Do it forever ; '------------------------------------------------------------------*/ while( GOD_PARTICLE != FOUND ) { /*--------------------------------------------------------------. ; This is typically put into a timer ISR for a predictable dt ; '--------------------------------------------------------------*/ Delay_X_mS( KEYBOARD_DEBOUNCE_5mS_TICKS ); // you do the routine Scan_Buttons( ); /*--------------------------------------------------------------. ; Is there somebody at the door? ; '--------------------------------------------------------------*/ button = Check_Button( BUTTON_BEEP ); if( button != FALSE ) { beep( ); // Wake up the sentry } /*--------------------------------------------------------------. ; If they are to be 'buzzed in' then do it. ; '--------------------------------------------------------------*/ button = Check_Button( BUTTON_LOCK ); if( button != FALSE ) { Unlock( ); // Button must be held while opening door } else { Lock( ); // make sure it returns to the secured position } } } /*=========================================================================== * END OF MODULE ( Debounce_Example.C ) ===========================================================================*/
(if you do find errors, please let me know).
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA
hmmmm...you know...there is a lot to be said for a resistor and a cap next to the switch!
R
A resistor and a cap will change the behaviour. But if the input pin doesn't have schmitt-trigger, then the bounces can still get the filtered signal to vary enough to make the input signal toggle multiple times between low and high.
As a matter of fact - all uses of external RC filters should be avoided unless the input has hysterese. Not only can you get multiple toggles, you can also get the input to consume a lot of power when floating in the dead zone between a logic high and a logic low.
Besides: A software bug can be corrected by a firmware update. A hw problem - such as too high/low value on a component - is very hard to compensate for. You may have to send the unit in for modification.
The important thing here is that most mechanical switches are quite easy to debounce since the bounce time is short in relation to the expected number of switch activations/second. And since the debounce is so easy to do in software, there is no real need to figure out ways to let the hardware help.
As a matter of fact - all uses of external RC filters should be avoided unless the input has hysterese. one more reason to avoid RC filters is that it slows down the input. Many moons ago (before the micro, with a mini) I did some investigation on RC filtering and found that (for this particular app, how general I do not know) sufficient RC filtering made the thingy fail to respnd to the "fastest fingers"
And since the debounce is so easy to do in software, there is no real need to figure out ways to let the hardware help. I second that opinion
Erik