By dave | March 5, 2016

When we press a button that’s connected to an Arduino input, it is likely that the button will momentarily “flicker” between the on and off state. This gives false readings for a short period of time after the button is pressed. Problems caused by this can range from the mild annoyance of a slight flicker, to doing something more than once that should have only happened once. Therefore we need a way to ignore these false readings; ensuring we only consider the button pressed or released when we know for sure that it is “stable”. Before we can go any further, we need to understand why we get “bounce” on switches. Please also see the youtube video (over to the left) for a detailed explanation.

diagram of mechanical switch Switches are mechanical and they usually have a spring to hold them in one state or another. Current only passes through the switch when the contact is "closed", and does not flow when it is "open". At the point when contact is made, our input may momentarily flicker between on and off. This is because of the action of the spring and the fact that it may take a moment for the contacts to settle together properly. We can see in the diagram to the left that the switch contacts touch the wire when it is pressed, there is a spring that holds the switch in a normally open state. Now we can understand why it is called de-bounce. It is because we are removing the bounciness or springiness of the switch using software.

An example that highlights bounce

Before anything else, let’s connect a switch up to the Arduino using the circuit below.

example switch circuit wiring to arduino

Wiring a switch to an arduino

Before writing anything to de-bounce, we should expose switch bounce by writing some code that reads the state as often as possible. If your’e using a micro-switch for this, it will take quite a few attempts to make it flicker.

Create a new project in Arduino studio and paste in the code below, changing the switchPin variable to the pin you used:

const int switchPin = 32;

void setup()
{
  Serial.begin(9600);
	pinMode(switchPin, INPUT);
}

int lastState = LOW;

void loop()
{
	int newState = digitalRead(switchPin);

	if (newState != lastState) {
		Serial.print(((float)millis()) / 1000.0);
		Serial.print(":   Switch change event of ");
		Serial.println(newState);
	}
	lastState = newState;
}

After pressing the button lots of times, you’ll eventually see something like:

69.12:   Switch change event of 1
69.12:   Switch change event of 0
69.13:   Switch change event of 1

Pseudo code de-bounce logic

So now we need to write some code that will remove the bounce when the switches state changes. One very common way to do this is to read and then read again, only changing state if the two reads agree.

Let’s look at some pseudo code for this before we start with a sketch:

Read switch digital input
IF the switch has changed from the last reading
  Wait for a short time (may require experimentation with your switch)
  Read switch digital input again
  IF the switch is still in the same state
    Record the new state for the switch
  END IF
END IF

Example de-bounce code for Arduino

In the example below, when the button is pressed or released the new state is printed to the Serial port, but only after ensuring that the switch is in a stable state. Create a new project in Arduino Studio and paste the following into the sketch window, again change SWITCH_PIN to the pin you have used for the switch:

/*
 * This arduino sketch demos one very simple switch debounce technique where
 * we just wait a while after a changed reading, to give the switch time to
 * get back into a steady state.
 */
#define SWITCH_PIN 32

void setup()
{
	Serial.begin(9600);

	pinMode(SWITCH_PIN, INPUT);
}

// the last known good state of the switch
int lastSwitchState = false;

void loop()
{

	// we purposely make the loop faster than normal, because most switches
	// would exhibit some bounce that this speed.
	delay(1);

	// now we read the new input state, and if it's changed we start the
	// debounce logic.
	int switchState = digitalRead(SWITCH_PIN);
	if (lastSwitchState != switchState) {

		// wait a while before proceeding, we need to let the switch settle.
		// depending on your switch this time may be greater. If you wanted to
		// do this as part of a larger loop, rather than calling delay you'd 
		// just use a counter or a timer instead.
		delay(50);

		// now read again, and see if it's still in the changed state. If so
		// then the switch should be in a steady state again now.
		int debounceCheck = digitalRead(SWITCH_PIN);
		if ((switchState == debounceCheck) && (lastSwitchState != switchState)) {
			// yes it is still changed, so now we accept the new state.
			lastSwitchState = switchState;
			Serial.print("Switch changed state: ");
			Serial.println(switchState);
		}
	}
}

Other pages within this category

comments powered by Disqus

We use cookies to analyse traffic and to personalise content. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Please see our privacy policy should you need more information or wish to adjust your settings.