Lesson 5 / 25
Debouncing Buttons
One press, many edges.
Why mechanical contacts bounce
When a mechanical button closes, its metal contacts physically bounce for a few milliseconds, so the pin can toggle between HIGH and LOW many times. Code that counts presses or toggles on each change will see several presses. Software debouncing accepts a new state only after the reading has stayed stable for a short window (often 10-50 ms; tune for your switch). Edge detection compares the debounced state with the previous one so you act once per press rather than continuously while held. Hardware alternatives include an RC filter, optionally with a Schmitt-trigger input.
Toggle an LED once per press
Time-based debounce using millis(); wiring as in the previous topic.
const uint8_t BUTTON_PIN = 2, LED_PIN = 8;
const unsigned long DEBOUNCE_MS = 30;
int lastReading = HIGH, stableState = HIGH;
unsigned long lastChange = 0;
bool ledOn = false;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
if (reading != lastReading) { // raw input changed: restart timer
lastChange = millis();
lastReading = reading;
}
if (millis() - lastChange > DEBOUNCE_MS && reading != stableState) {
stableState = reading; // stable long enough: accept it
if (stableState == LOW) { // falling edge = new press
ledOn = !ledOn;
digitalWrite(LED_PIN, ledOn);
}
}
}Waiting for the echo to fade
Debouncing is like waiting for an echo to die down before deciding what was said: you only trust the signal once it stops changing.
Quick check: What does a software debounce do?
- Increases the voltage on the pin
- Accepts a new button state only after it has been stable for a short time
- Disables the internal pull-up
- Makes the button respond faster to every edge
Answer
Accepts a new button state only after it has been stable for a short time — Stability over a time window filters out contact bounce.