Previously, as they said at the beginning of the new episode of the TV series, we discussed the history behind the use of hardware and software to bounce switches. We also carefully studied the idea of using RC networks and Schmitt triggers to de-hop single-pole single-throw (SPST) toggle switches (
). In fact, if you are feeling nostalgic, you may need to revisit
with
, And the "Switch Type" and "Switch Term" columns.
My previous column led to a series of comments and questions. For example, regarding hardware and software solutions in commercial projects, James Langbridge, a university lecturer and freelance engineer, emailed me:
Someone emailed me asking if "LED" is appropriate or should I use "LED". The answer is "yes", "no" or "maybe". The problem is that it depends a lot on how you talk when you talk to someone. Some people say that "LED" rhymes with "bed", in this case, "LED" will be the correct form. Others spell it as "LED", in this case, "LED" will be the way to go. When writing it down, you should choose the internal style of the company or publication, otherwise, please write it in the way you say it.
Others questioned why we should use 20 milliseconds (ms) as the debounce time. We did mention it before, but this is a good question, and we all need to reach a consensus on this. When I opened my eyes, with a bushy tail, and just started as a junior engineer, I learned from many discouraged (experienced) professionals that the switch will complete within 1 millisecond, so if I double it and Keep working, 2 milliseconds, everything will become chunky. Unfortunately, I subsequently found that the value was too optimistic, or in other words, it was incorrect.
As Jack Ganssle said in his report
In the column, when he tested a bunch of switches, the results showed that the average bounce duration was 1557 microseconds (we may round to 1.6 milliseconds), and the maximum bounce duration was 6200 microseconds (or 6.2 milliseconds). In addition, a friend of mine who was a US Air Force technician said that they always use 20 ms as the value, after which it can be considered that the switch has stopped bouncing. I've heard that other values will bounce back (no pun intended), but the most important thing is that I will now use 20 milliseconds as the "default value" unless otherwise stated.
As we will see in future columns, some debounce solutions allow the microcontroller to see it almost immediately after the initial switching transition. Unfortunately, these methods can also be confused by noise. Other solutions, such as our RC network, add delay in the program (as mentioned above, we will assume a delay of 20 milliseconds).
Do we really care if our switch anti-shake solution delays the microcontroller "seeing" the switching event by 20 ms? Well, it depends on the application. If we are talking about limit switches used to detect the state of high-speed moving machinery, then 20 milliseconds may represent a very important time in the business plan. In contrast, if we use a switch to instruct the microcontroller to activate things such as a TV, one of the obvious manifestations is the lighting of the LED, then the delay of 20 milliseconds does not matter.
In his column, Jack also mentioned some of the tests he conducted, in which he wrote a simple program to read the button and turn on the LED after a programmable delay. Jack reports that there is clearly a 100 millisecond delay, and the 50 millisecond delay seems to be instantaneous. It's not that I doubt Jack's words, but I repeated the test myself. To be honest, I can hardly detect a delay of 100 milliseconds myself, so I am happy to accept his conclusion that delays of 50 milliseconds and below cannot be detected.
The other question I want to know is how fast the switch starts and closes. As far as my own project is concerned, I only care about manually operated switches. I started this test with a conventional toggle switch, which turned on and off 100 times as fast as possible. I repeated the test 3 times, which took 23.17, 24.78 and 23.23 seconds respectively. This averages 23.73 seconds. Divide this by 200 to get an average on/off switch of 119 ms, which is in addition to our 20 ms debounce delay.
I also performed this test on regular-sized momentary push-button switches and tactile switches mounted on the PCB. In both cases, the average time to press and release the switch 100 times is more than 20 seconds, which in the worst case is 100 ms to press or release the button.
An interesting point raised by someone in the email is that we introduced the RC network solution in the previous column. To remind yourself, the solution looks like this:
In fact, I made some changes to the original version, because I replaced the in-phase Schmitt trigger buffer with the in-phase Schnitt trigger buffer, which is slightly faster. To be honest, we are just talking about a difference of a few nanoseconds, which is absolutely negligible in our case of a 20ms RC delay, but if I have a choice, this is how I would do it (can you spell " Compulsive"?).
Of course, this means that when the switch is closed, the signal seen by the microcontroller now changes from 0 to 1 (from 1 to 0 in the past). Conversely, when the switch is off, the signal seen by the microcontroller now changes from 1 to 0 (from 0 to 1 in the past). Fortunately, this is trivial in the software.
But we digress... The reader's question concerns the necessity of using diode D1. As mentioned earlier, when the diode is included, the capacitor is discharged through the resistor R2 and charged through the resistor R1. This allows us to specify the discharge and charging time separately. If we omit the diode D1, the capacitor will still be discharged through R2, but will be charged through R1 + R2, which will make the switch deactivation delay longer than its activation delay time.
Do we really care? If we are talking about man-machine interface, it may not be. In this case, we can omit the diode. On the other hand, if we are talking about an application in milliseconds, then adding diodes is the way to go.
This also makes us think about the way to use each toggle or button switch. For the purpose of these discussions, we assume that they all have a normally open (NO) terminal. In the case of a toggle switch, it may be that activating (closing) the switch will trigger some actions that we are interested in, but deactivating (opening) the switch is less important. Alternatively, the actions of closing and opening the switch can each trigger some form of time-related activity.
When it comes to button switches, there are two main variants: latches and momentary. If it is a self-locking button, we press it once to activate the switch, and then press it again to disable it. For toggle switches, it may be that we are only interested in activation delays, or both activation and deactivation delays.
For momentary buttons, pressing the button turns the switch off, and releasing the button turns the switch on again. It may be that simply pressing (and then releasing) the switch triggers a series of activities, in which case only the activation delay will make sense. Or, it may be that we press the button to start the activity, hold the button to continue the activity, and then release the button to terminate the activity. In this case, both activation and deactivation delays may require our attention.
Again, all of this depends on the application. For example, if we are talking about a relatively slow human-machine interface (such as a beer dispenser), press the button in it to start the beer flow, press and hold the button until the glass is full, then release the button to stop the flow, The difference between the 20 milliseconds and 100 milliseconds of the deactivation period is negligible (in fact, in the case of beer, the fact that the shutdown process takes longer may be an advantage in some cases). In contrast, applications where the state of a button is determined by the position of a mechanical mechanism may be time-dependent.
Some people touted another way to provide a jitter switch solution is to use a monostable multivibrator, or "single shot." After triggering, a single pulse with a predefined duration will be output. Then, the circuit returns to its stable state and no longer produces output before triggering again.
Is it a good idea to use a monostable debounce switch? The short answer is "No", and the longer answer is "Oh!" You can stop reading immediately and wait for Part 5 of this editor, but if you insist...
The way monostable is usually presented at a higher level of abstraction (ignoring switch bounce) is as follows:
Of course, we know that the switch will almost certainly bounce, which means that the pulse stream will be fed into a monostable state. The idea is that the first monostable is triggered by the leading edge of the first pulse, and the output pulse of the monostable starts almost instantaneously (a few nanoseconds later). As long as the width of the output pulse is large enough (we assume 20 ms) and the switch bounce stops before this time, everything is awkward, right? it is good…
Let's start with the low fruit. As shown in the figure below, a free-flowing roam of a switch debounce circuit on the Internet is based on a monostable created using an N-channel MOSFET, as shown below (we use the Rx annotation on the output resistance because we don’t want to compare it Early products confuse the circuit).
We assume that our microcontroller is an Arduino Uno (because that is something on my desk), which means we have a 5 V power supply. We can assume that the circuit should work as follows. Suppose we start with the switch off and the capacitor is charged to 5 V through R1, which turns on TRI, which means that the logic of the microcontroller is 0.
The effect of this function is that when the switch is closed, the capacitor is immediately discharged through the switch, thereby turning off the transistor, so the microcontroller will now see logic 1. This situation will continue as long as the switch is closed. . When the switch is turned off, the capacitor starts to charge with the RC time constant defined by R1 and C1, and finally returns the signal provided to the microcontroller to logic 1.
In fact, this circuit has so many problems that it is prohibitive. Let us start with the fact that many switches have relatively low current ratings, such as 20, 25, 50, or 100 mA. I just checked one of the toggle switches in the spare box. When closed, the total resistance of this switch and a few inches of 24 AWG copper wire is 0.2Ω. This means that the action of closing the switch will cause a surge current of 5V /0.2Ω = 25 amperes (eeek).
There is also the fact that when the capacitor is charged, the transistor will gradually turn on, which means that the signal sent to the microcontroller will gradually change from logic 1 to logic 0, but the microcontroller prefers to present a clear and clean signal. 0 and 1.
Most importantly, we will have to add another resistor through which the capacitor can discharge. We must also add a Schmitt-triggered buffer or inverter to the output to enhance the signal fed to the microcontroller. When finished, we will have a circuit similar to the following:
Basically, we are back to the original RC debounce circuit. The only difference is that we have now added an N-channel MOSFET inverter to the hybrid, which makes this work meaningless.
I will shorten the time because we can continue to work for a few hours. There are a variety of monostable multivibrator circuits out there, and many of them do a great job as long as what we ask them to do does not involve debounce switches.
For example, there are 74121 monostable multivibrator with Schmitt trigger input, 74122 retriggerable monostable multivibrator and 74123 dual retriggerable monostable multivibrator, all of which support positive Edge and negative edge trigger. In addition, if you are rooted in the Internet, you can find multiple examples where people say you can use a 555 timer, configure it as a monostable, and then use it to eliminate the jitter of the switch.
Sadness is involved, all these solutions based on monostable state have a fatal flaw. Let's start by looking at the following signals that are usually displayed as part of these solutions:
As we have seen, the initial falling edge of the monostable multivibrator input (Min) triggers the start of the pulse of its output (Mout). For non-triggerable monostable states, such as 74121, the pulse width (Pw) on the output is what we define as the width using the appropriate resistor and capacitor (we assume it has been set to 20 ms (as described earlier in this column) In contrast, a retriggerable monostable such as 74122 will be re-triggered every time the switch jumps, thereby "stretching" the pulse on the output, because the delay Pw does not start until the last trigger switch edge .
Look at the previous picture again. Can you spot obvious flaws? The problem is that the person who created the original version of this diagram first put the switch in an inactive state, showing some bounce, and then immediately returned the switch to its inactive state, but this is not how it works.
What we should show is that the switch starts from its inactive state, then jumps, and then the switch is in its active state, and the active state continues for a long time (relatively speaking) after the end of the Pw output pulse. Therefore, assuming a conventional non-retriggerable monostable multivibrator, we will actually see the following:
Well, as they said, this is a good fish. Consider the point of view of a microcontroller, every time you change the state of a toggle or button switch, you will see a pulse. In rare cases, this may be just what you are looking for, but in most cases, when you just want to know whether the switch is on or off, it is painful to go to the countryside.
Believe it or not, the situation will get worse. in
In this mini series, we introduced the topic of noise. We noticed that no matter which switch debounce technology is used, it should not be caused by crosstalk, EMI, (electromagnetic interference), RFI (radio frequency interference) occasionally" "Glitch" or "Spike") or ESD (electrostatic discharge). The problem is that the monostable will trigger immediately
The valid edge of the input, even if the edge is part of a single narrow ESD pulse (for example, sadness).
One way to solve these problems is to use the falling edge at the end of the monostable output pulse to drive the clock on the D-type flip-flop. Similarly, use the output of the switch as the data input of the trigger as follows:
Therefore, in the end, we have implemented a switch bounce solution based on a monostable multivibrator, which can actually accomplish what we want. On the one hand, we may shout "Hurray!" On the other hand...
Is it just me, or are we making things too complicated? If we take a step back and think, all the results achieved using monostable multivibrators and D-type flip-flops are the same as those achieved using RC delay and Schmitt-triggered inverters.
Most importantly, it is difficult for me to come up with a reason to implement a switch debounce solution based on a monostable multivibrator.
Believe it or not, when I first started writing on this topic, I thought I could do it in one or two columns, but there is still a lot to discuss. Next time we will watch... but no... surprises us. At the same time, I welcome your comments, questions and suggestions as always.
Just an appendix to your comment "The most important thing is that it is difficult for me to come up with a reason to implement a switch debounce solution based on a monostable multivibrator."
In my early days, I implemented the 16-switch keypad as a binary-hexadecimal keypad with 16 switches with common electrodes. The solution (taken from the Motorola application note if I remember correctly) is to use 2 MC14532 8-bit priority encoders (
); Each 4532's GS output performs an "or" operation, and then uses the "or" output as a monostable clock (I think it is MC14528), thereby providing a debounce circuit for all 16 switches. I remember that the output of Qn also undergoes an "or" operation. (Using 8 switches may be easier to explain). Just to say that when MC14490 (
) Does not exist yet...
Very interesting-thank you for sharing-actually I will talk about OR triggering interrupts using multiple switches later in this series-but it is interesting that someone has successfully used monostable with switch debounce
Max, I like this series very much.
Debounce is one of the things you will often encounter in any project. In FPGA, jump input will cause serious damage to your FSM, and find annoying errors in sequential logic.
Sometimes, you must group related switches (such as multi-pole switches) and need to latch them all at the same time.
This is the case with a circuit I shared in OpenCores a long time ago:
And it still gets downloaded there.
Great-thank you Jonny, I took a few weeks off, because some other topics need my attention, but I will return to Part 5 and 6 soon, and then I will refer to your FPGA solution.
Hi Max,
I think there will never be enough discussion about debounce. In order to contribute to naive questions...
Suppose we have a signal flow as follows:
4 groups of 8 switches (24V) -> photoelectric isolation -> latch (maybe 74HC573) -> uC port (maybe 8051)
Does it matter where RC is used to eliminate jitter? I think that debounce on the uC port will result in the least number of components.
I'm not ignoring you... I'm (a) thinking or (b) asking those who (not the same as you) actually have a clue haha
EmbSysDev-In this case, as long as there is a latch between optos and micro, I think it is not a good idea to debounce the microcontroller. It may lock the wrong state. If uC has Schmitt input, I will omit the latch and add a small capacitor across the LED of the optocoupler.
-Rick
I have not debounced the hardware conversion for more than 30 years. I always have some kind of MCU in my design, and I always have available pins and processing time to implement anti-jitter routines. I like this route very much because I can change the algorithm as needed to adapt to the situation without worrying about it in advance. I did put ESD protection on the switch inputs that need it, but that's how much I use hardware in the switch interface.
Thank you for your reply-I am taking a two-week break, this is because there are other topics that need my attention-but I will make more suggestions on this topic soon-I will want to hear when we use software solutions To your thoughts on the various methods I introduced.
Hey max,
So, so far, we have been asking ourselves this question:
How long will the switch bounce after being pressed or released?
Or change this question a bit:
After pressing or releasing, what is the longest time for the switch to bounce?
Now, I suggest that we look at the problem from a different perspective. To this end, I suggest turning the problem terminology into:
What is the phenomenon that the switch does not jump in the shortest time after being pressed or released?
Or, in other words, how long does it take for the handover to be considered stable after the event?
This has nothing to do with how long it takes to bounce. What we are really interested in understanding is whether the bounce has stopped.
Once we define this (for example, T = 10ms, which is very long), we can use the following technique, which can be better implemented in software or a mixture of software and hardware:
-Low-pass filter "noise". Just to avoid malfunction.
– Define a switch state, "stable" or "unstable". It is assumed to be stable at reset.
-Define the switch output as 0 or 1. Use hardware defaults during breaks. We call this output "OUT"
– If the switch is stable at "OUT" (0 or 1), then:
*If any event occurs on the switch, please update the output to NOT "OUT" to enter the unstable mode. Start a timer that elapses at time "T"
*If no event occurs, please keep "O" unchanged
– If the switch is unstable, then:
*If no event is observed within time T (ie, the timer has passed), then update "OUT" with the current switch input.
*If any event occurs, please restart the timer at time T.
If the switch is unstable during the time "T", it is effective to ignore any events on the switch. It has several advantages, namely fast response speed and relatively good immunity.
It can also be implemented on a simple microcontroller (such as PADAUK PMS150C-U6, which costs three cents ($0.3) and has a good SOT23-6 package).
Alvaro
Hi Alvaro-this is of course a method-wait for a stable time before any jitters appear before responding-but there is also an argument to respond immediately, and then wait for jitters and stable time before performing any other operations. I will discuss this in my next switch bounce column (or the one after it), because we still have some interesting hardware solutions to read and think about
You must be
Post a comment.