Everybody wants to push the button, don’t nobody wanna think about what’s inside the switch.
— Ronnie Coleman, probably
Reading the input from a pushbutton switch is probably the second thing most people do with a microcontroller, after blinking an LED.
It seems simple… but if you want to do it right, it’ll take you on a tour of the entire hardware stack!
-> embedded software
-> microcontroller architecture
-> digital logic gates
-> analog circuit analysis
-> mechanics of the switch
Spoiler
Which will lead to questions like:
“Is anything in your computer really a
1or a0?”
The problem with switches
There’s a metal wiper inside the switch and it literally bounces.
Without debouncing, you might count multiple press and release events in quick succession (over about 10 ms), even though the button was only “pressed” once.
If the switch is connected to a light bulb, you won’t see anything wrong. Your eye doesn’t respond that fast to changes. But a microcontroller can read state changes with microsecond resolution.
The Fixes
A few common ways to debounce in hardware are to use
- a double-throw switch and two input pins
- a Schmitt trigger input buffer
- or an RC circuit
A pretty common way to debounce in software is to:
- read inputs every 5 ms with a hardware timer
- if it goes high and stays high for 10ms (2 ticks) → button pressed event
or, if it goes low and stays low for 100ms (20 ticks) → button released event
More robust designs will use multiple approaches.
The tradeoff: the more delay added to prevent switch bounce, the slower the response to user input.
Measure the bounce time with an oscilloscope!
Readings & resources
Jack Ganssle: A Guide to Debouncing: Part 1
Jack Ganssle: A Guide to Debouncing: Part 2