De-bounce Button - Page 1
Forum section: electronics / projects

author: ksmccausland
author_rank: Newbie
timestamp: September 29, 2016, 08:47:39 pm
content: Wondering what people's thoughts are on different button de-bouncing circuits. Would like to keep it simple with stuff I have on hand, ie caps and resistors, and simpler than a full Schmitt trigger as at this point I'm tempted to just buy the IC. Avoiding doing it in software to keep my loop speed high for sampling.

author: Kleinstein
author_rank: Super Contributor
timestamp: September 29, 2016, 08:54:48 pm
content: You can't beat the SW solution on part's count and PCB area. So today it is usually the Sw way. If done right there is not much overhead for de-bouncing.Analog solutions with filter and schmidt trigger usually slow down the signal.There is also the possibility of using sampling, so flipflops and a clock, very much like the SW solution. This could be simpler, especially if there is a clock source like a µC or inside an FPGA.

author: Zero999
author_rank: Super Contributor
timestamp: September 29, 2016, 09:07:24 pm
content: If you're not using programmable ICs then what's wrong with a Schmitt trigger plus an RC circuit? The 74HC14 will do. If space is a problem, then there are single (74HC1G14), dual (74HC2G14) and triple (74HC3G14) gate packages.

author: Fungus
author_rank: Super Contributor
timestamp: September 29, 2016, 09:16:24 pm
content: The software solution is always best.You don't need to block your loop. Just make sure the switch is closed for a minimum amount of time (eg. 1ms). If you're 'sampling' then base the time on the period of your sampler loop.(and don't use interrupts, that never works out well...)

author: KerryW
author_rank: Regular Contributor
timestamp: September 29, 2016, 09:59:21 pm
content: There are a couple of ways to do it so that detecting a switch push is still very fast.Hardware: RC network (with or without Schmidt trigger) and a diode to bypass the R on switch contact. Pick the RC time to remain HIGH throughout bouncing but go low fast enough to satisfy input.Software: Detect switch push immediately, but don't allow 2nd push for X mS.

author: Zero999
author_rank: Super Contributor
timestamp: September 29, 2016, 11:15:36 pm
content: Re-reading the original post again. The issue doesn't seem to be responding to the switch quickly enough, but performing the de-bouncing without taking time away from the other processes. Still I don't see why it can't be done in software. If you can get a rough indication of how long the sample loop takes, then you can check the switch status X number of loops which shouldn't add much time to the loop.

author: Ian.M
author_rank: Super Contributor
timestamp: September 29, 2016, 11:26:20 pm
content: Don't even think about RC debouncing into any input without a decent bit of hysteresis. Into an ordinary fast CMOS chip input that isn't a Schmitt trigger one, too slow a transition + a little inevitable background noise is often worse than no debouncing at all.

author: LabSpokane
author_rank: Super Contributor
timestamp: September 30, 2016, 02:04:27 am
content: Quote from: Fungus on September 29, 2016, 09:16:24 pmThis.In the era of the <$1 16MHz micro, software is the correct answer.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2016, 02:44:02 am
content: QuoteUsing a ton of bitmasks you can set up a shadow register for the switch inputs, and your main code will check state of shadow register bit instead of IO. And it will change it only after X cycles. Or you can change it immediately and then timeout that bit for X cycles before it will change, using a post scaler/counter register for each input...Or... If you set the interval longer, say around 100 Hz, you don't even have to do any timeout/counter stuff. No debouncing, essentially. You are just looking at the switches in an interval that is longer than switch bounce. Just the shadow register and polling at 100Hz. If the switch was thrown immediately before it was polled and it registers the wrong (bouncy) state... well it's just gonna get picked up on the next poll. Same thing if it's opened and happens to read incorrectly on the following poll. The only worst-case error is that the switch state updates one cycle later. Some switches (rare) can have much much longer bounce much than that... but you can source around for something better.If you have more than 2 or 3 switches, and your code loop is highly variable and can't wait for debouncing, this is a very practical method. It works, and 99% of humans couldn't tell the difference, let alone appreciate it.After trying to write the ultimate debouncing software, I realized that for more than even one button, it quickly becomes a suboptimal compromise with dubious benefit outside of specialized applications. This works. Almost no code overhead and almost no cpu usage.

author: danadak
author_rank: Super Contributor
timestamp: September 30, 2016, 10:37:14 am
content: If you want to stick with basic logic -google "hardware debounce switches", tons of hits.Regards, Dana.

author: mjkuwp
author_rank: Unknown
timestamp: September 30, 2016, 11:15:59 am
content: Some micros have features for this built into the GPIO, making the solution - software control of hardware.

author: amyk
author_rank: Super Contributor
timestamp: September 30, 2016, 11:21:00 am
content: Use optical switches. No bounce

author: nuno
author_rank: Frequent Contributor
timestamp: September 30, 2016, 08:13:11 pm
content: The most basic I usually do is something like:if detected state change to pressed,wait 50msif still pressed,do my stuffAdjust the 50ms to your preference. This may be done asynchronously. No extra hw.What optical switches are those, amyk?

author: amyk
author_rank: Super Contributor
timestamp: October 01, 2016, 12:57:30 am
content: Look for "contactless switch", same technology found in optical rotary encoders. Some are Hall-sensor-based. No contacts to bounce or wear out. Not cheap though.

author: PointyOintment
author_rank: Frequent Contributor
timestamp: October 01, 2016, 04:26:16 am
content: http://www.ganssle.com/debouncing.htm/thread

author: MarkF
author_rank: Super Contributor
timestamp: October 01, 2016, 05:07:55 am
content: https://m.youtube.com/watch?list=PLD7F7ED1F3505D8D5&params=OAFIAVgF&v=ldaGmKPQIXU&mode=NORMALTime code 49:00 for debouce algorithm.

author: @rt
author_rank: Super Contributor
timestamp: October 01, 2016, 05:56:30 am
content: Well the wait 50ms is going to hold up the loop.If your program cycle is long enough:Code:if (buttonport == 1) {if (oldstate == 0) {dothething();}oldstate = 1;} else {oldstate = 0;} // buttonportQuote from: nuno on September 30, 2016, 08:13:11 pm

author: wraper
author_rank: Unknown
timestamp: October 01, 2016, 08:53:32 am
content: Quote from: nuno on September 30, 2016, 08:13:11 pmThe worst way you can do it. Both awfully and slowly working debounce and needlessly wasting cpu time with basically hanging the execution.

author: zapta
author_rank: Super Contributor
timestamp: October 01, 2016, 01:11:23 pm
content: Quote from: wraper on October 01, 2016, 08:53:32 amThe logical 'wait' doesn't have to block the CPU.

author: nuno
author_rank: Frequent Contributor
timestamp: October 01, 2016, 01:55:28 pm
content: What I wrote is an algorithm (and I did mention "most basic" and "may be done asynchronously", if I recall correctly), there are many ways of implementing it, do it as you prefer. And actually, in some cases even a CPU consuming delay may be a perfectly acceptable trade-off for code simplicity.

author: @rt
author_rank: Super Contributor
timestamp: October 01, 2016, 02:14:09 pm
content: For event driven maybe.Best I can think of in C right now if the program cycle is too fast for above, and is being polled.Not balanced timing for the checks though, so as is, it would break timing of the loop it was in if that’s important.Code:if (debounce > 0) {debounce—;}if (button == 1 && debounce == 0) {debounce = 50; // set arbitrary delaysetbuttonpressedflag();} // debounced button

author: nuno
author_rank: Frequent Contributor
timestamp: October 01, 2016, 02:45:43 pm
content: One technique I often use is to synchronize the main loop to a time tick (which can be absolute or relative) using the platform's sleep (block in a low power state); then all jitter-tolerant timing stuff I need to do is based on that time slice, button debouncing (if applicable) included. 50ms is a value I frequently find myself using in my applications.I don't know if there's an industry naming for this, but by "time tick absolute or relative" above I mean that I may use just a plain "wait XXms" at the loop's top (relative) when precision and jitter are not important, or really have a watch to look at the current time (uC-friendly "watch") and unblock at "precisely" spaced moments (absolute). The timing sensitive stuff usually happens in interrupts so it's actually rare to have precise timing in the main loop... I go "relative" most of the time.By the way, that Ganssle article is a classic, one of my readings when I 1st needed to do some button debouncing 10+ years ago.

author: max_torque
author_rank: Super Contributor
timestamp: October 01, 2016, 03:37:46 pm
content: The thread title uses the word "button" suggesting the input is a switch pushed by a human, rather than some sort of mechanical or electrical input. That means it's maximum rate for changes in state is, frankly, glacial, compared to even the slowest modern logic. Typically, a really fast human (one trained at a young age playing hours and hours of arcade games ;-) can press a button maybe, 10x times per second, and even a 20 to 50ms "delay" in registering that press is likely to be irrelevant. This means a basic analogue input RC filter can provide most of the de-bouncing, with some software lockout or double checking to create a fully robust solution.

author: wraper
author_rank: Unknown
timestamp: October 01, 2016, 03:56:13 pm
content: Quote from: max_torque on October 01, 2016, 03:37:46 pmWaste of money without doing any good.QuoteAnd such thinking is the reason why sometimes I want to kill the person who made the debounce in some devices happen to use.

author: wraper
author_rank: Unknown
timestamp: October 01, 2016, 04:01:44 pm
content: Don't forget that although you *might* not feel 50 ms delay, you'll certainly notice 50ms debounce delay +50 ms UI delay resulting in 100ms of total delay. Also such debouncing is prone to miss the clicks or produce double clicks when there is none. Often happens in old devices with worn switches which if good debounce was present still would work without an issue.

author: amyk
author_rank: Super Contributor
timestamp: October 01, 2016, 04:45:15 pm
content: Quote from: max_torque on October 01, 2016, 03:37:46 pmA human pressing asinglebutton would probably be unable to achieve >10Hz, but that's only 120WPM. Typing with all 10 fingers can cause the interval between presses to occasionally be in the <10ms range.

author: Pjotr
author_rank: Frequent Contributor
timestamp: October 01, 2016, 04:55:50 pm
content: The only real fastandreliable mechanical switch de-bouncing is by a dual throw switch and the classical SR-FlipFlop (can be implemented in software but takes 2 inputs).

author: janoc
author_rank: Super Contributor
timestamp: October 01, 2016, 07:14:45 pm
content: Theguide to switch debouncing by Jack Ganssle:http://www.ganssle.com/debouncing.htmThe actual solutions are in the part two.Oh and he also explains why software debouncing is often but not always the best solution. Think EMI - will your debouncer be able to make a difference between noise and a real button press? RC filter can.And then this is kinda a follow-up to that:http://hackaday.com/2015/12/09/embed-with-elliot-debounce-your-noisy-buttons-part-i/http://hackaday.com/2015/12/10/embed-with-elliot-debounce-your-noisy-buttons-part-ii/(the second part specifically improves one of the Jack's debouncers)

author: zapta
author_rank: Super Contributor
timestamp: October 01, 2016, 07:21:57 pm
content: Quote from: Pjotr on October 01, 2016, 04:55:50 pmYou don't need a RS flip flop, a single non inverting buffer should do. Just connect the output to the input, with or without a resistor and have the switch providing either 0, NC, or 1 to the input.

author: zapta
author_rank: Super Contributor
timestamp: October 01, 2016, 07:29:36 pm
content: Quote from: janoc on October 01, 2016, 07:14:45 pmIt should be able to.My standard debouncing algorithm is to use periodic sampling and switch state if all the samplings in the last T secs (e.g. 50ms) disagreed with the current state.E.g.https://github.com/zapta/linbus/blob/master/injector/src_reference/arduino/debouncer.h

author: nctnico
author_rank: Super Contributor
timestamp: October 01, 2016, 07:37:19 pm
content: Quote from: KerryW on September 29, 2016, 09:59:21 pmNo, that is bad because it will also react on a spike (the product probably won't pass compliance testing). In software you need to sample if a button is pushed for several tens of ms. I like to use 50ms to 100ms with at least 4 samples. This causes an unnoticable delay but gives small spikes no chance to cause problem.

author: Pjotr
author_rank: Frequent Contributor
timestamp: October 01, 2016, 07:40:49 pm
content: Quote from: zapta on October 01, 2016, 07:21:57 pmTrue, the single buffer acts as a latch then. Works best with CMOS schmitt trigger. Use a resistor for the feedback anyway to avoid shorting the output to GND/V+ causing large current spikes.

author: wraper
author_rank: Unknown
timestamp: October 02, 2016, 04:47:46 am
content: Quote from: zapta on October 01, 2016, 07:29:36 pmApproach which results with missed state change. Instead it should bemostof the samplings to be really reliable. If buttons are pressed fast, and switches are bouncy, they'll never be 100% stable for 50ms all of the times they are pressed. Even presses themselves likely to be shorter than 50ms. Your approach would be fine if you debounce release of the button only, and button press results in instant state change. Of course only good if there is no interference present on the input.