Arduino Debounce Code

 When we press a switch, the mechanical contact creates not just a single pulse but a series of pulses with a very HIGH going and then gradual decrease in signal magnitude. Such signal is called spurious signal. This phenomenon that produces spurious signal that when a switch or electrical contact are closed is called bounce. The process of removing the spurious signal is called debounce. The debouncing can lead to false reading of state of switches or push buttons that are used in keypads, keyboards, joystick buttons etc. In scientific instrumentation where accuracy is needed this debouncing phenomenon can lead to serious errors. Also in reading and writing to external EEPROM with Arduino, contact bounce of push button can lead to read/write error.

Here it is illustrated the de-bouncing effect with Arduino to avoid false readings due to contact bounce. It is illustrated how a push button when pressed leads to series of events trigger due to the mechanical contact bouncing effect. Debouncing code for Arduino are provided to eliminate the effect and void errors. 

To illustrate the debouncing phenomenon the following circuit is considered.

arduino debounce push button circuit diagram
In the above debouncing example circuit diagram, a push button is connected to the pin 10 which when read can cause false readings due to contact bounce. A LED is connected to the pin 8 with current limiting resistor.

On the breadboard the Arduino with push button and LED is shown below.

Arduino Debounce with pushbutton and LED

Without Debounc Code

To show later that the debouncing code will eliminate the contact bounce effect we show first the false reading due to contact bounce(false reading means multiple reading).

The code without debouncing code that reads the state of the push button and turns on the LED if the push button is low and also serial prints when the LED is ON is below.


const int SWpin = 12;
const int LEDpin = 7;

void setup(){
	pinMode(SWpin, INPUT);
	pinMode(LEDpin, OUTPUT);

	Serial.begin(9600);
}

void loop(){
	boolean state = digitalRead(SWpin);

	if(!state){
		digitalWrite(LEDpin, HIGH);
		Serial.println("ON");
	}
	else{
		digitalWrite(LEDpin, LOW);
	}
}

As you can see it is a simple Arduino push button led that reads the state of the push button and turns on the LED and prints out the state of the LED if it is turned on.

Now the following illustrates how Arduino reads the push button state multiple times when the push button is pressed just one time. The serial monitor shows multiple ON message instead of single ON message when the push button is pressed only once. This multiple reading by Arduino is because of the multiple contact bounces. 

multiple contact bounce illustration

 A simple debounce code solution

A simple debounce solution is to add a time delay after reading the state of the switch. Example code for this debounce solution is below.


const int SWpin = 10;
const int LEDpin = 8;

void setup(){
	pinMode(SWpin, INPUT);
	pinMode(LEDpin, OUTPUT);

	Serial.begin(9600);
}

void loop(){
	boolean state = digitalRead(SWpin);
	delay(100);	//wait for contact bounce 

	if(!state){
		digitalWrite(LEDpin, HIGH);
		Serial.println("ON");
	}
	else{
		digitalWrite(LEDpin, LOW);
	}
}

In the above simple Arduino deboucing code, we added a 100ms delay using delay function(consider using arduino delay timer without delay function) after reading the state of the push button. The following shows that with this code, when we press the push button, a single ON state is displayed on the serial monitor illustrating that Arduino now is reading or detecting only one time push button press.

simple debounce solution animation

Reliable Arduino Debounce Code

A better Arduino debounce code for reliably detecting the push button press or closing of a switch is below.


const int SWpin = 10;
const int LEDpin = 8;

const int debounceDelay = 50; // 50 ms delay to wait until stable read

void setup(){
	pinMode(SWpin, INPUT);
	pinMode(LEDpin, OUTPUT);

	Serial.begin(9600);
}

void loop(){
	if(!debounce(SWpin)){
		digitalWrite(LEDpin, HIGH);
		Serial.println("ON");
	}
	else{
		digitalWrite(LEDpin, LOW);
	}
}

boolean debounce(int pin){
	boolean state;
	boolean previousState;
	previousState = digitalRead(pin); // store switch state

	for(int counter=0; counter < debounceDelay; counter++){
	delay(1); // wait for 1 ms
	state = digitalRead(pin); // read the pin
		if( state != previousState){
		counter = 0; // reset the counter if the state changes
		previousState = state; // save the current state
		}
	}
	
	return state;	// now return the stable state
}

 In the above code, we have created a function called debounce() that accepts the pin to read which is the pin(SWpin) to which the push button is connected to. This function returns the state which is of boolean type. In this example, it returns false because the push button is pulled high by 10KOhm pull-up resistor. So in the main loop() function when the push button is pressed, a LOW is read which is false state and because we are inverting the state using the operator ! the argument in the if statement is true and the LED is turned on. Everything else in the Arduino debounce program is the same.

Now the following shows how the above debounce work. It shows that a single ON state is printed on the serial monitor and not multiple ON state when a single push button is pressed.

reliable arduino debounce solution animation

Using Internal pullup resistor

In all the above debounce circuit, we have used an external pullup resistor at the push button pin. Arduino(based on ATmega328p microcontroller) have internal pullup resistor feature which when activated the external pullup resistor is not required. Following is the code and circuit diagram with internal pull up resistor.

Arduino internal pullup resistor debounce circuit

Internal pull-up resistor debounce code


const int SWpin = 10;
const int LEDpin = 8;

const int debounceDelay = 50; // 50 ms delay to wait until stable read

void setup(){
	pinMode(SWpin, INPUT_PULLUP);
	pinMode(LEDpin, OUTPUT);

	Serial.begin(9600);
}

void loop(){
	if(!debounce(SWpin)){
		digitalWrite(LEDpin, HIGH);
		Serial.println("ON");
	}
	else{
		digitalWrite(LEDpin, LOW);
	}
}

boolean debounce(int pin){
	boolean state;
	boolean previousState;
	previousState = digitalRead(pin); // store switch state

	for(int counter=0; counter < debounceDelay; counter++){
	delay(1); // wait for 1 ms
	state = digitalRead(pin); // read the pin
		if( state != previousState){
		counter = 0; // reset the counter if the state changes
		previousState = state; // save the current state
		}
	}
	
	return state;	// now return the stable state
}


So in this tutorial we have shown how to write debounce code for Arduino. The above simple debounce code is used in the How to Read Write External EEPROM with Arduino and the reliable Arduino debounce code is used in the Read Write to External EEPROM with Arduino tutorial.

Watch the following video which shows simulation of how the Arduino debounce code works with push button.

See other Arduino tutorials:

- Arduino Hall Sensor RPM


Post a Comment

Previous Post Next Post