Software Debouncing

Discussion in 'Programmer's Corner' started by ke5nnt, Jan 19, 2015.

  1. ke5nnt

    Thread Starter Active Member

    Mar 1, 2009
    384
    15
    I am curious for those of you that do your button debouncing in software, what method you use to do it?
     
  2. wmodavis

    Well-Known Member

    Oct 23, 2010
    737
    150
    Read the port several times in relatively short succession and only when the results are unchanged for some number of those multiple reads do you consider the button to have changed state.
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    I read my button port every 25mS. If two sucessive reads agree I declare it stable, and place that in a global variable. The current reading is also placed in the previous reading variable so I can do this over and over and...

    For the buttons I use this does not glitch yet is quite responsive to the user.
     
  4. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    Technically, you need a lowpass, it can be done quite efficient and using little codespace.

    The best way is to call the code in regular intervals, typically 20mS or so, can be much slower but if it is too fast, you dont catch all bounces.

    I place the digital reading into a global flag, and pass the key variable to the key test function, later all key variables are tested. For a number of keys this produces only very little code.
     
  5. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,699
    906
  6. joeyd999

    AAC Fanatic!

    Jun 6, 2011
    2,689
    2,750
    Here's some PIC18F code that I've got for a single pushbutton.

    Features include full debounce, press, release, press & release, hold, repeat, double-click

    Code (Text):
    1.  
    2. ;******************************************
    3. ;** POLLSWITCH -- Poll pushbutton switch **
    4. ;******************************************
    5.  
    6. pollswitch
    7.  
    8.     bcf fswp        ;clear pressed flag
    9.     bcf fswr        ;clear released flag
    10.     bcf fswpr       ;clear press and release flag
    11.     bcf fswph       ;clear press and hold flag
    12.     bcf fswrp       ;clear press and repeat flag
    13.     bcf fswdc       ;clear double click flag
    14.  
    15.     retbc   tc8ms       ;process switch every 8ms
    16.  
    17.     movf    swdtimer,f,1    ;double click timer running?
    18.     skpz
    19.     decf    swdtimer,f,1    ;yes, update it
    20.  
    21.     clrc            ;pre-clear carry
    22.     btfss   button      ;switch pressed?
    23.     setc            ;yes, set carry
    24.     rlcf    swhist,w,1  ;rotate into history
    25.     andlw   b'1111'     ;keep only 4 tests
    26.     movwf   swhist,1    ;save history
    27.  
    28.     bz  pswup       ;z flag set if swithc up for history
    29.     xorlw   b'1111'     ;test for pushed whole history
    30.     bz  pswdn       ;z if switch down for history
    31.  
    32. ;position either up or down from last pass
    33.  
    34. pswtran bbc fswst,pswsup    ;switch still up (released)
    35.     bra pswsdn      ;switch still down (pressed)     
    36.  
    37. ;position up in current pass
    38.  
    39. pswup   bbc fswst,pswsup    ;switch still up
    40.  
    41. ;switch just transitioned to up (released) position
    42.  
    43.     bcf fswst       ;clear switch current state
    44.     bsf fswr        ;indicate switch released
    45.  
    46.     movf    swhtimer,f,1    ;key press time running?
    47.     skpz            ;z if not
    48.     bsf fswpr       ;yes, indicate press and release (otherwise, was press and hold)   
    49.  
    50.     clrf    swhtimer,1  ;clear switch press and hold timer
    51.     clrf    swrtimer,1  ;clear switch press and repeat timer
    52.  
    53.     return          ;done (no timer to process)
    54.  
    55. ;switch is still released (no change since last pass)
    56.  
    57. pswsup  return          ;nothing to do
    58.  
    59. ;position down in current pass
    60.  
    61. pswdn   bbs fswst,pswsdn    ;switch still down
    62.  
    63. ;switch just transistioned to down (pressed position)
    64.  
    65.     bsf fswst       ;set switch current state
    66.     bsf fswp        ;indicate switch just pressed
    67.     bsf fswrp       ;first pulse of repeat, also
    68.  
    69.     movlfb  swhtimer,cswpht ;set up press and hold timer
    70.  
    71.     movf    swdtimer,f,1    ;double-click timer running?
    72.     skpz
    73.     bsf fswdc       ;yes, signal double click
    74.  
    75.     movlfb  swdtimer,cswdct+1 ;and reset double-click timer
    76.  
    77.     return          ;and get out
    78.  
    79. ;switch is still pressed (no change since last pass)
    80.  
    81. pswsdn  movf    swhtimer,f,1    ;is hold timer already zero?
    82.     bz  pswrpt      ;yes, process repeat timer
    83.  
    84.     decfsz  swhtimer,f,1    ;decrement hold timer
    85.     return          ;nothing to do if not expired
    86.  
    87.     bsf fswph       ;indicate switch pressed and held
    88.     bsf fswrp       ;and second pulse of repeat
    89.     bra pswsrpt     ;go set repeat timer
    90.  
    91. pswrpt  decfsz  swrtimer,f,1    ;decrement repeat timer
    92.     return          ;nothing to do if not expired
    93.  
    94.     bsf fswrp       ;nth pulse of repeat
    95.  
    96. pswsrpt movlfb  swrtimer,cswprt ;reload press & repeat timer
    97.  
    98.     return
    99.  
    100.  
    101.  
     
  7. ke5nnt

    Thread Starter Active Member

    Mar 1, 2009
    384
    15
    Thanks all for your replies and inputs on the subject. I have seen that article from Ganssle before and read it thoroughly. I find that my knowledge to this point limits my understanding of his software methods in their entirety, though I'm sure with more time on it looking up some of the details I'm missing I could figure it out.

    All of your software methods seem to match the general results found when you google for software switch debouncing. At least we know that there is a general practice of polling the input to look for consistency. Thanks again for the insight Gents.

    Regards,
     
  8. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    lowpass

    Code (Text):
    1.  
    2. unsigned char key_tst(unsigned char k){
    3.     if(k==0){if(!(v_leds&0x04))k++; return(k);}
    4.     if(k==1){if(v_leds&0x04)k++; return(k);}
    5. }
    call in appropiate intervals, passing the key variable

    it's 2 when the key was pressed + released again.
    Need to reset to zero + need to initialize to zero before first use.

    v_leds&0x04 is the expression for the IO bit
     
    ke5nnt likes this.
Loading...