Go Down

Topic: Bouncing exceeding 200 ms (Read 2118 times) previous topic - next topic

SquishyFish

Hi guys,

I've implemented denouncing in my project, and I'm 100% confident that its working. However, the buttons I'm using (arcade style buttons) were fairly cheap and its evident from differing spring strengths, plunger depth etc that quality control on these things is pretty poor.

So after a lot of testing, I've determined that some of them occasionally bounce for more than 200ms. Considering that my project is a MIDI controller, 200ms is about twice as long as I would like, and replacing the buttons isn't something I can afford right now.

So are there other factors at play here that I can alleviate? Can I get cleaner readings with some kind of hardware debouncing?

Grumpy_Mike

Personally I don't like the way the denounce library is written, I would rather cope with debounce when I encounter it.

In your case act on the first transition you see and then do not act on a signal from that button again until the debounce period has passed. That way the button responds immediately but can't be pressed repeatedly very rapidly.

Any hardware debouncing will still produce the same latency as software.

SquishyFish

Grumpy_Mike, that's exactly what I've done. However, it bounces for longer than the 200ms I've set it to wait, and 200ms is far too long for something like this.

I've determined that the bounces don't exceed 300 ms, but like I said thats way too long to wait.

So I'm out of luck here?

odometer


I've implemented denouncing in my project,


Really? What does it denounce?

SquishyFish



I've implemented denouncing in my project,


Really? What does it denounce?


Really? Its a spelling mistake, get over it.

American2020

You sure the problem is bouncing? One thing is bouncing and another is a button pressed that still sending 0s and 1s

Pressing them harder makes any difference?

How do you have them connected right now?
My 3x3x3 Led Cube

[url=http://arduino.cc/forum/index.php/topic,1642

cjdelphi

i can think of a couple ways but the easiest...

place a smallish capacitor across the button so it begins charging when pressed, and then from the + side of the cap to a (experment) a 1 to 100k rezistor to bleed it back to 0v / logic low...

or a 555 in monostable.

or even inverter ic to debounce it... but 200ms is a bit sucky

jrdoner

I've used a 555 in difficult debounce cases.  Use your switch to start a pulse, and feed that into the Arduino.  Once the Arduino's seen it, send a reset out from the Arduino to the 555.  That way, you can fine tune the process to minimize the wait for a bouncy switch to get done bouncing.   Worked great for me in a clock setting circuit.

Good luck

Grumpy_Mike

Quote
I've set it to wait, and 200ms is far too long for something like this.

No not wait, do not use delay, use the millis timer like in the blink without delay so you don't look at that button once it has triggered. You still look at the others during this time.

fungus


I've used a 555 in difficult debounce cases.  Use your switch to start a pulse, and feed that into the Arduino.  Once the Arduino's seen it, send a reset out from the Arduino to the 555.  That way, you can fine tune the process to minimize the wait for a bouncy switch to get done bouncing.   Worked great for me in a clock setting circuit.


There's absolutely no need for extra hardware. Software can do it.

Just ignore all 'presses' that occur less than 200ms after the initial one (ie. remember when the initial press was).

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

fungus


No not wait, do not use delay


delay() is the Devil's Function. Tempting newbies in, making them think they're doing real programming when all the time they're only digging fiery pit for themselves

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

SquishyFish

#11
Apr 22, 2013, 04:52 pm Last Edit: Apr 22, 2013, 05:01 pm by SquishyFish Reason: 1
I should have been clearer; I'm not using delay() or wait().

When the button state is novel, I'm recording the millis value at that time, subtracting it from the current time and checking if the result is greater than 200 ms.

Here's the code:
Code: [Select]
int btnStateStart[16];
int btnState[16];
int btnStatePrev[16];

void setup()
{
 for(int i=0; i < sizeof(btnState); i++){
   btnState[i] = 0;
   btnStatePrev[i] = 0;
 }
}

void run(){

 for (int i=0; i < 16; i++){
   if ((millis() - btnStateStart[i]) > 200){
     btnState[i] = digitalReadMUX1(i);        //get current button state
     if (btnState[i] != btnStatePrev[i]){
       if (btnState[i] == 1) {
         MIDI.sendProgramChange(i+1,1);
       }
       btnStateStart[i] = millis();
       btnStatePrev[i] = btnState[i];
     }
   }
 }
}


Should I be using a different primitive type for the btnStateStart array (containing millisecond values)?

EDIT: I've been looking at ints vs unsigned longs and I could be losing precision due to using ints. I come from a Java background so I wasn't aware that integers in Arduino are only 16-bit, I just assumed they were 32-bit. Could this be the issue? I've anecdotaly noticed that the bouncing seems to get slightly worse after a certain amount of time.


You sure the problem is bouncing? One thing is bouncing and another is a button pressed that still sending 0s and 1s

Pressing them harder makes any difference?

How do you have them connected right now?



Yes, I've tested the buttons extensively. Its not a case of loose contacts or dodgy switch components; they work just fine and the mechanism seems solid enough. Pressing harder/softer/shorter/longer makes no difference.

I'm using crimps like these, but I tested both crimped connections and soldered ones and there was no difference.





I've used a 555 in difficult debounce cases.  Use your switch to start a pulse, and feed that into the Arduino.  Once the Arduino's seen it, send a reset out from the Arduino to the 555.  That way, you can fine tune the process to minimize the wait for a bouncy switch to get done bouncing.   Worked great for me in a clock setting circuit.


There's absolutely no need for extra hardware. Software can do it.

Just ignore all 'presses' that occur less than 200ms after the initial one (ie. remember when the initial press was).


What is a 555?

fungus


Should I be using a different primitive type for the btnStateStart array (containing millisecond values)?


They should be the same type as the value returned by millis().


EDIT: I've been looking at ints vs unsigned longs and I could be losing precision due to using ints. Could this be the issue?


Yes.


What is a 555?


It's an analogue chip people used to use in the 1970s (before we had software).

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Professor Chaos

Hardware debouncing might be your friend;  see http://www.ganssle.com/debouncing-pt2.htm for some ideas.

I have used the RC solution with a model railroad system, where contact between the wheels and rails can be extremely dirty/bouncy.  


But if you need to detect a button release in less than the bounce time I'm not sure there is a decent solution.  At least hardware debouncing has the advantage of automatically "integrating" the amount of time the button is in the closed state.

Grumpy_Mike

Quote
But if you need to detect a button release in less than the bounce time I'm not sure there is a decent solution.

I am sure that there isn't if that is what you need.
It looks like you should get some better switches.

Go Up