Reliable Debounce Circuit

Hi,

I found the attached debounce circuit from http://robotgestation.com/SensorForce.html which I am using for a sleep/ wake button for my Arduino.

I was looking for a very reliable circuit, taking into account the lifetime of the switch.

I would like to change it so that the button needs to be pushed for 1 second for it to switch. What resistor values or capacitor value should be used to achieve this?

Please note, for my circuit I also fed the output through another inverter input to achieve my desired result.

Greatly appreciate any help.

Debouce_circuit.png

R2 controls how long it takes to discharge C1 (along with the value of C1, of course) and therefore controls how long you must hold down S4 for the output to go HIGH.

R1 controls how long it takes for C1 to charge, so controls how long the output stays HIGH after releasing S4.

You can look up what the trip points are of 74HC14 and figure out the timing. A quick calculation in my head says, 1/3-2/3 of Vcc switching points, t = 1.1R2C1 to discharge from Vcc to 1/3 of Vcc.

Time for the output to remain HIGH after releasing S4 depends on how long you continue to hold down S4 after the output switches HIGH. If you continue to hold down S4 until C1 is fully discharged (generally regarded at 5 time constants, therefore 5R2C1), then charging from 0 to 2/3 of Vcc will result in t = 1.1R1C1.

One of the many legacies of having 555 timers on the brain.... a 555 wired as a monostable, the timing is 1.1RC. The capacitor is charging from 0 to 2/3 of Vcc. Charging from 0 to 2/3 of Vcc is the same as discharging from Vcc to 1/3 of Vcc.

I didn't look up the shottky trip points of the 74HC14, so I may be off a bit.

Yes that circuit is good, but lose the diode, it does nothing, its never even
forward biased with those resistor values! You won't need as long a delay as 1s, 0.2s is
conservative enough I think.

Thanks, i'll take both your responses on board.

The main reason I would like to use a 1 second press time is because this button is my 'Power' button (puts Arduino to sleep/wake), and I don't want to accidently push it to sleep/ wake it. I thought this would help prevent this from happening.

Of course, I am open to better solutions.

Cheers

R2 would be about 91k to get 1 second 'til turn on, but 100k would be close enough, I would expect. In that case, the diode would make a difference if you wanted time to OFF to be not much more than or shorter than the time to ON.

It is true that with the parts values in there now, the diode is a wasted part.

ButtonPressed=digitalRead(pin);
if (ButtonPressed==HIGH)
{
delay(1000); // could swap for milli and simply check time stamps for 1 second's worth.
if (digitalRead(pin)==HIGH)
{
//Yup user really is holding down button.
}
}

Delay without delay(); is the better option, but I like the hardware version lol, you could reduce the capacitor size to something like 1uf and increase resistor values to compensate.

As for the diode, the diode allows the cap to quickly and sharply transition states when you press the button (direct path to gnd) so it will discharge a lot quicker than relying on the resistor???

Thanks for your responses.

If I put this circuit on a PCB with surface mount components, would it matter what type of capacitor was used or would it need to be an electrolyte type. I have noticed that this type is rather large for 10uF for surface mount.

Cheers

Easier to use a circuit emulator (there's a few good free ones about, like ltspice) once you got it, increase the resistor sizes to compensate for the smaller capacity of the smt capacitors (unless it's not a ceramic and it's an electrolytic)

As for the diode, the diode allows the cap to quickly and sharply transition states when you press the button (direct path to gnd) so it will discharge a lot quicker than relying on the resistor???

That is incorrect. The diode is reverse biased when the capacitor is charged and you press the button.

The diode bypasses the discharge resistor when you let go of the pushbutton.

polymorph:

As for the diode, the diode allows the cap to quickly and sharply transition states when you press the button (direct path to gnd) so it will discharge a lot quicker than relying on the resistor???

That is incorrect. The diode is reverse biased when the capacitor is charged and you press the button.

The diode bypasses the discharge resistor when you let go of the pushbutton.

Thank you for the information, but you're also incorrect... i added "????" meaning (to me at least) it's a question, the way i phrased it was bad I know.... but i meant it as a question.

[edit]

but yes after looking at it again, i see where i was going wrong... I was for some reason thinking + could get to gnd (and discharge) but it can't because of the diode. (i got confused)

cjdelphi, you really need to brush up on basic electricity and electronics if you are going to continue trying to offer advice.

A 10uF surface mount capacitor isn't really that large. I suggest it might be better to incorporate switch debouncing in software. Perhaps it wakes up on button press, then starts a timer while still checking to see if you are still holding the button. If you are not still holding it after 1 second, it goes to sleep again. If you are, it wakes up the rest of the circuit.

I strongly suggest you do NOT use delay() to accomplish this. All that will tell you is if the button is held down at the end of 1 second. You could have let go and pressed it again, or it could get a pulse of noise from something at just that moment. There is no checking to make sure you have been pressing the button during that time.

Look at the example "Blink Without Delay" for inspiration.

polymorph:
cjdelphi, you really need to brush up on basic electricity and electronics if you are going to continue trying to offer advice.

A 10uF surface mount capacitor isn't really that large. I suggest it might be better to incorporate switch debouncing in software. Perhaps it wakes up on button press, then starts a timer while still checking to see if you are still holding the button. If you are not still holding it after 1 second, it goes to sleep again. If you are, it wakes up the rest of the circuit.

I strongly suggest you do NOT use delay() to accomplish this. All that will tell you is if the button is held down at the end of 1 second. You could have let go and pressed it again, or it could get a pulse of noise from something at just that moment. There is no checking to make sure you have been pressing the button during that time.

Look at the example "Blink Without Delay" for inspiration.

it's not "advice" it was a mistake now get over yourself.

polymorph, you really need to brush up on your common decency/ people skills. (since i accepted it was a mistake from over tiredness if you must know)

Thanks all, appreciate the help

PedroA:
Of course, I am open to better solutions.

I agree with polymorph - there is no reason (other than your own enjoyment and education) to do this in hardware, as it is easy to do in software.

This works with some very bouncy swtiches
The macro assumes non-blocking code and at least 4 readings. The value becomes true if you have exactly 1low and 3high consecutive readings.

Example:

//macro for detection and debouncing of raising edge
#define RE(signal, state) (state=(state<<1)|(signal&1)&15)==7

int buttonstate;
const int button = 2;
const int LED = 13;

void setup(){
  pinMode(LED, OUTPUT);
}//setup()

void loop(){
  if(RE(digitalRead(button), buttonstate)) digitalWrite(LED, !digitalRead(LED));//toggle led
}//loop()