Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Button Debounce Coding help

Status
Not open for further replies.

Suraj143

Active Member
Hi I want to debounce my button without a flag bit.Here is the coding but its not working well.

SHOW contains displaying digit stuff in the segments.

Code:
	btfsc	PORTA,0		;check the button is pressed?
	goto	SHOW		;NO its not pressed then display the digits
	call	DEL50mS		;YES its pressed then add a small debounce delay
	btfss	PORTA,0		;check the button has it released?
	goto	SHOW		;NO then again show the digits
	goto	COUNTUP		;YES it has released then count up
 
You are using active low, aren't you?
I always use 100 ms for debouncing without any problem, with tact switch.
What switch are you using?
What happen when don't press anything and what happen when you press only once?
 
Yes I’m using active low.

When I press nothing it shows the “0000” in the segments.
But when I press its counting in a messy way.

I’m using micro switches

Is my code right?
 
Maybe you can't release the switch fast enough? Try to increase the delay and see whether it helps.
I do this way usually:
Code:
	btfsc	PORTA,0		;check the button is pressed?
	goto	SHOW		;NO its not pressed then display the digits
	call	DEL50mS		;YES its pressed then add a small debounce delay
	btfss	PORTA,0		;check the button has it released?
	[b]goto	$-1		;nothing happen unless it is released[/b]
	goto	COUNTUP		;YES it has released then count up
 
Is the displays getting off while the button is press & hold time?

It's displaying after the button released isn't it?
 
bananasiong said:
So, the label SHOW is not in the interrupt vector? Have you tried increasing the delay?

Hi I will try to increase the delay & see.

Can you tell a 62uS Delay is it a good or a bad delay for button debouncing.
 
Here's one thing to keep in mind:
Say your button could bounce for 62uS. What if the person holds down the button for 100mS, then lets go? Typically off-bounce is not the same issue but I've never ruled it out- what if the delay expires, he lets off the button, and it goes off then on again then finally off for real, that would end up erroneously being detected as a second press.
 
Oh I see 62uS is too low value.Because it expires as soon if the user has press & hold on the button too long.I must try with a 100mS delay.

But for a 62uS delay I'm already checking the button has released so the small delay wont expire.

Am I right?
 
Suraj143 said:
Oh I see 62uS is too low value.Because it expires as soon if the user has press & hold on the button too long.I must try with a 100mS delay.

But for a 62uS delay I'm already checking the button has released so the small delay wont expire.

Am I right?

Not quite. The user might hold it for 500mS or any number really.

The procedure I've done:
Wait for button press, then take the action you take for a press and start the on-debounce counter. During this period further transitions will not be counted.
At the end of the debounce count if the button is still pressed, wait for it to be released.
When the release is detected, start the off-debounce counter.
At the end of the off-debounce period, if it's pressed take the actions you take for a press again. Otherwise wait for a new button press.

Debounce time varies greatly with the quality of the switch.
 
I agree with Oznog. Its good to wait till button is released either before or after calling a function. The debounce time is switch dependent and environmental. I always filter and debounce, though filtering is not needed for tact switches. Generic mouse button type tacts produce good clean signals.

By the way, calling a button press function first and then processing the button release afterwards is a sign of incredible natural ability or years of good experience. So Oznog, which one are you?


If you truely wish to understand what is going one, take an observation of the switch signal with an O-scope.
Below are captures of a regular 4-pin pushbutton mouse style tact switch. Notice the very fast and relatively clean rise time.
There is actualy more noise after the button is pressed than during the act of pressing and releasing (not captured) yet still very clean.
**broken link removed**
Animated GIF file above. Must "Instruct" Internet Explorer 7 to "Allow" animation if you use IE 7 and do not see the animation.
 
Last edited:
Wow what a video thanks donniedj I now understand.I applied Oznog codings it comes like this

Code:
	btfsc	PORTA,0		;check the button is pressed?
	goto	SHOW		;NO its not pressed then display the digits
	call	DEL500mS	;YES its pressed then add a small debounce delay
	btfss	PORTA,0		;check the button has it released?
	goto	SHOW		;NO then again show the digits
	goto	COUNTUP		;YES it has released then count up

But the problem is when increase the debounce delay time when i press the button & hold the segment displays going dim.When i reduce the debounce delay it counts up in a messy way.

can you tell me is my coding right & what modifications to be done?
 
donniedj said:
I agree with Oznog. Its good to wait till button is released either before or after calling a function. The debounce time is switch dependent and environmental. I always filter and debounce, though filtering is not needed for tact switches. Generic mouse button type tacts produce good clean signals.

