Debouncing multiple buttons using schmitt trigger

Noting to do with the current caps, but something that applies for [u]all[/u] chips, they want a 100nF ceramic cap over the power rail close by (aka, right next to the IC) so they have a clean power supply :)

septillion:
Noting to do with the current caps, but something that applies for all chips, they want a 100nF ceramic cap over the power rail close by (aka, right next to the IC) so they have a clean power supply :slight_smile:

So something like this?

attached like C4?

Yeah, it's close on the schematic but he means physically close to the IC, as close as possible.

raschemmel: Yeah, it's close on the schematic but he means physically close to the IC, as close as possible.

I've been reading up on that, looks like my schematic above is slightly wrong though because the cap should go to ground.

Correct.
I didn’t notice that it was connected to Vcc.

|500x398

runaway_pancake: |500x398

I'm not sure what I'm looking at here, is this the same concept but cutting out the extra resistors and doing a 20k instead of 2 seperate 10k's?

What you're looking at is a circuit that I've actually used. Each Schmitt output goes to an input pin, but they also get diode OR'd before the INTerrupt pin. Any button-push results an interrupt where the sketch then determines which switch it was. I used this to control a motor [increase/decrease PWM or Stop]. (I added a fail-safe in the sketch where two or more would stop the motor.)

I'm not sure I know how to recreate that. This is the final schematic that I have at this moment. I've got my PCB designed as well. Are there any changes I could make to this design to make it more efficient or component/space saving?

|500x302

Thank you all for your time and help btw!

Even if you must use interrupts to handle button presses, maybe because you use delay() statements in your sketch and you need to “jump” over these, you can still use simple software debouncing. In the interrupt service routine, on a valid call, simply set a timer, say: static uint32_t isrLastCalledAtMs = millis() ;

However, if too little time has elapsed since the last valid call and the current call ( say less than 100mS ) then ignore the call because it is a bounce.

@Kuusou, yeah, like that, OVER the supply :) And important, on the actual layout they must be physically close to the chip.

And like runaway_pancake also showed, no real need for R1, R3 and R5.

And you are still drawing GND evil. Okay, a little less evil but still ;) Just flip all the caps! Then the GND can be down and in line! Room enough to do so. And all switches can easily share the GND that way. Same for C1 to C3. I would even have used pins 1-2 on the switch to go to GND just to make it all look way better.

@runaway_pancake, is it just me or am I really missing a pull down in that design?

@runaway_pancake, is it just me or am I really missing a pull down in that design?

Where?

On that INT pin. Nothing is ever pulling it low.

Kuusou: However my particular case (i need you to trust me on this) I need to have the interrupts attached to the buttons. A hardware solution is the only one I have. My program has some 13 different looping functions that I need to be able to switch between whenever a button is pressed.

That's calling for a state machine, with buttons changing between the states. No interrupts needed, assuming you have done your programming properly. It sounds like debouncing is also not needed - if say button2 switches to loop2, bouncing doesn't matter as you're in loop2 already after the first contact is made. Debouncing is only needed when you have to count button presses.

I may be missing something, but that's basically what you're telling here. So all you need is buttons - no caps, no resistors (use the internal pull-ups), no Schmitt trigger.

So yeah, XY problem.

On that INT pin. Nothing is ever pulling it low.

Is that required? It's designated 'RISING' in the sketch, I think that takes care of it.

Yes, it's required :) It only looks for a rising edge, it does nothing to the state of the pin. Just like on any other input, just letting it float WILL include pick up noise thus it will include a rising edge.

You might get away with it because of reverse leakage current through the diodes. But that's in the order of 5 to 10nA for a 1N4148 @ 5V (aka, at best). Times three that might be enough to keep the pin at a LOW state but I would not count on it. Add some noise and you have a trigger for sure.

May I do A wild guess? You said you've used this design. Is the first thing you do in the ISR to check which of the normal pins fired the interrupt? So any false triggering can be hidden by that if you don't see a HIGH pin on those :-X If so, I think you fire that interrupt way more often then you think ;)

runaway_pancake: On that INT pin. Nothing is ever pulling it low.

Is that required? It's designated 'RISING' in the sketch, I think that takes care of it.

Absolutely required, you must never have an undefined input on an interrupt enabled pin, it might fire all the time from capacitive pickup. With your circuit it might never fire as it stays HIGH all the time, or fire continuously, or only at the weekend, whatever.

septillion: @Kuusou, yeah, like that, OVER the supply :) And important, on the actual layout they must be physically close to the chip.

And like runaway_pancake also showed, no real need for R1, R3 and R5.

And you are still drawing GND evil. Okay, a little less evil but still ;) Just flip all the caps! Then the GND can be down and in line! Room enough to do so. And all switches can easily share the GND that way. Same for C1 to C3. I would even have used pins 1-2 on the switch to go to GND just to make it all look way better.

Ok so remove resistors 1, 3, and 5 and replace resistors 2, 4, and 6 with a 20k. Make the caps/switches all share a ground. So how does this look?

|500x303

The other thing I should mention is part of the problem I believe is button glitching, where i'm pressing the button and on release its registering multiple presses, these circuit are suppose to debounce at 1ms but is that enough? It seems to me that I should make the caps larger so as to increase the debounce time to avoid this issue. Does anyone have any thoughts on this? In programming it seems the normal is 50ms debounce but does follow over to hardware debounce?

wvmarle: That's calling for a state machine, with buttons changing between the states. No interrupts needed, assuming you have done your programming properly. It sounds like debouncing is also not needed - if say button2 switches to loop2, bouncing doesn't matter as you're in loop2 already after the first contact is made. Debouncing is only needed when you have to count button presses.

I may be missing something, but that's basically what you're telling here. So all you need is buttons - no caps, no resistors (use the internal pull-ups), no Schmitt trigger.

So yeah, XY problem.

This was my setup before but when the buttons are pressed they sometimes skip functions in the sequence on release, so its registering multiple interrupts extremely quickly. I've tried to debounce them in software but nothing seems to work.

My program has roughly 14 different LED functions. The PCB has three switches for effect, color, and brightness. Using interrupts I can switch between any looping function without delay or change the color or brightness at any point and it works great (except for this button issue). I had tried other programming but there was always an extremely bad delay on the button presses since the function would be looping. I'm also new to programming and self taught so while there may be a better way to do this its the only way i've been able to find that works. I've posted about this on these forums before but as I said, I would just get referred to blink without delay and honestly just couldn't figure it out. I have no idea how to have 14 looping functions within a loop and how to poll for buttons in such a way that they can be responsive. :(

Also another question I have is when designing the PCB do the individual components have to have traces between their GND connecting them or can they all just be left as is? My first PCB I just covered both sides of the PCB in copper as the grounding layer and that seemed to work just fine. I didn't have any ground traces.