← Back to Homepage

Button Debounce Algorithm

So this week's assignment was to investigate the concept of debounce. If you've ever worked with physical pushbuttons, you might not know that inside, they have mechanical metal contacts that act like microscopic springs. When you press them, they actually vibrate and "bounce" against each other for a few milliseconds. To a fast microcontroller, this looks like multiple erratic ON/OFF spikes instead of one clean press.

To fix this, I wrote a software debounce algorithm. It essentially uses a timer to filter out all that mechanical noise. It ignores rapid state changes and only registers a press as valid once the electrical signal has stayed completely steady for a short window (about 50 milliseconds).

Python Source Code

import board
import digitalio
import time

button = digitalio.DigitalInOut(board.GP15)
button.direction = digitalio.Direction.INPUT

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

# =========================================
# TODO VARIABLES
# =========================================
last_reading = False       # Tracks the raw reading from the previous loop
button_state = False       # Tracks the actual, confirmed (debounced) state
led_state = False          # Tracks whether the LED should be ON or OFF
last_debounce_time = 0     # The last time the input pin fluctuated
debounce_delay = 0.05      # 50 milliseconds threshold for stability
# =========================================

while True:
    reading = button.value
    
    # STEP 1: Detect change
    # If the current reading is different from the last loop, reset the timer
    if reading != last_reading:
        last_debounce_time = time.monotonic()
        
    # STEP 2: Check if stable
    # If the time since the last fluctuation is greater than our delay threshold, 
    # we consider the signal stable.
    if (time.monotonic() - last_debounce_time) > debounce_delay:
        
        # If the stable reading is different from our officially recorded button state:
        if reading != button_state:
            button_state = reading
            
            # STEP 3: Toggle LED
            # Only toggle the LED when the button transitions to True (a press)
            if button_state == True:
                led_state = not led_state
                
    # STEP 4: Apply output
    # Continuously drive the LED to whatever the current led_state is
    led.value = led_state
    
    # STEP 5: Update last state
    # Save the raw reading for the next time through the loop
    last_reading = reading
    
    time.sleep(0.01)