HOME - - - - - - - - Table of contents, my Arduino "How To" articles
Other material for programmers    Delicious Bookmark this on Delicious   Recommend to StumbleUpon

Debouncing Simple Inputs, the Software Answer

Connecting switches, buttons and the like

(If you want help with connecting an input to an Arduino, I have a page for you on that subject.)


The dreaded "switch bounce"....

Compared to our computers, even the "little" Arduino, we humans are dreadfully slow.

There are many times when your assumptions about what your Arduino is "seeing" will get you in trouble.

This essay is the "short answer" (!) to the questions "What is switch bounce, switch chatter? How do we debounce things?". If you are keen to become a better Arduino designer, I recommend my long, excellent (if I do say so myself) essay nominally about making a door monitor. It goes into many topics, including switch bounce and good program development techniques. These things are hard to address adequately in "bite sized" quick answers. But if you don't have time and energy for the work.... I'll understand!

Here's the "short answer": Consider a simple momentary switch, the sort you would have on a doorbell. You might think that if you wire it up right, then the Arduino will see a 0 on the input most of the time, then a 1 while the button is pressed, and then the input "should", you would think, go back to 0. If I were to write out the state of the input every millisecond, with "...." for long strings of 0s or 1s, you would imagine, I suspect, that one press and release of the button would look like.....

0000....000011111111111111....1111111110000.....0000....

In fact, what will happen with many switches is more like....

0000....000000101100111111....1111111010110.....0000....

The difference is that, for a moment or so after the first closing of the switch, as you press the switch down, the connection is broken and made and broken several times, before settling down in the "made" state, and staying there until you release the switch. And a similar thing happens during the release phase... After the first "0", you don't get just zeros until the next time the switch is pressed down. You get a few makes and breaks until the switch settles in the "broken" ("open") state.

Sometimes it doesn't matter. In the program that follows, if you left out all the fancy bits, and just told the Arduino to turn the LED on when the switch is closed, off when it is open, you would never see the "flickering" during the change from open to closed, or the change back to open from closed.

However, consider on the other hand, a program which is supposed to count how many times a momentary switch has been pressed. That would almost certainly "count" the "flickering" as the contacts "bounce" while closing and opening. In a situation where, in human terms, you have only pressed and released the button 5 times, the Arduino might be reporting a dozen or more openings and closings.

What to do??

There are many solutions. The one below is very simple. Have a look at it in a moment. It does suffer from being a "blocking" solution, which I will discuss. If you want a non-blocking input monitoring answer, I've written one of them up, too... but even so, study what follows for what it can teach you, unless you already know the things below.

In a moment, I am going to speak of the program going "to sleep". I only mean this in the everyday sense. I am not talking about some low power "sleep mode" of the chip's electronics.

What is happening in the program below is that as soon as it sees the first closing of the switch, the program just "goes to sleep" for a moment. While the computer executes the "delay(10)" command, it is "twiddling its thumbs", "ignoring" (most) things. I've used "delay(10)" in the example below, which gives rise to 10 milliseconds of thumb twiddling. The choice of 10ms assumes....

If the switch is pressed by a human, then the second assumption is reasonable. The exact switch you are dealing with will determine whether the first assumption is valid. 10ms is almost no time at all (human terms). I'd be tempted to use a longer "wait for the bouncing to end" delay. But make it too long, and your program will "go wrong" if you close the switch very, very briefly.

So... we've talked about the first part of the program. After waiting for the bounces-on-closure to pass, we reach the place where I've inserted the following into the code....

//
//Put here: Stuff to happen when switch closed
//

That might, for instance, be the "add 1 to the count" part of the program to count button presses. It must not be anything that takes to long to happen.

Then the program waits until it sees the first dis-connect, the one at the start of the bounces- while- switch- opens. As soon as that first disconnect is seen, the program again "goes to sleep" for 10ms. This is to let the bounces which arise while the switch returns to open to pass by, ignored.

And that's about all there is to it! Have a little read. Put the code in your Arduino, try it....

//Debounce
//31mar10

//For http://sheepdogguides.com/arduino/
//               aht0bounce1.htm

//Note that processing of switch is "blocking"... nothing useful will
//  be done until switch is released... but there can be an action
//  which happens just after switch pressed.

const int Inp0=13;//connect a momentary switch
   //connected to GND to this pin
const int Out0=12;//connect an LED and resistor
   //connected to GND to this pin.
   //LED is just for a "switch state" indicator

void setup()
{
pinMode(Inp0,INPUT);
digitalWrite(Inp0,HIGH);//Yes... WRITE to the input pin...#
  //This causes the Arduino to "attach" an internal pull up
  //resistor to the input pin.
pinMode(Out0,OUTPUT);
digitalWrite(Out0,LOW);//Turn LED off to start with.
};

void loop()
{
if (digitalRead(Inp0)==LOW) {DealWithSwitchPress();};
};

void DealWithSwitchPress()
{
digitalWrite(Out0,HIGH);
delay(100);//Wait while closure-of-switch bounces pass
//
//Put here: Stuff to happen when switch closed
//
while (digitalRead(Inp0)==LOW){;};//do nothing while waiting
digitalWrite(Out0,LOW);
delay(100);//Wait while opening-of-switch bounces pass
//
//Put here: Stuff to happen when switch finishes opening
//
}


I hope that has made things more clear for you? The official Arduino pages have good information, too, of course!

So far, so good, but....

Why is there always a "but"?

The tricks used above are fine if you will only ever have one switch down at a time. It is fine as long as you don't mind if the computer does nothing else while the switch is down, which will often be fine for a single momentary ("doorbell" type) switch. But you won't always have only one switch. What will the problem be?

The trick above is called a "blocking" solution. While the switch is closed, the program is stuck in the "While..." loop. It is blocked from doing anything else.

There are solutions to such problems. I'll try to write them up another time... especially if I get some shareware sales citing this page as what led you to my Windows freeware and shareware pages! (Self promotion doesn't get much more shameless than that, but those programs are under-appreciated... awwww.... and they were a lot of work!!)



   Search this site or the web        powered by FreeFind
 
  Site search Web search
Site Map    What's New    Search

The search engine is not intelligent. It merely seeks the words you specify. It will not do anything sensible with "What does the 'could not compile' error mean?" It will just return references to pages with "what", "does", "could", "not".... etc.
In addition to the tutorials for which this page serves as Table of Contents, I have other sites with material you might find useful.....

Sequenced set of tutorials on Arduino programming and electronics interfacing.
Tutorials about the free database supplied with Open Office version 2. (If you experienced Adabas with Star Office, ooBase is nothing like it!)
Some pages for programmers.
Using the parallel port of a Windows computer.


If you visit 1&1's site from here, it helps me. They host my website, and I wouldn't put this link up for them if I wasn't happy with their service.




Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!

Click here to visit editor's Sheepdog Software (tm) freeware, shareware pages.


If you liked the material above, here is more from the same source....

Click here to visit the homepage of my biggest site.

Click here to visit the homepage of Sheepdogsoftware.co.uk. Apologies if the "?FrmAht" I added to that link causes your browser problems. Please let me know, if so?

Click here to visit editor's pages about using computers in Sensing and Control, e.g. weather logging.



To email this page's editor, Tom Boyd.... Editor's email address. Suggestions welcomed!


Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org


Why does this page cause a script to run? Because of the Google panels, and the code for the search button. Why do I mention the script? Be sure you know all you need to about spyware.

....... P a g e . . . E n d s .....