View Full Version : About to cry!!

09-22-2007, 12:36 AM

I've been pulling my hair out over the last few days trying to software debounce a switch. I've had my Prop for about two weeks now and i've got it hooked up to a HD44780 screen, a couple of LED's and a single solitary extremely annoying switch!

I had similar problems with debouncing on a PIC chip so i expect i should just try to make projects that don't involve any user input!!

Anyhoo, i've taken a gander on the internet and found a couple of approaches one of which is to count while the switch is pressed and reset when not and if the counter reaches some safe value then i can say that the button is pressed. I've tried this and it sorta works except i get a delay after releasing the button before my button flag returns to 0. I've also noticed when tying an LED to this button 1/0 event that it flickers a bit before finally going out which suggests that bouncing is still occurring.

I am using ina[pin] to read the switch and the switch itself is connected to +3v. Is this correct or am i going about it backwards?

Any help appreciated.

Mike Green
09-22-2007, 12:51 AM
1) It's usually a bad idea to connect a Propeller pin directly to Vdd (+3.3V) or to ground for that matter. If there's a bug in your program and you set up that I/O pin as an output, it will be grounded and you'll have a short circuit if the switch is closed. On most microprocessors, you'll burn out the I/O circuitry on that pin. The Propeller seems to be more robust than most and will probably survive this, but don't count on it! The safe thing to do is to use a 220 ohm series resistor on the I/O pin.

