Mechanical Switches

Push buttons, switches, rotary selector switches, mechanical encoders, and directional switches are all example of input devices that switch state via a mechanical means.  There are a couple of issues that you must be aware of.

Detecting the state

When a device is connected to a microcontroller input, it must drive the microcontroller pin to 0 volts, or the power supply voltage.  These are the good old 0 or 1 binary states.  To do this with a mechanical switch, the switch is usually held in one state, then switched to the other as shown below.

This circuit shows a pin connected to a switch.  Via the resistor, the pin is held at VCC (no current flows, so there is no voltage drop, making the voltage at the pin, PB0, VCC).

When the push button is pressed, it make the circuit, setting the pin, PB0 to ground, logic 0.  Note that this logic is backwards, (button up = 1, button down = 0) but as long as the microcontroller is aware, it can invert the results.

The resistor in the above circuit is called a pull-up resistor.  It is typically 50k Ohms or more.  It pulls the voltage on the pin up to VCC.  A similar circuit can be made with a pull-down resistor between the button and ground, and measuring the voltage at the switch/button junction.  In this case the logic is not inverted.

So why use a pull-up resistor when it inverts the logic?  The microcontroller optionally can connect an internal pull-up resistor to the input.  This makes wiring easier.  Switches can be wired directly between the I/O pin and ground.


When a mechanical switch changes from one position to another, the mechanical contacts can bounce.  This causes the electrical state to rapidly jump between states until the mechanical actuator settles.  The image below is an oscilloscope's view of a push button debouncing on release.

There are two solutions to this.  One is to use an RC (Resistor-Capacitor) filter to smooth out the result.  The other, simple solution, is to get the microcontroller to wait until status has settled.  In the capture above, the button bounces for about 400us.  On the GenericHID, it will wait for 20ms of steady voltage before signaling a change.

When not to use Debounce and Pull-ups?

If the input device is a digital device, it will not need debouncing and probably wont need a pull-up resistor.  Adding debounce will slow the response, and adding a pull-up resistor, may cause incorrect readings.