Raspberry Pi Push Button
Learn to read the state of a physical push button with gpiozero's Button class, understand why the internal pull-up resistor means you don't need an extra resistor for a simple button, and compare polling with event-driven callbacks.
Input vs. Output
So far, the Pi has been driving pins - deciding whether each one outputs 3.3V or 0V. A button reverses that relationship: the Pi reads a pin, and it's the physical state of the switch that decides what voltage the Pi sees, high when the button's circuit is open and low when it's closed, or vice versa depending on the wiring. Reading input correctly requires understanding not just the switch, but how the pin is 'biased' in between presses.
Wiring a Push Button
A typical push button wiring is simple: connect one leg of the button to a GPIO pin, and the other leg to GND. When the button is pressed, it closes the circuit between the pin and ground. Unlike an LED circuit, you don't need an external resistor here - gpiozero enables the GPIO's internal pull-up resistor for you by default, which gently holds the pin at logic HIGH when the button is not pressed, so it reads a clean LOW only when you actually press it and complete the connection to ground.
The Button Class
Reading a button with a polling loop
from gpiozero import Button
from time import sleep
button = Button(2) # GPIO2 to one leg, GND to the other; internal pull-up handles the rest
while True:
if button.is_pressed:
print("Button is being pressed")
else:
print("Button is not pressed")
sleep(0.2)- `button.is_pressed` - a read-only property that's True exactly while the button is held down
- `button.wait_for_press()` - blocks execution until the button is pressed
- `button.wait_for_release()` - blocks execution until the button is released
- `button.when_pressed` - assign a function here to run automatically on every press
- `button.when_released` - assign a function here to run automatically on every release
Event-Driven Handling
Polling in a loop works, but it wastes CPU time checking the button dozens of times a second whether or not anything changed, and it can miss very short presses if `sleep()` is too long. Assigning a function to `when_pressed`/`when_released` lets gpiozero notify your code only when the state actually changes, which is both more efficient and more responsive.
Combining a button and an LED with events
from gpiozero import LED, Button
from signal import pause
led = LED(17)
button = Button(2)
button.when_pressed = led.on
button.when_released = led.off
pause() # keeps the program alive so the callbacks can keep firing