Configurations
Switches are described by 2 parameters:
- Poles
Number of independent circuits controlled simultaneously. - Throws
Number of output positions each pole can connect to.
SPST
Single Pole Single Throw. 1 input, 1 output. Either connected or disconnected.
Used for on/off control, power switches, simple button inputs.
SPDT
Single Pole Double Throw. Common terminal connects to either of 2 outputs.
In MCU circuits: 1 throw to , 1 to GND, common to GPIO. Pin is always at a valid level. No pull resistor required.
DPST
Double Pole Single Throw. 2 independent poles, each with 1 throw, ganged on 1 actuator.
Used when 2 circuits must switch simultaneously (e.g. live and neutral in a mains circuit).
DPDT
Double Pole Double Throw. 2 independent poles, each with 2 throws, ganged on 1 actuator.
Used for DC motor direction reversal and switching 2 signal lines between 2 destinations.
Types
Push Button
A momentary contact switch. Circuit closes only while physically held.
Requires a pull-up or pull-down resistor. Without one, the pin floats when released.
Bistable
A latching switch. Each actuation toggles between 2 stable states.
- MCU reads current state at any time. No interrupt needed.
- Transition edges still bounce.
Examples: toggle switches, rocker switches.
Monostable
Produces a fixed-duration pulse per actuation regardless of hold duration.
A monostable multivibrator starts a timer on the trigger edge. Output goes HIGH for , then returns LOW. Produces a clean, bounce-free pulse. No software debouncing needed.
Edge Detection
Level detection acts continuously while the pin is held. Edge detection acts once per transition.
2 transitions per press-release cycle:
- Falling edge
HIGH to LOW. On a pull-up circuit, moment of press. - Rising edge
LOW to HIGH. On a pull-up circuit, moment of release.
uint8_t prev = HIGH;
void loop(void) {
uint8_t curr = read_pin();
if (prev == HIGH && curr == LOW)
handle_press();
prev = curr;
}
Requires debouncing. Without it, bounce produces multiple spurious transitions per physical press.
Bouncing
When 2 metal contacts meet or separate, elastic rebound causes multiple rapid transitions before settling. Duration: typically –.
Clean Bounce
Transitions are sharp. MCU sees valid logic transitions in quick succession.
Dirty bounce
Voltage sits near the forbidden band. Irregular amplitude and timing. Harder to filter.
Causes:
- Contact oxidation
Oxide layer causes erratic make resistance during early contact. - Contamination
Dust, flux residue, or moisture increase resistance during partial contact. - Worn contacts
Reduced contact pressure worsens bounce count and edge quality.
Debouncing
Delay and Confirm
After the first edge, block for –, then re-sample.
if (button_pressed()) {
delay_ms(20);
if (button_still_pressed())
handle_press();
}
Blocks the CPU for the blanking period. Unsuitable in event-driven or RTOS firmware.
Counter Method
Timer ISR samples the pin periodically. Counter increments while pin holds its new state. State accepted when counter reaches threshold .
void debounce_tick(void) { // 1 ms ISR
if (read_pin() == NEW_STATE) {
if (++stable_count >= THRESHOLD) {
accepted_state = NEW_STATE;
stable_count = 0;
}
} else {
stable_count = 0;
}
}
Any bounce resets the counter. Threshold of 10–20 at 1 ms rate gives – settle time. Non-blocking.
Shift Register Method
A fixed-width integer (8 or 16 bits) holds recent samples. Each tick, shift left and OR in the current pin state at LSB. State accepted only when all bits are identical.
void debounce_tick(void) { // timer ISR
shift_reg = (shift_reg << 1) | read_pin();
if (shift_reg == 0xFF) accepted_state = HIGH;
else if (shift_reg == 0x00) accepted_state = LOW;
}
Advantages over counter method:
- No counter to reset. History is implicit in the register.
- Detects instability over the full window, not just from the last edge.
- Works correctly during dirty bounce.
Hardware RC
RC low-pass filter on the input line smooths bounce transitions. Schmitt trigger converts the rounded edge back to a clean transition. Time constant must exceed worst-case bounce duration.
Hardware RC + Diode
Diode in parallel with the series resistor creates asymmetric time constants.
- On press
Diode forward-biased. Capacitor discharges through diode. Time constant , very short. - On bounce or release
Diode reverse-biased. Capacitor charges through . Time constant , long. Bounce cannot reach before contact re-closes.
Choose –.
SR Latch
SPDT switch wired to SR latch (/ inputs). Moving to 1 throw sets the latch. Moving to the other resets it. Subsequent bounces cannot change the output. Zero software overhead.
Dedicated Debounce IC
RC filter + Schmitt trigger per channel in a single package. Some ICs latch the output until MCU reads it.
Advantages over discrete or software solutions:
- No CPU cycles consumed.
- Consistent timing across all channels.
- Fewer discrete components.
Common ICs:
- MAX6816 / MAX6817 / MAX6818 (Maxim)
Single, dual, octal variants. debounce time. Internal pull-ups. Active-low output. - MC14490 (ON Semiconductor)
6-channel. Debounce period set by : ~ to ~. - SN74LV1T34 + external RC
Schmitt trigger buffer with discrete RC. Lower cost, more components.