2) There will always be some bounce in any mechanical switch. A simple way to debounce a switch is to look for the off-on transition (ina[pin] was zero earlier, now it's one). Wait for a reasonable debounce time (maybe 50ms), then check to make sure the switch is still closed. If not, then ignore the whole thing. The same thing happens to a lesser extent when the switch is released.

Chad George
09-22-2007, 12:52 AM
I usually have the input pin pulled up to 3.3v through a resistor 10K or so.
The switch is connected so it pulls the input pin to ground.


sorry its not as pretty as some people's ascii schematics.


Graham Stabler
09-22-2007, 12:56 AM
So the best option would be to combine Chad's idea with Mike's. You need a pull up resistor to define the input voltage when the switch is open but a limiting resistor in series will prevent problems if you load the wrong program etc.

I suspect your main problem is not having a pull up resistor, it can cause a lot of confusing problems.


Chad George
09-22-2007, 01:04 AM
Mike said...
If there's a bug in your program and you set up that I/O pin as an output, it will be grounded and you'll have a short circuit if the switch is closed.

As usual Mike brings up a good point here.

I haven't had that kind of "bug" yet, but it certainly could happen. Better put a series current limiting resistor in there just to be safe.

- Chad

09-22-2007, 01:08 AM
Thankyou Mike, Chad and Graham. I had tried a resistor but obviously hadn't used it correctly. It now works much much better. A bit of software tweaking is still required but it's whole lot better now. Cheers.

Fred Hawkins
09-22-2007, 01:21 AM
What happens with Chad's example when the prop sets the pin to·an output·as per Graham's caution?
("Or to ground for that matter. If there's a bug in your program and you set up that I/O pin as an output, it will be grounded and you'll have a short circuit if the switch is closed.")

Mike Green
09-22-2007, 01:33 AM
By default, the Propeller pins are set up as inputs and, if changed to output, the level is low (ground). The same bug could set the level to high (3.3V). Chad's example would also potentially cause a short circuit. It's almost always helpful to use a series resistor like 220 ohm on any Propeller pin that could be connected to another output or power supply voltage, particularly when you're debugging a program. Fortunately, if you're pretty sure of your code or it's a production system or there's some specific reason why a series resistor will cause problems, you can rest easier knowing that it's hard to damage a Propeller I/O pin structure.

09-22-2007, 02:35 AM
Of cause there is also some paranoia in it http://forums.parallax.com/images/smilies/smile.gif When the switch is open, no harm will be done with a 10k pull-up. When the switch is pressed for a long time AND the pin is set to output AND high , than it could demage the Prop. This should be rare....
I personally would NOT use an additional serial resistor in this context...

Fred Hawkins
09-22-2007, 04:44 AM
Thanks Graham et al. I've been adding switches to the PE kit (guided by lab schematics) without any problems but also without any consideration of these niceties. Left on my own I would have surely found the elusive source of magic smoke.

09-22-2007, 08:21 PM
Debounce it hardware,cross coupled NAND or Schmitt Trigger?

09-22-2007, 10:33 PM
Never! Use software http://forums.parallax.com/images/smilies/smile.gif

Mike Green
09-22-2007, 11:19 PM
That's not fair! There are always circumstances where external hardware may be cheaper, more efficient, more reliable, etc. than doing it all in software just as there are circumstances where it's cheaper, more efficient, and more reliable to do it all in software. For example, the Propeller does not have Schmitt Trigger type inputs. If you truly have slowly changing inputs, it's much better to handle the signal conditioning in hardware than trying to imperfectly approximate it in software. If you're short of I/O pins, it may be simpler and cheaper to use a cross coupled NAND gate with a SPDT switch for debouncing rather than tie up two I/O pins per switch or use some kind of serial shift register for input expansion.

Ken Peterson
09-22-2007, 11:39 PM
I've used RC filters on switches for debouncing before. It slows response time a bit, but for user input it's probably negligible. If you have a scope handy to see how long your switch bounces, just choose a RC delay longer than that.



The more I know, the more I know I don't know.· Is this what they call Wisdom?

09-23-2007, 02:03 AM
You are right - I am unfair, and your counter examples are well chosen. However I am a SW man - and I have learnt a little bit hardware 20 years ago just to become able to convince my EE-colleagues that they need only half of the hardware they deemed necessary http://forums.parallax.com/images/smilies/smile.gif

I think we have discussed debouncing many times....

Fact is, there is no need at all to have a "clean" signal from a switch in the first place. So let it bounce!

What you need in software is some intelligence (6 to 12 aditional instructions). True, there can be situations where this is not possible...

What is "bouncing" viewed as signal behaviour? It is a train of pulses (0.1 to 100 ms) before the signal becomes stable during a CLOSING action.

What is software debouncing assumed to do:
(1) Asume the switch is closed during this debounce-time
(2) There is no second...

I did not check the following code, I used a similar piece some monthes ago, but for multiple switches, which looks too confusing...

PUB getSwState:swPressed
' Needs to be called at least once in 20 seconds to get along with clock overflow
' Switch is still reported "ON" for further swDebounceConst ticks after the previous
' call of this routine, even if it has been released in the meantime

IF INA[swPin]
swDebounceCnt := CNT
IFNOT swDebounceCnt ' avoid zero as we use this as an "active" flag as well

IF swDebounceCnt AND CNT- swDebounceCnt < swDebounceConst
swPressed := TRUE
swDebounceCnt :=0

'--- end of rotine getSwState

After looking at this code for 10 minutes now, I think the swDebounceCnt flag is not really necessary, as when you do not call this routine within 20 seconds it will not work reliably anyhow...

PUB getSwState:swPressed
' Needs to be called at least once in 20 seconds to get along with clock overflow
' Switch is still reported "ON" for further swDebounceConst ticks after the previous
' call of this routine, even if it has been released in the meantime
' Simplified version...

IF INA[swPin]
swDebounceCnt := CNT

IFNOT swPressed := CNT- swDebounceCnt < swDebounceConst
swDebounceCnt := CNT - swDebounceConst

The Problem with this second version is, swDebounceCnt must be preset correctly (CNT-swDebounceConst) rather than to 0... this is awkward....

Post Edited (deSilva) : 9/22/2007 7:47:44 PM GMT

09-23-2007, 09:56 AM
Hi All,
As usual I agree with all of you, but for a quick and ( dirty? ) fix go
with the hardware, then when its running do the software fix.
Sorry to all ( ex hardware engineer )

Yes Da Silva great S/W solution but does he need it
if you're trying to unroll a tight loop and constrained by CPU time
you don't need to be waisting time looping on a pin state.???

Best Regards
Ian :- If it aint broke don't fix it

09-23-2007, 10:11 AM
JUST NOTICED I GOT DeSilva's handle wrong
Many Apologies

Best To All

09-23-2007, 01:42 PM
IAN, you can edit your posts, press the no-bouncing icon (the one with a pencil on it) on the top-right corner of your post, you can add a note to what you modified, if you want http://forums.parallax.com/images/smilies/smile.gif.

I never used the HW version, but the software one, in the case of the propeller, can be done with a separate COG, and some waitcnt to put it to sleep between counts, besides being waked up by waitpeq or waitpne.

09-23-2007, 01:53 PM
Here's a link to a nice paper on switch debouncing - hardware and software examples included:

www.ganssle.com/debouncing.pdf (http://www.ganssle.com/debouncing.pdf )



09-23-2007, 02:58 PM
Hi Matb_uk

Hereby a cool link to a interesting document re deboucing swithces

Well worth downloading and having a good read.


Ronald Nollet·· Australia

09-23-2007, 03:02 PM
Yes, I generally give this link everytime debouncing comes up -- tired of it now http://forums.parallax.com/images/smilies/smile.gif

Graham Stabler
09-23-2007, 03:06 PM
If something is worth recommending its worth recommending thrice :)

thanks for the link


09-23-2007, 03:21 PM
@Ale: You are probably overdoing....
All "real time" processing is a matter of "need to know". We generally tend "to be prepared" for situations that rarely will happen and being much too fast (in engineering i.e., not in politics http://forums.parallax.com/images/smilies/smile.gif )

So when you need to react IMMEDIATELY to a button press, then use a COG (has nothing to do with debouncing in the forst place)

But generally "polling" will do.. So what happens when you just start in a gap during the bouncing? You will not "see" the press. But you won't do either when you load one of those little caps generally proposed http://forums.parallax.com/images/smilies/smile.gif

The reason behind debouncing is that you not unintentionally mistake a "gap" for a "release".

My very small (!) SW solution is handicapped by the fact that CNT "aliases" after 40 (I think 40, not 20..) seconds. this will most likely be no problem at all.


When talking of the use of an independant COG, then a "General Timer Action" would be nice (e.g. resetting a regsietered HUB cell after a defined time less or MUCH larger than 40 seconds).

This is one of the ideas behind a "Small Utility COG" (SMUC) I haven't tracked further during the last monthes :-(

09-25-2007, 07:06 AM
Thanks for the heads up on editing ALE

Best Regards Ian.

09-29-2007, 10:27 AM
Put a small capacitor in parallel with the switch. Take a look at tau =RC time constant to make sure it's in the right order with everything else.

Peter Jakacki
09-29-2007, 12:13 PM
Take a look at this circuit that I suggested once before in this group. It is a very simple circuit that does not rely on software catching the keypress but instead is self-latching and debouncing. How is this?

The circuit relies upon the capacitor being charged via the resistor which means the I/O has to become a high output long enough to charge the capacitor and then it can release the I/O line (become an input). The self-discharge of the cap is relatively slow so that if the prop checks the I/O pin as an input it should be high. If it is high it can optionally refresh the charge on the cap. If it is low then it means the button has been pressed since the last check as the button discharges the cap and there is nothing to recharge it as the 10K is not sourcing current.

You may find if you don't refresh the charge that it may actually hold the charge for several seconds or more.

The 10K resistor can just as easily be a 100R resistor, it really doesn't matter. The lower value will charge the cap faster, the higher value will perhaps protect the input a bit more from ESD (as does the cap).

As I have said previously, this circuit is super-simple yet very reliable and can be handled easily even by slow-polling software.

What does everyone think?


___ 10K
.------------|___|--------- I/O
| |
| o ---
|=|> ---
| o | 0.1uF
| |
(created by AACircuit v1.28.6 beta 04/19/05 www.tech-chat.de)

Mike Green
09-29-2007, 12:19 PM
It's nice and simple. Thanks for posting it.

09-29-2007, 01:50 PM
Its also one extra part....

Peter also handles debouncing, but in the first place he addresses "missing presses" which is quite another issue.

A 1k will generate a latency of 100ms - you can press faster; 1k will be best, but I should rather reduce the cap, as 0,1u is a lot of charge - discharged abruptly.

Attention: The idea to place the other end of the press button directly at the I/O rather than between cap and resistor is not so good, as it would lead to a short when you press the key whilst the circuit is charging..

BTW: My personal philosophy is to do in hardware what can't be done in software and not do in software what cannot easily be done in hardware http://forums.parallax.com/images/smilies/smile.gif But also to know both worlds!

Post Edited (deSilva) : 9/29/2007 6:55:44 AM GMT

Peter Jakacki
09-29-2007, 05:35 PM
Many switches are simple plated contacts that can develop a film that degrades the contact resistance. The solution is simple, apply enough current to the contacts at closure to "vaporise" the film www.allaboutcircuits.com/vol_4/chpt_4/2.html (http://www.allaboutcircuits.com/vol_4/chpt_4/2.html). The capacitor in this circuit does this nicely and keeps those contacts clean.

As to sensing multiple key presses that is totally up to the software as to how often it will be polled. If you don't poll it often enough then you still know whether it has been pressed or not when you do get around to polling it.

If you want to scan keypads then this is not the usual way to do it, but if you want to sense momentary switch closures this surely is the simple and elegant way.

Any values given are purely for illustration of principal. Personally I would use 0.01uF and 220R which would result in only a microsecond or two of charging.


Ken Peterson
09-29-2007, 09:04 PM
I find, as an engineer, that there are many solutions to a problem and one can argue about which one is "correct". At the end of the day, it depends on the application and what your requirements are. There is usually no "one size fits all" solution. It is important to understand the pros and cons of each solution so you can choose the best fit for your application.


The more I know, the more I know I don't know.· Is this what they call Wisdom?

11-09-2007, 05:26 AM
Brownouts or or heavy loads on logic circuits can cause weird things to happen. To be safe always add the resistors to I/O pins.

http://forums.parallax.com/forums/undefinedhttp://forums.parallax.com/forums/undefinedhttp://forums.parallax.com/forums/undefinedhttp://forums.parallax.com/forums/undefinedSteven Kirk Nelson (slamer)

Team K.I.S.S
Build Safe, Build Mean, Build Strong!