Go Down

Topic: debounce buttons with a analog pin? (Read 546 times) previous topic - next topic

xarvox

Hi all!
My project will be using a bunch of buttons, and that debounce code is everything but neat..

So im trying to figure out other ways to measure the buttons (simple momentary push buttons, directly connected to arduino nano digital pins, with pull-up resistors active).


The idea is to tie each button to its dedicated digital pin, but also, thru a schottky diode (have a bunch), connect it to a analog pin.

So all the buttons (about 6 in total) are connected to D3 thru D9, as well as A0 (thru 6 schottky diodes), to isolate each "channel".


The idea is then to read the digital pin(thisPin) AND analog pin 0, if A0 is NOT between 1V and 3.5V, (schottky voltage drop of about 0.5v, 1v margin of error, project is on 5V)  detect the button as is, if LOW; then PRESSED.
else if A0 = 1-3.5v, repeat read_inputs block

To explain in a different way, the analog pin is supposed to detect a floating signal (not Vss or Vcc), and if it detects a floating signal, it nullifies the digital pin read, forcing the program to repeat the read input block.


Now, the question is; will this actually work?
Will a analog read, in combination with a digital read (on the same button) result in a non-bouncing input signal?



Ive had a similar idea, but instead of the analog pin, tie the schottky diodes to digital pin 2 or 3, witch supports interrupts.
I would then be able to use interrupt to initiate the read_input codeblock, and compare thisPinRead with interruptPinRead, if same, then allrightie then, else button is bouncing.

Since i figure that eventually, the bouncing will stop, rendering the interuptpin and thisPin equal, witch in turn returns the correct button state.



Would this be a better option? If so, why? If not, why? (im trying to learn here.. :) )



Are there other ways to eliminate the button debounce issue?

I´ve seen some suggestions towards hardware debouncing, how much PCB real-estate does it cost?
Is it unfeasible for most projects, or is it just a few SMD parts?

PaulRB

So all these crazy ideas using diodes and extra pins are because a piece of code is not neat? Post the code and we will help you make it neat.

xarvox

Well, yes, to be simple, i dont like debounce, and would like to find another way to reliably read the button states.

And posting my code would not help in any way, you guys would laugh at my incompetence, suggest i take a programming course and have me read the debounce tutorial or something.. :)




The thing is that i do not want to debounce each button separately, since it requires more ram, but i havent had much luck in debouncing ALL buttons in one go eather, mostly because of ram usage.
Im trying to keep the hardware usage to a bare minimum at this stage, since all of the features are not inplemented yet..


Regarding the "normal" way of debouncing, it demands that i keep track of time elapsed, debounce time values, this&lastbuttonRead and so on...
This works fine for a single button, but this isnt very neat when dealing with multiple buttons of different types, and it requires a whole bunch of variables, values and so on to be stored in memory.

I also need short/longclicks, as well as HOLD-clicks, witch makes the software a bit more of a hazzle..



So please dont loose focus, this thread is about ways to skip the debounce shite, not to fix it. :)




Yet another way to "debouce" would be to have the main loop to read each button, if pressed; add 1 to button[thisPin] array, if not pressed, set button[thisPin] to = 0.

If button[thisPin] >= 3, button is pressed and "debounced".



So, what do you guys say, is there a (reasonable) way work around the debounce shite?




And a final and off-topic note, i can not for the life of me understand why one has to debounce a button manually, i figure this should be done in hardware in the Atmega chip...
This current debounce requirement feels like someone cut (at least) one corner too many in the development stage..

And yes, i understand what bouncing buttons are, but i fail to understand why the controller doesnt incorporate bouncing filters.

PaulRB

No chip designer is going to waste silicon on something as simple to achieve in software as button debouncing.

Tell us more about the buttons. How many (7)? What type? What kind of usage will they get? Are they together like a keypad, a control panel or a music keyboard? Will they be pressed one at a time or simultaneously in rapid combinations, and if so how important is it to recognise each press in sequence and in length?

