Go Down

Topic: Hardware debouncing questions (Read 686 times) previous topic - next topic

dtp1

Hi all,

I learned a great deal about debouncing from this extremely useful thread here...
http://forum.arduino.cc/index.php/topic,14397.0.html

I even implemented his "revised circuit" with great success on my own magnetic reed switch circuit.

So, my questions are:
1) What is the significance of choosing the values 470 (R1) and 10k (R2)? I think it has something to do with how fast the capacitor charges/discharges but what is the math behind those values?

2) I have seen other examples of hardware debouncing that only use one capacitor and one resistor. Basically, they get rid of R1 below and instead of D1 it is just a straight shot to the interrupt pin.How does this circuit compare to the one below? Advantages/disadvantages of each are... ??? (Besides the obvious "fewer components.")


{{{photo credit to author of post in link above}}}

cjdelphi

#1
Aug 13, 2013, 04:24 am Last Edit: Aug 13, 2013, 04:27 am by cjdelphi Reason: 1
The 1 resistor cap method is used because it's obviously cheaper and quicker to build, essentially without the cap/resistor what will happen is the IC or MCU's job is to detect the button being pressed, in a split moment in time that IC at the very moment in time you push to make 2 pieces of metal come together can touch, de touch, touch a few thousand times , so the basic role of the circuit is to fill the capacitor very very quickly giving a nice clean waveform so instead of seeing the quick succession of off's and on's while the contacts are making contact, we see a full "on" voltage to defeat the dreaded "debouce" issue... or (Delay(100) will  for me) ... either circuit will do that.

oh yes, i forgot, the role of the resistor to ground is simply to bleed off the voltage so the MCU see's LOW again (higher the resistor value, the longer it takes to drain the cap)

cjdelphi



{{{photo credit to author of post in link above}}}



After looking at this Circuit for a minute or so , I got the role ..

Ok what's happening is that it's essentially the circuit I just talked about but backwards, the idea is the capacitor is constantly filled high let's say 5v, when the button presses, the 5v high is passed to the arduino where it's shortly discharged to ground giving a low.

This would circuit would give a sharp pulse high and stay low, the other circuit would stay high until you release the button......

polymorph

Switch not pressed, C1 is kept discharged by R1 and R2, so the voltage at the Interrupt is 5V.

Press the switch, the capacitor charges very quickly through D1, pulling the Interrupt to 0.7V and then R1 finishes charging C1 to 5V and so Interrupt is finally at 0V.

Let off on the button, and the capacitor discharges through R1 and R2. R1 is necessary because the diode is reverse biased at this point.

I'm not really certain why D1 and R1 are necessary for this.
Steve Greenfield AE7HD
Nick Gammon on multitasking Arduinos:
http://gammon.com.au/blink
http://gammon.com.au/serial
http://gammon.com.au/interrupts

cjdelphi


Switch not pressed, C1 is kept discharged by R1 and R2, so the voltage at the Interrupt is 5V.

Press the switch, the capacitor charges very quickly through D1, pulling the Interrupt to 0.7V and then R1 finishes charging C1 to 5V and so Interrupt is finally at 0V.

Let off on the button, and the capacitor discharges through R1 and R2. R1 is necessary because the diode is reverse biased at this point.

I'm not really certain why D1 and R1 are necessary for this.


C1 is kept discharged how exactly? GND only connects via the button?

polymorph

C1 is discharged by R1 and R2. That is a complete path around C1. Discharged does -not- mean ground. Discharged means no voltage across the capacitor, no charge on it.
Steve Greenfield AE7HD
Nick Gammon on multitasking Arduinos:
http://gammon.com.au/blink
http://gammon.com.au/serial
http://gammon.com.au/interrupts

CrossRoads

The other way to debounce is to get rid of all that stuff and just do it in software.
Use the internal pullup, and have the switch connect to Gnd.
When the switch is closed, capture the time.
Then do not accept another switch closure for action until some time has passed.
Code: [Select]

void loop(){
if ( (digitalRead(button) == 0) && ( (millis() - buttonPressTime) >=debounceDuration) ) {  // somebody pressed the button
                                                                                              // and it's been long enough since prior button press
      buttonPressTime = millis();  // start new debounce timer, time elements are unsigned long
      buttonPressed = 1;                // and note that a button press was accepted
 }
If (buttonPressed == 1){
// take some action
buttonPressed = 0; // clear the button press
}
} // end void loop

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

dtp1

Thanks everyone for your help. I was hoping to find out the actual math behind choosing a 104 cap and the 10k and 470 values of R1 & R2. However, the explanations are indeed helpful.

I have tested the other circuit that uses only a resistor and a cap (I'm using 10k-ohm and again a 104 capacitor) and this is working just fine. Again, what is the math behind these being the "magic values" when dealing with +5v input?


The other way to debounce is to get rid of all that stuff and just do it in software.


Yeah I'm fully aware of software debouncing and how to implement it, but I am using an ATTiny chip for the uC on this project so code size is an issue. I am already using half of the available code space and I have only implemented two of three interrupts required and none of the sound output.

Plus this is a great opportunity for me to learn a little more electronics theory. I am a very competent software person but somewhat new to figuring out all of the electronics on my own.

I might just turn this project into an Instructable too. I think a few people might enjoy spending part of a weekend building this contraption.

Now I need to figure out how to (or even if I can) use a voltage divider circuit on a rotary select switch with a pin-change or hardware interrupt. I might just have to "simulate" the interrupt by checking for changes to the switch-pin voltage in loop() but I prefer the more elegant "interrupt" solution.

polymorph

It takes about 0.7RC (in seconds) for the capacitor to discharge to about 1/2 the charged voltage. With 10k, 470 ohms, and 0.1uF (I don't think you meant mfd aka milliFarad as that'd be 100uF) the timing is approximately 730uS. Typically, switch bounce is pretty fast.

However, ideally you'd also be worried about -not- triggering if the signal is very short. In which case, I'd expect to see a resistor in -series- with the diode to slow the charge time. After all, if the switch seems to be closed for 1mS or less, it is probably noise pickup, not you pressing the button.
Steve Greenfield AE7HD
Nick Gammon on multitasking Arduinos:
http://gammon.com.au/blink
http://gammon.com.au/serial
http://gammon.com.au/interrupts

Go Up