Raspberry Pi - Button - Debounce

When a button is pressed or released, or when a switch is toggled, newbies often assume that its state is simply changed from LOW to HIGH or HIGH to LOW. In reality, this is not the case. Due to mechanical and physical characteristics, the state of the button (or switch) may be toggled between LOW and HIGH multiple times. This phenomenon is known as chattering. Chattering can cause a single press to be read as multiple presses, leading to malfunction in certain applications.

chattering phenomenon

The method to prevent this problem is referred as debouncing or debounce. This tutorial instructs you how to do it when using the button with Raspberry Pi. We will learn though the below steps:

Hardware Preparation

1×Raspberry Pi 4 Model B
1×Breadboard-mount Button with Cap
1×Breadboard-mount Button Kit
1×Panel-mount Push Button
1×Breadboard
1×Jumper Wires
1×(Optional) Screw Terminal Adapter for Raspberry Pi
1×(Optional) Power Adapter for Raspberry Pi 4B
1×(Optional) Plastic Case for Raspberry Pi 4B

Or you can buy the following sensor kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables.

Overview of Button

If you are unfamiliar with buttons, including their pinouts, how they work, and how to program them, the following tutorials can provide you with more information:

Wiring Diagram

The wiring diagram between Raspberry Pi and Button

This image is created using Fritzing. Click to enlarge image

Let's take a look at the differences between Raspberry Pi code WITH and WITHOUT debounce, as well as their respective behaviors.

Reading Button without Debounce

Before understanding debouncing, take a look at the code without it and observe its behavior.

Detailed Instructions

  • Make sure you have Raspbian or any other Raspberry Pi compatible operating system installed on your Pi.
  • Make sure your Raspberry Pi is connected to the same local network as your PC.
  • Make sure your Raspberry Pi is connected to the internet if you need to install some libraries.
  • If this is the first time you use Raspberry Pi, See how to set up the Raspberry Pi
  • Connect your PC to the Raspberry Pi via SSH using the built-in SSH client on Linux and macOS or PuTTY on Windows. See to how connect your PC to Raspberry Pi via SSH.
  • Make sure you have the RPi.GPIO library installed. If not, install it using the following command:
sudo apt-get update sudo apt-get install python3-rpi.gpio
  • Create a Python script file button_without_debounce.py and add the following code:
""" 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()
  • Save the file and run the Python script by executing the following command in the terminal:
python3 button_without_debounce.py

The script runs in an infinite loop continuously until you press Ctrl + C in the terminal.

  • Press and hold the button for a few seconds, then release it.
  • Check out the result in the Terminal.
PuTTY - Raspberry Pi
Button pressed Button pressed Button pressed Button released Button released

Sometime, you only pressed and released the button once. Nevertheless, Raspberry Pi recognizes it as multiple presses and releases. This is the chattering phenomenon mentioned at the beginning of the tutorial. Let's see how to fix it in the next part.

Reading Button with Debounce

Detailed Instructions

  • Create a Python script file button_debounce.py and add the following code:
""" 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 # Set the GPIO mode to BCM GPIO.setmode(GPIO.BCM) # Define the GPIO pin for your button BUTTON_PIN = 16 # Define debounce time in milliseconds DEBOUNCE_TIME_MS = 200 # 200 milliseconds # 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 and previous state button_state = GPIO.input(BUTTON_PIN) prev_button_state = button_state # Define a function to handle button presses def button_callback(channel): global button_state button_state = GPIO.input(BUTTON_PIN) # Add an event listener for the button press GPIO.add_event_detect(BUTTON_PIN, GPIO.BOTH, callback=button_callback, bouncetime=DEBOUNCE_TIME_MS) try: # Main loop while True: # Check if the button state has changed if button_state != prev_button_state: if button_state == GPIO.HIGH: print("Button released") else: print("Button pressed") prev_button_state = button_state except KeyboardInterrupt: # Clean up GPIO on exit GPIO.cleanup()
  • Save the file and run the Python script by executing the following command in the terminal:
python3 button_debounce.py
  • Press and hold the button for a few seconds, then release it.
  • Check the terminal for the results.
PuTTY - Raspberry Pi
Button pressed Button released

As you can observe, you only pressed and released the button once. Raspberry Pi detects it as a single press and release, thus eliminating any unnecessary noise.

Raspberry Pi Button Debounce for Multiple Buttons

""" 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 # Set the GPIO mode to BCM GPIO.setmode(GPIO.BCM) # Define the GPIO pins for your buttons BUTTON_PIN_1 = 14 BUTTON_PIN_2 = 15 BUTTON_PIN_3 = 18 # Define debounce time in milliseconds DEBOUNCE_TIME_MS = 200 # 200 milliseconds # Set the initial state and pull-up resistor for the buttons GPIO.setup(BUTTON_PIN_1, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(BUTTON_PIN_2, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(BUTTON_PIN_3, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Initialize the button states and previous states for all buttons button_state_1 = GPIO.input(BUTTON_PIN_1) button_state_2 = GPIO.input(BUTTON_PIN_2) button_state_3 = GPIO.input(BUTTON_PIN_3) prev_button_state_1 = button_state_1 prev_button_state_2 = button_state_2 prev_button_state_3 = button_state_3 # Define a function to handle button presses def button_callback_1(channel): global button_state_1 button_state_1 = GPIO.input(BUTTON_PIN_1) def button_callback_2(channel): global button_state_2 button_state_2 = GPIO.input(BUTTON_PIN_2) def button_callback_3(channel): global button_state_3 button_state_3 = GPIO.input(BUTTON_PIN_3) # Add event listeners for the buttons GPIO.add_event_detect(BUTTON_PIN_1, GPIO.BOTH, callback=button_callback_1, bouncetime=DEBOUNCE_TIME_MS) GPIO.add_event_detect(BUTTON_PIN_2, GPIO.BOTH, callback=button_callback_2, bouncetime=DEBOUNCE_TIME_MS) GPIO.add_event_detect(BUTTON_PIN_3, GPIO.BOTH, callback=button_callback_3, bouncetime=DEBOUNCE_TIME_MS) try: # Main loop while True: # Check if the button states have changed and print when they do if button_state_1 != prev_button_state_1: if button_state_1 == GPIO.HIGH: print("Button 1 released") else: print("Button 1 pressed") prev_button_state_1 = button_state_1 if button_state_2 != prev_button_state_2: if button_state_2 == GPIO.HIGH: print("Button 2 released") else: print("Button 2 pressed") prev_button_state_2 = button_state_2 if button_state_3 != prev_button_state_3: if button_state_3 == GPIO.HIGH: print("Button 3 released") else: print("Button 3 pressed") prev_button_state_3 = button_state_3 except KeyboardInterrupt: # Clean up GPIO on exit GPIO.cleanup()

The diagram that illustrates the wiring for the code mentioned:

The wiring diagram between Raspberry Pi and Button Library

This image is created using Fritzing. Click to enlarge image

Video Tutorial

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!