Debouncing a momentary switch

Started by Mark Hammer, October 20, 2020, 10:44:02 AM

Previous topic - Next topic

Rob Strand

#40
QuoteOkay, will this work?
In order to drive the 4017 you will need to power it from -6V and 6V.     Since the supply is effectively 12V you will then need to use a 74C14 or 40106 chip, as the common 74xx devices are roughly for 5V.   It might fix the switch but it still leaves the problem of the trigger.

From the 40106 datasheet the Schmitt thresholds for 12V,

                                min      typ     max
VP                           5.7      7.4      9.0
VN                           3.3      4.9      6.3
VH  (VP-VN)          1.3      2.9      4.2

While VH max of 4.2V implies you could use a 5V pulse, you would need to bias the input.     If you biased to 9.0V to meet VP max  then 9.0 - 5 = 4.0V   cannot meet the VN min of 3.3V.   In other words a 40106 powered from 12V won't work all the time with a 5V input pulse.

So another option is to power the 40106 from 6V  then you would need an open collector or open drain switch and a resistor to -6V to drive the 4017, which is powered from +/-6.   

All looks too messy.


Why not just try  a different opamp in the original circuit?
Send:     . .- .-. - .... / - --- / --. --- .-. -
According to the water analogy of electricity, transistor leakage is caused by holes.

R.G.

I wish the vertical adder was something even nearly as clever as the proposed ones. Those are great ideas for new designs, though!  :icon_lol:

A vertical adder can be thought of as a bank of memory locations. The ongoing results are a vertical slice through the bits, not horizontally across one memory word. So, for instance, if you were using a four bit result, you would use bit 0 (lowest order bit of four different memory words) as the four bit word. Word 0 holds the LSB, wtoord 1 holds bit 1, word 2 holds bit 2 and word 3 holds the MSB. If all the words are cleared to 0, there is 0 in your first four bit word in bit 0 of all the four memory words (and everywhere else).

bit number.........7 6 5 4 3 2 1 0

memory loc  3 = 0 0 0 0 0 0 0 0
memory loc  2 = 0 0 0 0 0 0 0 0
memory loc  1 = 0 0 0 0 0 0 0 0
memory loc  0 = 0 0 0 0 0 0 0 0

In this setup the "words" you're interested in are >vertical< as in "all the bits vertically under bit number 7" is one, all the bits under bit number 6 is a different word, and so on, eight at a time.

If we read 8 pins on the uC, and some of them are 0, others are 1, we can shift that reading into memory location 0. Let's say we only have six input pins we're reading, and we read x x 0 0 1 0 0 1, the "x" meaning the value doesn't matter as it never gets used. So the memory contents become:

bit number.........7 6 5 4 3 2 1 0

memory loc  3 = 0 0 0 0 0 0 0 0
memory loc  2 = 0 0 0 0 0 0 0 0
memory loc  1 = 0 0 0 0 0 0 0 0
memory loc  0 = x x 0 0 1 0 0 1

Some time later, we read the pins again and get "x x 0 0 1 0 1 1"; the memory becomes:

bit number.........7 6 5 4 3 2 1 0

memory loc  3 = 0 0 0 0 0 0 0 0
memory loc  2 = 0 0 0 0 0 0 0 0
memory loc  1 = x x 0 0 1 0 0 1
memory loc  0 = x x 0 0 1 0 1 1

The previous value was just shifted up one location, because the operation we're doing is vertical shifter. If we did a vertical adder, we could simply do the boolean operation for adding the input to memory location 0, instead of shifting. Shifting is simpler to show.
Next read, we read x x 0 0 0 0 0 1, and the memory locations become:

bit number.........7 6 5 4 3 2 1 0

memory loc  3 = 0 0 0 0 0 0 0 0
memory loc  2 = x x 0 0 1 0 0 1
memory loc  1 = x x 0 0 1 0 1 1
memory loc  0 = x x 0 0 0 0 0 1