The reason buttons often have to be debounced is because microcontrollers are so fast that they can pick up on the bouncing, if they constantly check the input pin. If you slow down that process, like only checking the buttons 10 or 20 times per second, the bouncing is not a problem. But there is then a danger of missing very short presses. So that's why it's important to know how the buttons will be used.

groundFungus

#4
Aug 13, 2017, 03:22 pm Last Edit: Aug 13, 2017, 03:27 pm by groundFungus
I expect to get reamed for suggesting it, but consider hardware debounce  A 0.1uf cap across the switch is all that it takes to debounce it.  If not the switch is probably bad.

larryd

I expect to get reamed for suggesting it, but consider hardware debounce  A 0.1uf cap across the switch will debounce it.  If not the switch is probably bad.
This works well.



.
No technical PMs.
The last thing you did is where you should start looking.

xarvox

Ehm.. are you guys kidding me?? is a tiny capacitor enough to debounce the button??

Well, this feels awkward, how did i not know this??


Thank you kindly for bringing that to my attention, i belive i just solved the debounce shite! :)

Would a capacitor be connected directly to the button, or the arduino (button pin), or anywhere on the cable?
Im asking because sometimes the position is important when it comes to capacitors, but im too much newbie to understand why..

Also, in case i do not have that specific value, a larger value would still debounce the button, but the cap just takes some tiny amount of time longer to fill up?
In other words, any cap should suffice, but try to keep it around 0,1µF? Or MINIMUM 0,1µF?





Regarding the other questions:
The buttons are used to control horn, turn indicator and so on and are placed around the users thumbs on the handlebar, much like on a motorcycle.

So there are 4 "channels" for the buttons, turn right/left, horn and loud_horn.
I will probably be doubling up some of buttons, so i can use the horn with both hands for instance.

The minimum duration of a interesting keypress would be somewhere around 0.1-0.2 seconds, a quick "mouseclick" type of action.


I will allow multiple simultanious button presses, i want to be able to use the horn even when im activating the turn indicators and so on.


There are also 3 inputs dedicated to a 3way sliding switch, to set current mode, to turn on/off position lights and to toggle hazard light blinks.

The slide inputs are not to change that often, so a 0.5second delay would be fine, even tho i´dd rather have a delay to short to notice.





groundFungus

Quote
Would a capacitor be connected directly to the button, or the arduino (button pin), or anywhere on the cable?
That is a good question.  I usually put the cap at the switch.  I googled "hardware debounce cap location" to see if there is any info to validate how I do it and didn't really find anything, so am not sure that it matters.

Quote
Also, in case i do not have that specific value, a larger value would still debounce the button, but the cap just takes some tiny amount of time longer to fill up?
If you use too large a cap the RC time constant will be longer, but the bigger factor, I think, is with large caps (1uf or greater?), contact arcing could adversely effect contact life.  Experimenting is allowed.  Try a smaller value, try a larger value. See what happens.

If you are going to be in the hobby for a while, buy 0.1uf caps by the hundred.  They are the most used cap value in my experience.

Long ago, before microcontrollers came with all of the peripherals built in, timer chips were an expensive (cost and board real estate) option.  Hardware debounce with a cap, SR flip flop or Schmitt trigger were about the only ways.  

PaulRB

I am no longer sure now why you want to debounce the buttons at all. If is a simple press-to-start-doing-something, release-to-stop operation, there is no need to debounce at all. You only need to debounce when you need to perform a once-per-click-only operation such as registering a keystroke on a keypad or counting the clicks to cycle through a set of options such as in a menu, setting a mode etc. These are the situations where double/triple-registering a press because of button bounce is unwanted.

xarvox

groundFungus;
Hmm.. my buttons will be external, encased in hotglue plastic.. so im not sure if i can have the cap´s on the button itself..

And im getting a bit confused regarding the exact connection of the cap..
Do i put the cap´s each leg to each leg of the button, in essence parallell with the button?
Or am i supposed to connect ground to buttonPin1, buttonPin2 to cap1, cap2 to arduino digital pin? (using pull-ups in software.)

The parallel connection seems to me to be wrong, since the cap would charge from the pull-up resistors, making it impossible to detect the button behind the cap..
I assume im wrong, or just misunderstood something, but on the other hand, my hunches (or gut) are often not wrong..


