DEV Community

Cover image for Raspberry Pi - Button - Debounce
Arduino ESP32 Raspberry Pi Tutorials
Arduino ESP32 Raspberry Pi Tutorials

Posted on Originally published at newbiely.com

Raspberry Pi - Button - Debounce

If you have ever pressed a button once and had your code register two or three presses, you have met chattering. A mechanical button does not switch cleanly from LOW to HIGH; it bounces between the two states for a few milliseconds before settling. This tutorial shows the Raspberry Pi behavior with and without debounce, so you can see the problem and fix it with a simple time check in Python.

The full tutorial, with every detail and the line-by-line code explanation, is on our site: Raspberry Pi - Button - Debounce

What you need

Wiring

Raspberry Pi - Button - Debounce wiring diagram

A button connects to a GPIO pin and to ground. When you use several buttons at once, wiring them directly on a breadboard gets messy, so the tutorial recommends a Screw Terminal Block Shield for Raspberry Pi for the multi-button version, which keeps each wire clamped down and clearly labeled instead of relying on loose jumper wires.

How it works

When the button's metal contacts touch, they physically bounce for a short time, so the GPIO pin briefly flickers between LOW and HIGH before settling on its final state. If your code reacts to every change, it sees that flickering as several presses instead of one. Debounce means telling your code to ignore any state changes that happen too soon after the last one, so only the real, settled press or release gets counted.

Code

The first script, button_without_debounce.py, reads the GPIO pin with RPi.GPIO and reports every change it sees, which is where you can watch chattering happen in the terminal. The second script, button_debounce.py, adds a check against elapsed time before accepting a new state, so a single press and release shows up as exactly one event. Both run as normal Python scripts over SSH after installing the RPi.GPIO library.

raspberry-pi-button-debounce.py

"""
This Raspberry Pi code was developed by newbiely.com
This Raspberry Pi code is made available for public use without any restriction
For comprehensive instructions and wiring diagrams, please visit:
https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-button-debounce
"""


import RPi.GPIO as GPIO
import time

# Set the GPIO mode to BCM
GPIO.setmode(GPIO.BCM)

# Define the GPIO pin for your button
BUTTON_PIN = 16

# Set the initial state and pull-up resistor for the button
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Initialize the button state
button_state = GPIO.input(BUTTON_PIN)

try:
    # Main loop
    while True:
        # Read the current button state
        current_state = GPIO.input(BUTTON_PIN)

        # Check if the button state has changed and print when it does
        if current_state != button_state:
            if current_state == GPIO.HIGH:
                print("Button released")
            else:
                print("Button pressed")
            button_state = current_state

        time.sleep(0.1)  # Adjust the sleep time as needed

except KeyboardInterrupt:
    # Clean up GPIO on exit
    GPIO.cleanup()
Enter fullscreen mode Exit fullscreen mode

Things that go wrong

If you run the non-debounced script and press the button once, watch for multiple press or release lines appearing in the terminal from a single action, that is chattering, not a wiring fault. If the debounced version still shows extra events, double check that the debounce logic is actually comparing against the current time rather than a fixed value, and that each GPIO pin used for a button is wired correctly, especially when you scale up to multiple buttons with the screw terminal shield.

Full tutorial

The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-button-debounce

Top comments (0)