By the way, calling a button press function first and then processing the button release afterwards is a sign of incredible natural ability or years of good experience. So Oznog, which one are you?
I guess it's natural. Say, do you have some scope captures of a button turning off?

Incidentally, SOME applications take action on the button release, for good reason, and the user almost never notices.
For example, on an iPod if you press the (I think this is what it is) play button once it plays the track you're on, but if you hold it for 1 sec then it turns on the backlight and does NOT take that as a "play" instruction. Hmmm... how does it know not to play when you press the button? Like I say, it starts a counter when it detects a button press (debounces) counts the pressed time and if the counter reaches 1 sec then it turns on the backlight and forgets the play instruction. If the button is released before 1 sec then it'll take it as a play instruction and forget the backlight instruction. Turns out nobody holds down a button that long without a specific reason and pressing under 1 sec is so short that you won't notice the track starts on the release rather the the press.

This also gets used for some "soft reset" conditions. If your device gets in a funky state but the ISRs are still working, there's often like 2 buttons you hold down together for 3 sec to force a reset. Yet you may not want the device to take the actions those 2 buttons normally cause.
 
Suraj143 said:
Wow what a video thanks donniedj I now understand.I applied Oznog codings it comes like this

Code:
	btfsc	PORTA,0		;check the button is pressed?
	goto	SHOW		;NO its not pressed then display the digits
	call	DEL500mS	;YES its pressed then add a small debounce delay
	btfss	PORTA,0		;check the button has it released?
	goto	SHOW		;NO then again show the digits
	goto	COUNTUP		;YES it has released then count up

But the problem is when increase the debounce delay time when i press the button & hold the segment displays going dim.When i reduce the debounce delay it counts up in a messy way.

can you tell me is my coding right & what modifications to be done?
It is because during the period you press and hold, no multiplexing is happening because it is looping in the delay routine. But if you reduce the debounce delay time, it is not enough for it to debounce, causing it counts up many times (I think so).
Why don't you put the display routine in the ISR? So you don't need bother about the displaying.
 
Hi banansiong I’m not familiar with much more ISR.
I applied your codings too replacing the goto SHOW with goto $-1 after btfss command.

That worked well but within the button pressed time the whole display is going off that is better without dimming the display.

But I still trying to have a smooth count in my coding without going to ISR.
Any suggestions will be greatly appreciated.
 
It's worthwhile to ask just what's so bad about making a debounce period longer than necessary? Well, if it's too long a second press would get interpreted as a bounce and ignored. But then who presses a button 10 or even 5 times a second? Probably advancing through a list of mp3 tracks or scrolling down a display, or- wait I know- advancing the alarm on a digital clock once you've let off the spin it does when you hold it down and need to step it minute-by-minute. Not sure how fast those are. Note that some buttons won't even pop back up fast enough to be pressed at such a frenetic pace.

Sometimes you get a crappy button in a bag of them, or one gets bouncier as it ages. As such it may be a good idea to figure out at what point is it possible that the debounce time will miss valid presses and set it substantially less than that, so it can be as tolerant as possible to bouncing.
 
You can use your show routine as a debounce delay.

Code:
loop		call	SHOW
		btfsc	PORTA,0
		goto	loop;	not pressed so wait
; is pressed
		call	COUNTUP
loop1		call	SHOW
		btfss	PORTA,0
		goto	loop1;	still pressed, so wait

		goto	loop

Mike.
 
Suraj143 said:
Hi banansiong I’m not familiar with much more ISR.
I applied your codings too replacing the goto SHOW with goto $-1 after btfss command.

That worked well but within the button pressed time the whole display is going off that is better without dimming the display.

But I still trying to have a smooth count in my coding without going to ISR.
Any suggestions will be greatly appreciated.

ISRs can implement the debounce in one of two ways- set a timer resource (all have ISRs associated with them), when the timer counts down reenable the ability to react to a press. Bad part is that unless you pull some fancy coding you need one timer per button and this can be a problem.

The other possibility is to have a timer that expires say every 25mS. The timer ISR decrements the debounce timer and reenabled the button at zero. So when you detect a press you might set the counter to 3 for a 75mS debounce time. Downside is that the period of the first count is uncertain because the counter is already running when the button is pressed- it might make a debounce period of 51mS to 75mS in this case. Frequent interrupt tend to eat up the processing time esp if you're running low freq clocks. They also mean you can't use SLEEP mode mid-code to save power. We could pull a trick to disable the timer if no debounce counter needs to be decremented, a really good idea actually, you just need to be very careful with what you're doing.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top