Pages: [1] 2   Go Down
Author Topic: Bouncing exceeding 200 ms  (Read 1815 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 197
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've implemented denouncing in my project,

Really? What does it denounce?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've implemented denouncing in my project,

Really? What does it denounce?

Really? Its a spelling mistake, get over it.
Logged

Offline Offline
Sr. Member
****
Karma: 9
Posts: 252
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

My 3x3x3 Led Cube

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

Offline Offline
Edison Member
*
Karma: 29
Posts: 2449
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5494
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).

Logged

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

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5494
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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?
« Last Edit: April 22, 2013, 10:01:00 am by SquishyFish » Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5494
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).

Logged

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

0
Offline Offline
Full Member
***
Karma: 1
Posts: 225
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1] 2   Go Up
Jump to: