A push button looks trivial but trips up a lot of beginners because of two things: floating inputs and mechanical chatter. This walks through wiring a button to a Raspberry Pi and reading its state in Python, using the internal pull-up resistor so you don't need any extra parts beyond the button itself.
The full tutorial, with every detail and the line-by-line code explanation, is on our site: Raspberry Pi - Button
What you need
- Raspberry Pi 5
- Breadboard-mount Button with Cap
- Breadboard-mount Button Kit
- Panel-mount Push Button
- Push Button Module
- Breadboard
- Jumper Wires
- Screw Terminal Block Shield for Raspberry Pi
- Raspberry Pi Prototyping Base Plate & Breadboard Kit
- DIYables Sensor Kit (18 sensors/displays)
- DIYables USB Type-A to Type-B Cable
Wiring
A button has four pins, but internally they're linked in pairs, so only two are actually independent. Connect one of those two pins to GND and the other to a Raspberry Pi GPIO pin, for example pin 16. For a panel-mount button the idea is the same; if you want tidier connections, a Screw Terminal Block Shield for the Raspberry Pi makes it easier to secure the wires instead of relying on breadboard jumpers.
How it works
Inside the button there are two pins, call them A and B. When the button is not pressed, A and B are disconnected. Pressing the button connects them. Since one pin is wired to GND and the other to a GPIO pin, this turns a mechanical press into an electrical change you can read in code.
Using the Raspberry Pi's internal pull-up resistor on that GPIO pin means the pin reads HIGH when the button is untouched, and LOW the moment it's pressed, with no external resistor needed.
Code
In Python, GPIO.setup() configures the pin as an input with pull_up_down=GPIO.PUD_UP, enabling the internal pull-up. From there, GPIO.input() returns the current state, and because of the pull-up wiring, a LOW reading means the button is pressed. One script just polls and prints the state continuously; a second script is built around detecting the moment of a press rather than just the current level.
raspberry-pi-button.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 """ import RPi.GPIO as GPIO import time # Define the GPIO pin connected to the button BUTTON_PIN = 16 # Set the GPIO mode to BCM GPIO.setmode(GPIO.BCM) # Initialize the pushbutton pin as an input with a pull-up resistor # The pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) try: while True: # Read the state of the switch/button button_state = GPIO.input(BUTTON_PIN) # Print out the button's state print(button_state) # Small delay to avoid unnecessary printing time.sleep(0.1) except KeyboardInterrupt: print("\nExiting...") # Clean up GPIO settings GPIO.cleanup() Things that go wrong
If you skip the pull-up or pull-down resistor, the input pin floats, meaning it picks up random noise and the value it reports has nothing to do with whether the button is actually pressed. Using the internal pull-up as described avoids this entirely.
The other common issue is chattering: mechanically, a single press can cause the pin to flicker between LOW and HIGH several times in rapid succession, so your code sees multiple presses instead of one. This is a known physical quirk of switches, not a bug in your code.
Full tutorial
The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-button



