Buttons and switches

Many projects include physical buttons or switches of some kind. The basic principle is simple: Two wires are disconnected until the switch connects them, closing the circuit. (Sometimes the principle is inverted, where the circuit is closed by default and pushing a button opens the circuit until it's released.)

On the software side, you just check whether the signal pin is in a LOW or HIGH state, and branch accordingly.


const int buttonPin = 2;

void setup()
{
	// Prepare the Arduino to read the button as input.
	pinMode(buttonPin, INPUT);
}

void loop()
{
	// Get the button state, either HIGH or LOW
	int value = digitalRead(buttonPin);

	if (value == HIGH) {
		// Do something for HIGH
	}
	else {
		// Do something for LOW
	}
}

Debouncing

Any time a switch opens or closes a connection, there is a brief moment of instability in the signal received by the circuit or device handling the signal. This can cause the signal to be misinterpreted as if the switch rapidly opened and closed multiple times. Dealing with this issue is called debouncing.

Debouncing can be accomplished either by using a hardware debounce circuit to clean up the transition between low and high voltages or, with a microcontroller, by writing software to suppress or ignore the bouncing voltage until the transition is complete.

Software debouncing

The most straightforward way to handle debouncing in software is to rapidly read the state of the switch and only respond after multiple successive readings are consistent with each other. This leads to predictable behavior at the cost of latency (on the order of a few milliseconds).

The implementation is rather simple. It just introduces some boilerplate in the way you handle state.


// Deboucing example
const int buttonPin = 2;

int buttonState;
int lastButtonState = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;

void setup()
{
	pinMode(buttonPin, INPUT);
}

void loop()
{
	int value = digitalRead(buttonPin);

	if (value != lastButtonState) {
		lastDebounceTime = millis();
	}

	if ((millis() - lastDebounceTime) > debounceDelay) {
		if (value != buttonState) {
			buttonState = value;

			if (buttonState == HIGH) {
				ledState = !ledState;
			}
		}
	}

	digitalWrite(ledPin, ledState);
	lastButtonState = value;
}