Software Debouncing

Thread Starter

ke5nnt

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

wmodavis

Joined Oct 23, 2010
739
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.
 

ErnieM

Joined Apr 24, 2011
8,377
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.
 

takao21203

Joined Apr 28, 2012
3,702
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.
 

joeyd999

Joined Jun 6, 2011
5,287
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:
;******************************************
;** POLLSWITCH -- Poll pushbutton switch **
;******************************************

pollswitch

	bcf	fswp		;clear pressed flag
	bcf	fswr		;clear released flag
	bcf	fswpr		;clear press and release flag
	bcf	fswph		;clear press and hold flag
	bcf	fswrp		;clear press and repeat flag
	bcf	fswdc		;clear double click flag

	retbc	tc8ms		;process switch every 8ms

	movf	swdtimer,f,1	;double click timer running?
	skpz
	decf	swdtimer,f,1	;yes, update it

	clrc			;pre-clear carry
	btfss	button		;switch pressed?
	setc			;yes, set carry
	rlcf	swhist,w,1	;rotate into history
	andlw	b'1111'		;keep only 4 tests
	movwf	swhist,1	;save history

	bz	pswup		;z flag set if swithc up for history
	xorlw	b'1111'		;test for pushed whole history
	bz	pswdn		;z if switch down for history

;position either up or down from last pass

pswtran	bbc	fswst,pswsup	;switch still up (released)
	bra	pswsdn		;switch still down (pressed)	 

;position up in current pass

pswup	bbc	fswst,pswsup	;switch still up

;switch just transitioned to up (released) position

	bcf	fswst		;clear switch current state
	bsf	fswr		;indicate switch released

	movf	swhtimer,f,1	;key press time running?
	skpz			;z if not
	bsf	fswpr		;yes, indicate press and release (otherwise, was press and hold)	

	clrf	swhtimer,1	;clear switch press and hold timer
	clrf	swrtimer,1	;clear switch press and repeat timer

	return			;done (no timer to process)

;switch is still released (no change since last pass)

pswsup	return			;nothing to do

;position down in current pass

pswdn	bbs	fswst,pswsdn	;switch still down

;switch just transistioned to down (pressed position)

	bsf	fswst		;set switch current state
	bsf	fswp		;indicate switch just pressed
	bsf	fswrp		;first pulse of repeat, also

	movlfb	swhtimer,cswpht	;set up press and hold timer

	movf	swdtimer,f,1	;double-click timer running?
	skpz
	bsf	fswdc		;yes, signal double click

	movlfb	swdtimer,cswdct+1 ;and reset double-click timer

	return			;and get out

;switch is still pressed (no change since last pass)

pswsdn	movf	swhtimer,f,1	;is hold timer already zero?
	bz	pswrpt		;yes, process repeat timer

	decfsz	swhtimer,f,1	;decrement hold timer
	return			;nothing to do if not expired

	bsf	fswph		;indicate switch pressed and held
	bsf	fswrp		;and second pulse of repeat
	bra	pswsrpt		;go set repeat timer

pswrpt	decfsz	swrtimer,f,1	;decrement repeat timer
	return			;nothing to do if not expired

	bsf	fswrp		;nth pulse of repeat

pswsrpt	movlfb	swrtimer,cswprt	;reload press & repeat timer

	return
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
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,
 

takao21203

Joined Apr 28, 2012
3,702
lowpass

Code:
unsigned char key_tst(unsigned char k){
    if(k==0){if(!(v_leds&0x04))k++; return(k);}
    if(k==1){if(v_leds&0x04)k++; return(k);}
}
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
 
Top