# Debouncing Buttons — Arduino & Embedded C

Source: https://www.geekswithgeeks.com/en/arduino-embedded-c/debounce

> 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.

```cpp
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.

**Quiz:** What does a software debounce do?

- [ ] Increases the voltage on the pin
- [x] 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.