And one more reading, which shows input pins of "x x 1 0 0 0 0 1" to give

bit number.........7 6 5 4 3 2 1 0

memory loc  3 = x x 0 0 1 0 0 1
memory loc  2 = x x 0 0 1 0 1 1
memory loc  1 = x x 0 0 0 0 0 1
memory loc  0 = x x 1 0 0 0 0 1

We look at vertical rows for debouncing. The lowest order bit position shows four sequential 1s, so presumably the pin that feeds the bit number0 position can be confirmed as a 1. Bit number 2 and 4 have stayed zero for four readings, so they're debounced to 0. Bits 1, 3, and 5 are wobbling around and have not settled.The timing on checking things is important. I use a time of 10mS to 20mS between sampling inputs, so in this example, the time spent for getting a stable debounce is four sampling times. Even horribly bouncing switches tend to settle in 50mS to 100mS.

Why go to something this complicated? Well, for shifting it might be just as easy to go with horizontal shifts, all the incoming bits going into their own memory location; and I have done that as well. However, if you want to do something fancy, like making a running sum of inputs, or ensure that all the inputs are sampled simultaneously, the vertical form works very well, down to a uC cycle. Another is easy masking or different operations on different inputs. In one variant of this, I used a mask word to make debounced switches with a 1 in the mask word be a "toggle" and a 0 caused the input to be a momentary.

Not as fun as vertical pit vipers, but ... what can I say? I'm a computer nerd.  :icon_lol:
R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

Rob Strand

The power supply design looks a bit marginal.   Maybe the problem is the power.   You might expected the 100uFs to save it but maybe not.

The LEDs are drawing 3mA.

Without the LEDs the zener current is only (9V - 6.2V) / 1k = 2.8mA.

That means any load is going to cause the power supply rail to drop below the zener voltage.
The 3mA LED current is going to cause a 3V drop across the 1K resistor and pretty much rob all the zener current, then the zener won't be doing much regulating.

The nominal zener voltage is 37mA for 6.2V and we probably shouldn't go below 3.7mA to even remotely regulate.      So 3.7mA zener and 3mA LED means we should target 6.7mA through the power supply resistors.

Rpsu = (9 - 6.2) / 6.7mA  = 417 ohm

So we'd probably want no more than 470 ohms instead of 1k's.

I'm not saying that's the problem but it is a possible hole in the design.    The 100uF caps should hold-up the rail but maybe it's not good enough.  The thing is, if the supply glitches it could glitch the clock, it could also glitch the reference voltage for the Schmitt-trigger (R6, R7)
Send:     . .- .-. - .... / - --- / --. --- .-. -
According to the water analogy of electricity, transistor leakage is caused by holes.

Mark Hammer

The datasheet for the 74HC14 gives its operating voltage as 2-6VDC.  I figured I'd us the +6.2V line and drop it with a diode.

But while I'm here, just thought I'd say I appreciate the thought you folks are putting into this.

ElectricDruid

I've seen a different implementation of a vertical counter by Scott Dattalo. Unfortunately the website where he described it no longer exists. Rather than using a byte per reading, like RG suggests, it uses bits like a standard binary counter. So you can count to four with only two bytes vertically.

Here's PIC code for it:


;---------------------------------------------------------
; Test and debounce the digital inputs
;---------------------------------------------------------
; Do Scott Dattalo's vertical counter debounce (www.dattalo.com)
; This debounces eight inputs on PORTA.

; Increment the vertical counter
movf.        DEBOUNCE_LO, w
xorwf DEBOUNCE_HI, f
comf.       DEBOUNCE_LO, f
; See if any changes occured
movf.        PORTA, w
xorwf IN_STATE, w ; Test for changes
; Reset the counter if no change occured
andwf DEBOUNCE_LO, f
andwf DEBOUNCE_HI, f
; If there is a pending change and the count has rolled over
; to 0, then the change has been filtered
xorlw 0xFF ; Invert the changes
iorwf DEBOUNCE_HI, w ; If count is 0, both..
iorwf DEBOUNCE_LO, w ; ..A and B bits are 0
; Any bit in W that is clear at this point means that the input
; has changed and the count rolled over
xorlw 0xFF ; Invert the changes
xorwf IN_STATE, f ; Update the changes
; W is left holding state of all filtered bits that have changed.
movwf IN_CHANGES


