Electronic – PIC12F509 Switch Debouncing On Press Release Or Both

microcontroller

I have a question regarding switch debouncing I'm using a PIC12F509 and the internal RC oscillator operating at 4 MHz.

I'm toggling an LED on and off connected to GP1 (output) via a momentary push button switch on GP3 (input) which is held high via a 10K resistor when the switch is open. I'm using the following macro and the code below to debounce the push button switch. It utilizes timer 0 set to a 1:256 prescale.

It waits until the contacts have remained in the same state (open in this case) for 10 milliseconds before executing the rest of the code. If they bounce (go low) timer 0 gets reset.

DbnceHi     MACRO    port,pin
local       start,wait,DEBOUNCE
variable    DEBOUNCE=.10*.1000/.256 ; debounce count = 10ms/(256us/tick)

    pagesel    $ ; select current page for gotos
    start      clrf TMR0 ; button down, so reset timer (counts "up" time)
    wait       btfss port,pin ; wait for switch to go high (=1)
    goto       start
    movf       TMR0,w ; has switch has been up continuously for
    xorlw      DEBOUNCE ; debounce time?
    btfss      STATUS,Z ; if not, keep checking that it is still up
    goto       wait

    ENDM

main_loop
; wait for button press

wait_dn   btfsc GPIO,3 ; wait until button low
goto      wait_dn

; toggle LED
movf      sGPIO,w
xorlw     b'000010' ; toggle shadow register
movwf     sGPIO
movwf     GPIO ; write to port

; wait for button release
DbnceHi     GPIO,3 ; wait until button high (debounced)

; repeat forever
goto     main_loop

END

Now onto my question up until now I've been debouncing both the button press and release. It's been brought to my attention in the tutorial I'm following that it's not normally necessary to debounce both the press and release of a switch.

I can understand why in theory because after the switch is read as low via the btfsc instruction (even if it's momentarily because the contacts are bouncing). The LED is toggled and the debounce high code will wait until the contacts have opened and stopped bouncing before executing the goto to loop the code from the beginning.

On the positive side this saves program memory. But if something seems too good to be true it usually is what are the potential pitfalls using this method?

Obviously for a simple application like this the code is overkill. But for something more critical like putting the PIC in sleep mode and waking up from a pin change any bounce must be eliminated in order for the micro to enter the leave sleep mode reliably.

What are your opinions on switch debouncing do you debounce the press and release or only one?

My guts telling me to go belt and suspenders and just debounce both to be safe but I have no logical reason for it.

Best Answer

Mechanical switches bounce on both transitions. The bouncing on opening is usually shorter than on closing, but can certainly happen.

I generally use 50 ms debounce time in both directions. A long time ago, I tested a bunch of pushbuttons. Most stop bouncing in 10-15 ms, but some took much longer, like 40 ms. I settled on 50 ms since that seemed to be long enough to be safe with just about any switch unless you deliberately try to keep it at the transition. I also did some testing on human delay perception, and concluded that 50 ms was about the limit you can get away with without the delay being noticed, unless perhaps someone is specifically looking for it.

Most microcontroller projects have a 1 ms periodic interrupt for other reasons anyway, so I usually add debouncing code to that. I keep a counter and a global flag for each switch. The flag indicates the current debounced state of the switch, which is what all the application code uses as the switch state. The counter is private to the interrupt routine. It is set to 50 whenever the actual switch state matches the debounced state, and decremented by 1 when they differ. When the counter reaches 0, the switch becomes officially debounced in the new state, and of course the counter is reset to 50 since now the switch and the debounced state agree.

I have used this basic approach in many microcontroller projects, and haven't had any trouble with bouncing buttons or users complaining (or even noticing) the 50 ms delay.