I ordered a baggie of cap´s on ebay a few years ago, i believe it was 10 of each value, about 15 or 20 values in total.
So i should be good for the time being, but yes, i will be ordering bulk when the economy allows. :)
The prices in sweden are insane, about 0,2€ per resistor (smd), while the chinese parcels often gets "misplaced" by the swedish postal "services"...

So its ether paying a high price for local parts, pay a lower price, but higher shipping on swedish e-commerce sites, or pay a good price(low as fsck), with a reasonable shipping cost, but at a roughly 20% risk loosing your package before you get it.


lol @ "if you're going to be in the hobby for a while"... :)
I believe i found my calling in life, my only regret is that i didn't learn it when i was a young lad.. :P :)
..its VERY hard to learn electronics and programming by yourself, even if you have internet to help you..
..especially when you passed the half-way mark on your way to eternity...


Paul;
Well, when you put it like that, i cant really argue.. :)
But i wont be "simply" using "press-for on, release for off" type of button trigger, i will be using multiple types of clicks, like shortclick/longclick/longpress.

With that said, i still don't know exactly why i would debounce them, i kind of though it was necessary, for some reason or another..

But on the other hand, i cant have the features popping on or off at random and many of the features are "latching" in software, so i click a button to invert the current state of that specific feature, turn ON the turn indicator if it was off and vice versa.

Some of the features are disturbing for others in traffic, a truck horn going off due to bad debouncing is not a welcome surprise at the red lights...
..and yes, im aiming at a electric truck horn as my loud horn, the polite horn will be a LOT quieter.. :)


But still, i´ve just learned that i can use cap´s to eliminate bouncing, so this discussion is now purely academic, to further my development on the topic. :)


groundFungus

#10
Aug 14, 2017, 11:18 am Last Edit: Aug 14, 2017, 11:26 am by groundFungus
Here is how a switch is wired.  Each switch gets a cap.  



xarvox

Thanks Fungus! (what would i ever do without you?? :) )




so, as i understand it, when the button gets pressed, both sides of the cap gets grounded, therefore: cap emptied, and the digital input reads 0V.

And when the button is not pressed, the pullup charges the cap to vcc, so a digital read returns HIGH.

So when the button is bouncing, the input still reads unpressed while the cap is emptying, until it suddenly reads pressed?

Is this correct?

..sorry for nagging about this, but im slowly grasping the finer details here, and just want to make sure im not wrong before i store the knowledge as fact. :)


groundFungus

#12
Aug 14, 2017, 01:38 pm Last Edit: Aug 14, 2017, 01:40 pm by groundFungus
Quote
So when the button is bouncing, the input still reads unpressed while the cap is emptying, until it suddenly reads pressed?
That is kind of backward.  When the button is pressed, the cap is shorted (0V across the cap) and the input is LOW.  If the contacts open, due to bounce, the cap begins to charge at the rate determined by the pullup resistance (RC time constant) .  So the cap starts at 0V and slowly (relatively), the voltage begins to rise.  If the switch closes again quickly the voltage is brought back to 0V again.  And as long as the voltage during the charging never reaches Vcc * 0.6 (the threshold for logic HIGH) the input will read LOW.

larryd

#13
Aug 14, 2017, 04:30 pm Last Edit: Aug 14, 2017, 04:31 pm by larryd
Using a capacitor is a great way to de-bounce switches.

As far as software is concerned, just read your switches every 50ms.
This will suffice for 99.999% of the time.

Code: [Select]

if (millis() - switchMillis >= 50ul)
  {
    switchMillis = millis(); //reset timing
 
    //it is time to go read the switches
    chechSwitches();
  }   



.
No technical PMs.
The last thing you did is where you should start looking.

MorganS

I would put the cap as close as possible to the Arduino. That way it will also act as a filter to exclude interference picked up by the long cable. More filtering is possible if you put a resistor in the line coming in to the Arduino box.

If you're riding your pushbike on the road, you will get interference from the ignition systems of nearby cars.
"The problem is in the code you didn't post."

Go Up