GPIO, Pull-up Resistors and Button Debouncing
Read buttons reliably and understand floating inputs, active-low signals and switch bounce.
A floating input is like a question with nobody assigned to answer. A pull-up provides the default answer; pressing a switch deliberately overrides it.
An input pin observes a voltage rather than supplying a defined logic value. If disconnected, capacitance, leakage and nearby electrical noise can change that voltage. A pull-up resistor weakly connects the input to its logic supply. A switch to ground then creates two defined conditions: released is high, pressed is low. This is called an active-low input.
The resistor limits current when the switch closes. With a 3.3 V supply and 10 kΩ pull-up, the closed switch carries approximately 0.33 mA. A direct wire from supply to ground would instead make a short circuit. Internal pull-ups are convenient but their resistance and availability depend on the chip; consult its documentation when leakage or power matters.
Mechanical contacts may open and close repeatedly during one press. Reading every edge as a new press can increment a counter several times. Debouncing accepts a new state only after it remains stable for a chosen interval. A value such as 20 ms is a starting point to measure and tune, not a universal property of every switch.
Separate the debounced level from the press event. A level stays true while held; an event occurs once when the stable level changes to pressed. This matters for menus and counters. Keep polling without long delays so other tasks can run, and verify that voltage on the input remains inside the device's allowed range.
Read buttons reliably and understand floating inputs, active-low signals and switch bounce.
Core ideas
- INPUT_PULLUP normally makes a grounded button active-low.
- Debounce the physical contact before counting presses.
- A level and an edge are different kinds of information.
Closed-switch pull-up current ≈ Vcc / R3.3 V / 10 kΩ = 0.33 mAWork through a practical example
1Connect a button between the selected input and ground; use the board's supported internal pull-up.
2Record the time whenever the raw input changes.
3Accept the input after 20 ms without another change.
4Increment the application counter only on the accepted high-to-low transition.
Counting every low reading as a new press, or leaving the input unconnected without a pull resistor.