A debounce timer is a hardware circuit or software routine that filters out the rapid, unintended electrical oscillations caused by mechanical switch contacts, ensuring a single physical press registers as exactly one clean logic pulse. Without it, a microcontroller reading a tactile button might register 15 distinct presses in a single millisecond, completely breaking your state machine or incrementing a counter by a dozen instead of one. Beginners frequently confuse a debounce timer with a simple RC low-pass filter or basic propagation delay; while an RC network smooths the analog voltage, it requires a Schmitt trigger to actually regenerate a clean digital edge, which is the true job of the complete debounce circuit.
The Physics of Contact Bounce (With a Numeric Example)
When the metal contacts inside a mechanical switch close, they do not mate perfectly on the first impact. The moving contact acts like a tiny tuning fork, physically bouncing off the stationary contact several times before settling. This creates a rapid series of make-and-break electrical connections.
Let us look at a concrete numeric example using a standard Omron B3F tactile switch. According to its datasheet, the maximum contact bounce time is 5 milliseconds (ms). If your microcontroller polls the GPIO pin every 1ms, a single button press will look like a chaotic string of 1s and 0s for that 5ms window.
If you choose a hardware RC (resistor-capacitor) approach to swallow this bounce, you need a time constant ($\tau = R \times C$) that outlasts the 5ms bounce period.
The Math: Using a 10 kΩ resistor and a 1 µF capacitor yields a time constant of 10ms ($10,000 \times 0.000001 = 0.01$ seconds). Because an RC circuit takes roughly $3\tau$ to $5\tau$ to fully charge or discharge, this 10ms time constant will easily absorb the 5ms mechanical bounce, holding the voltage steady through the chaotic physical impacts.
Where You Meet This in Practice
You will encounter the need for a debounce timer anywhere a mechanical physical action translates into a digital logic signal. The most common bench and jobsite scenarios include:
- Rotary Encoders: High-resolution optical or mechanical encoders (e.g., 1000 pulses per revolution) generate square waves at high frequencies. Un-debounced mechanical encoder contacts will cause motor controllers to skip steps or reverse direction erratically.
- Matrix Keypads: In a 4x4 keypad matrix, bounce on a single key can cause the scanning algorithm to register ghost keys or multiple simultaneous presses.
- Industrial Limit Switches: Heavy-duty mechanical limit switches on CNC machines or garage doors bounce violently due to their large spring-loaded masses. Failing to debounce these can cause a PLC to trigger a fault state or double-cycle a hydraulic press.
- Relay and Contactor Contacts: Even if the switch is solid-state, if it drives a mechanical relay coil, the relay's own contacts will bounce when they pull in, requiring debouncing on the downstream logic.
Hardware vs. Software: The Decision Tree
Choosing between handling bounce in firmware or silicon is one of the most common design crossroads. Use this decision path to select the right approach for your specific constraints.
| Application Scenario | System Constraint | Recommended Approach | Concrete Pick / Value |
|---|---|---|---|
| Simple UI pushbuttons on an MCU (ESP32, Arduino) | Low speed (<10 Hz), plenty of CPU cycles available | Software Polling / State Machine | Default Pick: Bounce2 library with a 50ms debounce window. |
| High-speed rotary encoders or RPM sensors | High frequency (kHz range), CPU interrupts would be overloaded | Hardware Dedicated Logic IC | Default Pick: MAX6816 (dedicated dual debounce IC) or 74HC14 Schmitt trigger with RC. |
| Industrial 24V limit switches on long cable runs | High EMI noise, voltage spikes, galvanic isolation required | Hardware Optocoupler with filtering | Default Pick: H11L1 Schmitt-trigger optocoupler with a 100nF input filter cap. |
| FPGA / CPLD digital designs | No CPU available for software polling, strict synchronous logic | Hardware Shift Register (Meta-stability filter) | Default Pick: 3-stage flip-flop shift register clocked at 1kHz. |
Implementation Deep-Dive: Getting the Values Right
If you opt for software debouncing on a microcontroller, the most robust method is tracking time deltas rather than using blocking delay() functions. According to the Espressif ESP-IDF GPIO documentation, modern MCUs often include hardware glitch filters on the silicon die, but they are typically limited to very short windows (e.g., a few clock cycles) and cannot replace a proper 20-50ms software debounce timer for human-interface buttons.
delay(50) every time you check a button, your MCU is blind to the rest of the world for 50ms. Use a non-blocking timestamp check: if (millis() - lastDebounceTime > debounceDelay).
If you must use hardware debouncing, the classic 74HC14 hex Schmitt-trigger inverter is the workhorse part. As detailed in comprehensive switch bounce analyses by All About Circuits, the RC network creates a slow, sloping voltage curve. A standard logic gate (like a 74HC04) will oscillate wildly when presented with a slow slope through its linear region. The 74HC14 features built-in hysteresis (different threshold voltages for rising and falling edges), which forces the output to snap cleanly from HIGH to LOW without oscillating, completely eliminating the bounce.
Sizing the Hardware RC Components
When building a 74HC14 debounce circuit for a 5V logic system:
- Pull-up Resistor (R1): 10 kΩ from VCC to the switch node. (Limits current when the switch closes to ground).
- Filter Resistor (R2): 10 kΩ between the switch node and the capacitor/Schmitt input. (Isolates the capacitor from the switch contacts to prevent high inrush current discharge spikes).
- Filter Capacitor (C1): 1 µF from the Schmitt input to GND. (Absorbs the bounce energy).
This specific combination yields a reliable, low-cost debounce timer that consumes less than 0.5mA of quiescent current.
Frequently Asked Questions
Can I just use a capacitor across the switch contacts without a resistor?
No. Placing a raw capacitor directly across a mechanical switch creates a dead short across your power rail for a microsecond every time the switch closes. The inrush current will pit and destroy the switch contacts over time, and can cause localized voltage brownouts that reset your microcontroller. Always use a series resistor to limit the discharge current.
Why does my software debounce timer still register double presses?
If your software timer is set to 50ms but you are still seeing double increments, you are likely dealing with a failing switch or severe EMI. Mechanical switches with oxidized contacts can exhibit "make" bounce times exceeding 100ms. In this case, increase your software window to 150ms, or replace the switch. If the issue only happens when a motor turns on, you are picking up electromagnetic interference, not physical bounce; you need shielded cables or hardware RC filtering.
Do solid-state relays or MOSFETs need debouncing?
No. Solid-state components have no moving mass, therefore they exhibit zero physical contact bounce. However, if the signal driving the MOSFET gate comes from a mechanical switch, that upstream switch still requires a debounce timer to prevent the MOSFET from rapidly toggling in its linear region, which will cause it to overheat and fail.






