If you’ve ever used an LED with a Raspberry Pi, then you probably know how GPIO outputs work. Code makes electricity flow through General Purpose Input / Output (GPIO) pins, passes through the LEDs, and lights things up. But have you ever tried doing the reverse? With pushbuttons, you can do the exact opposite. This tutorial shows you how to turn a GPIO pin into an input pin, listening to every button press you make!
How Pushbuttons Work
A pushbutton is a type of switch. It has two separate conductive pins that prevent a complete circuit by being separate from each other. When you press on a pushbutton, you’re actually pushing the two pins together, completing the circuit. But if you let go, there’s a spring-like mechanism that separates the pins again.
The typical pushbutton in sensor kits has four pins, with each pin separated from the others. A moving plate of metal sits right below the button area, which goes down and connects all the other pins when the pushbutton is pressed downward.
You’ll find two plates inside a 4-pin pushbutton. Each is connected to two external pins. Both plates are kept separate from each other and can only be connected by pressing on a third plate – the metal plate underneath the button.
In a way, there are always two pins connected in a pushbutton. When you press the 4-pin pushbutton, you connect all four pins together.
Using Pushbuttons with Raspberry Pi GPIO Pins
This time, we are making the Raspberry Pi GPIO pins detect a button press from a pushbutton. When electricity passes through it, the Raspberry Pi will print out a message telling you that it’s working.
Things You’ll Need
- Pushbutton (4-pin)
- Resistor (one between 100Ω and 1000Ω should work)
- Jumper wires
- Voltmeter (optional)
- Raspberry Pi
- Monitor and keyboard (or SSH)
How to Use Pushbuttons
- Open your choice of code editor and paste the following code:
import RPi.GPIO as GPIO from time import sleep GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) while True: if GPIO.input(7) == GPIO.HIGH: print("Pin 7 is HIGH!") elif GPIO.input(7) == GPIO.LOW: print("Pin 7 is LOW...") sleep(0.15)
- Save as “rpi-pushbutton.py” (or any name you want as long as the file extension is the same).
- Build the circuit. On one pin of the pushbutton, wire it up to pin 7 and a resistor in parallel. Attach a jumper wire to a GND pin (pins 6, 7, 14, 20, 25, 30, 34, or 39) at the other side of this resistor, then attach another jumper wire to a 3.3V pin (pins 1 or 17) on a separate pushbutton pin.
Tip: to find the right pin number, hold your Raspberry Pi in a way that the GPIO pins sit in the upper-right corner. The top-left pin is pin 1, and to the right of it is pin 2. Below pin 1 is pin 3, to the right is pin 4, and so on.
- Power up your Raspberry Pi and open the terminal. Use
cdto move to the Python script’s directory, then enter
python3 rpi-pushbutton.py. If you used a different filename, use that instead of “rpi-pushbutton.”
- You should see a new line of text saying
Pin 7 is LOW...every 0.15 seconds on the terminal. If you press the button, the new line will be
Pin 7 is HIGH!.
If you switch the GND and 3.3V pins, with 3.3V on the resistor and GND on the other side of the pushbutton, you’ll reverse the pushbutton’s logic. It will output
Pin 7 is HIGH! all the time and become
Pin 7 is LOW when you press the button.
Hardware on Pushbuttons
Pushbuttons use two kinds of resistors: pull-up and pull-down. The one with 3.3V connected to the resistor is a pull-up resistor. It pulls the voltage upward. Meanwhile, pull-down resistors pull voltage down by having a GND pin connected to them.
You can still use a pushbutton without a resistor, but doing that leaves your GPIO pin on float. A floating GPIO pin receives no direct electric charge, so it looks for charges over its surroundings. If there’s a strong electromagnetic field near it, for example, it will just measure that instead.
That’s why you need a reference point. If you hook the GPIO pin to 0V (GND) by default, then it will measure 0V while the button is unpressed. But if you don’t, the GPIO pin’s value can be anywhere – even negative volts!
Floating pins can do some interesting things, though. If you leave a pin floating, it can sense the voltage difference in the air, measuring even the effect of having your finger move near the pin itself. It’s like an electromagnetic presence sensor or something.
It’s too bad you can’t just do that on the Raspberry Pi, though. For that to be useful, you’ll need analog pins, and the Raspberry Pi doesn’t have them.
Code for Pushbuttons
Knowing that, you should understand that pin 7 senses whether 3.3V or 0V passes through it. If it senses 3.3V, then it reports itself as HIGH. But if it senses 0V, then it’s LOW.
Let’s divide the code into three parts: import commands, setup commands, and looped commands.
We are using two import commands:
import RPi.GPIO as GPIO from time import sleep
import RPi.GPIO as GPIO imports the RPi.GPIO module, which lets you do stuff with your Raspberry Pi’s GPIO pins. By adding in
as GPIO at the end, you’re telling Python to say that typing
GPIO is equivalent to typing
RPi.GPIO. You can even replace it with other strings, and the code should still work as long as you format it properly.
On the other hand,
from time import sleep imports only a part of Python’s time module. It lets you use the
We are working with the three commands from the RPi.GPIO module on the setup commands to fix some settings.
GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
The RPi.GPIO module normally shows a message that warns you about using the GPIO pins as soon as you start up the Python script.
GPIO.setwarnings(False) prevents that from happening.
GPIO.setmode(GPIO.BOARD) is another command from the RPi.GPIO module. It tells Python that you’re using the “BOARD” pinout. There are two kinds of pinout in RPi.GPIO: BOARD and BCM. BOARD lets you pick pins by using the pin numbers. BCM (short for “Broadcom”) lets you pick pins with their individual Broadcom SOC Channel. BOARD is much easier to use, as it’s always the same no matter what kind of Raspberry Pi board you use. The BCM pinout can change depending on which model you use.
GPIO.setup(7, GPIO.IN) lets you set pin 7 as an input pin. It uses the
.setup() function and reads
7 as the pin you’re trying to choose.
GPIO.IN means you’re trying to set that as an input pin.
Embedded systems normally just use a few lines of code and loop them indefinitely. Different programming languages use different ways to do it. But the concept is the same: they use some sort of a loop. For Python, that’s
while True: if GPIO.input(7) == GPIO.HIGH: print("Pin 7 is HIGH!") elif GPIO.input(7) == GPIO.LOW: print("Pin 7 is LOW...") sleep(0.15)
while True: lets you loop code indefinitely. Everything you place in it will run forever as long as there’s electricity on the board.
if GPIO.input(7) == GPIO.HIGH: is an if statement. It says that if pin 7, which is an input pin, reads as
HIGH, then it should do everything inside it.
print("Pin 7 is HIGH!") is inside an if statement. All it does is print out
Pin 7 is HIGH! on the console. You can replace that with any string, number, or variable that contains those.
elif GPIO.input(7) == GPIO.LOW:. It’s basically the same as
if GPIO.input(7) == GPIO.HIGH: except for the first part: it uses
elif instead of
if. The code
elif stands for Else If. What it says is that if all the other code above it returns false, then Python should run this else-if statement.
sleep(0.15) pauses the code for 0.15 seconds. Why pause the code at all? It’s mostly for performance issues. The Raspberry Pi will send output code so fast that it’s going to make your GUI lag a bit. It’s even more pronounced if you’re using your Raspberry Pi via SSH. There’s going to be a noticeable delay that will just get worse over time. Pausing the code slows it down to avoid performance issues.
Frequently Asked Questions
Is it safe to hot-swap pins on the Raspberry Pi?
Hot-swapping, or replacing the Raspberry Pi’s pins while powered on, is generally a bad idea. It’s always safer to remove it from the power supply before switching.
What makes 4-pin pushbuttons better than 3-pin pushbuttons?
Utility-wise, they’re basically the same. But having four pins lets you wire the 4-pin pushbutton to another pushbutton in a series circuit.
Can I turn any pin on the Raspberry Pi as an input pin?
The Raspberry Pi may have 40 pins, but only 27 of them are GPIO. You can only program GPIO pins into input and output pins. Most IDEs won’t let you reprogram a non-GPIO pin into an input pin.
All photos and screenshots by Terenz Jomar Dela Cruz
Our latest tutorials delivered straight to your inbox