It's a neat method for debouncing eight inputs in only a few instructions (all credit to Scott, not me). And having STATE and CHANGES variables afterwards is very useful for detecting various different states (you can toggle things based on CHANGES, or you can just follow STATE) so you can do momentary or latching code without difficulty.

HTH,
Tom

Rob Strand

QuoteThe datasheet for the 74HC14 gives its operating voltage as 2-6VDC.  I figured I'd us the +6.2V line and drop it with a diode.
Yep, if you can power the Schmitt-trigger off one rail you can use the 74HC14 (the *absolute max* is 7V)..    However the 74HC14 output will swing 0 to 6.2V (approx) but the 4017 clock needs -6V to 6V.
Send:     . .- .-. - .... / - --- / --. --- .-. -
According to the water analogy of electricity, transistor leakage is caused by holes.

Rob Strand

#46
Something like this is about as simple as I can think of.

Note you need to use two Schmitt-triggers to emulate the original circuit.




The clock will swing -6V (via resistor) and +6V via transistor *and* gate output.


This one is more conventional but uses an extra resistor,  you might be able to remove R3 anyway,



Send:     . .- .-. - .... / - --- / --. --- .-. -
According to the water analogy of electricity, transistor leakage is caused by holes.

anotherjim

Have to say that I absolutely hate panel push buttons for direct switching plain logic. They are rarely well made, no matter how big & chunky. Keep then for the bell push!

I prefer direct switching with a spring biased toggle.



Top is a simple switch. I'm assuming the external jack is for a momentary footswitch and carries no signal and sources no voltage. Using the 4017 Schmitt input and RC debounce.
Below is prefered flip-flop arrangement with biased toggle. Need no cap to debounce. External input not so easy to provide - may need a cap across it. Thing with the flip-flop is that the switch contact would have to bounce all the way to the opposite throw to bounce the output.
VDD is +6v and VSS -6v.


marcelomd

Debouncing in software is one of those things that you end up coding over and over again. It's always the same thing (checking a stream of bits), but different enough (read operation, number of bits, multiplexing, etc.) that you can't have a standard library.

R.G.

Quote from: ElectricDruid on October 22, 2020, 08:40:20 PM
I've seen a different implementation of a vertical counter by Scott Dattalo. Unfortunately the website where he described it no longer exists. Rather than using a byte per reading, like RG suggests, it uses bits like a standard binary counter. So you can count to four with only two bytes vertically.
I've used that variant before as well. It's a very clever idea - and Scott's page is what got me started on the idea. The logic operations between each horizontal stage are open to modification. I used it a byte wide, eight inputs wide, and two stages tall, binary encoded, and added masking and so on. I deliberately skipped the byte-wide logic operations for computing add and carry so that the operation would be clearer. As you say, all thanks to Scott for explaining it to me.

R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

ElectricDruid

I miss that website! I'd have liked to have known what else he might have come up with. Now he's probably got a *proper job* or something...sigh...poor chap.

Still, Wayback Machine ftw!

https://web.archive.org/web/20060222014359/http://www.dattalo.com/technical/software/software.php

Rob Strand

QuoteI miss that website! I'd have liked to have known what else he might have come up with. Now he's probably got a *proper job* or something...sigh...poor chap.

Still, Wayback Machine ftw!

https://web.archive.org/web/20060222014359/http://www.dattalo.com/technical/software/software.php
Unless you come across it in a course, only hardcore micro programmers know about non-restore binary square roots.
Send:     . .- .-. - .... / - --- / --. --- .-. -
According to the water analogy of electricity, transistor leakage is caused by holes.