Well, today is the day we actually get to use RPi.GPIO a little bit. But, before we get to that, you should know about the two different numbering systems you can use with RPi.GPIO.
If you take a look at the main GPIO header (P1) of the Raspberry Pi, you’ll see that there are 26 pins. The top left pin (as we look at this photo) is called pin 1, the one to the right of it is pin 2. So the next row is 3, 4 etc. and on down to 25, 26. This is how pin headers are numbered.
But Pins have names too
The slightly confusing part is that each pin also has a name, according to what it does. Some of them have alternative functions, but RPi.GPIO doesn’t currently control those, so we’ll ignore them for now. The best way to see which pin number does what is with a diagram…
- red ones are +ve power (3V3 or 5V)
- black ones are -ve ground
- yellow ones are all dedicated general purpose I/O ports (OK, 18 does PWM as well, but forget that for now).
The rest can all be used as GPIO ports, but do have other functions too. If you need 8 or less ports, it’s best to use the yellow ones because you’re less likely to have a conflict with other things. A quick rundown of what the others are…
- greeny/grey – i2c interface
- light grey – UART (serial port)
- orange – SPI (Serial Peripheral Interface)
How to set up BOARD and GPIO numbering schemes
In RPi.GPIO you can use either pin numbers (BOARD) or the Broadcom GPIO numbers (BCM), but you can only use one system in each program. I habitually use the GPIO numbers, but neither way is wrong. Both have advantages and disadvantages.
If you use pin numbers, you don’t have to bother about revision checking, as RPi.GPIO takes care of that for you. You still need to be aware of which pins you can and can’t use though, since some are power and GND.
If you use GPIO numbers, your scripts will make better sense if you use a Gertboard, which also uses GPIO numbering. If you want to use the P5 header for GPIO28-31, you have to use GPIO numbering. If you want to control the LED on a Pi camera board (GPIO5) you also have to use GPIO numbering.
The important thing is to pick the one that makes sense to you and use it. It’s also important to be aware of the other system in case you ever need to work on someone elses code.
So, at the top of every script, after importing the RPi.GPIO module, we set our GPIO numbering mode.
import RPi.GPIO as GPIO # for GPIO numbering, choose BCM GPIO.setmode(GPIO.BCM) # or, for pin numbering, choose BOARD GPIO.setmode(GPIO.BOARD) # but you can't have both, so only use one!!!
So, with a drumroll and a fanfare of trumpets, it’s now time for us to set up some inputs.
How to set up a GPIO port as an input
Use the following line of code…
…changing Port_or_pin to the number of the GPIO port or pin you want to use. I’m going to use the BCM GPIO numbering and port GPIO25, so it becomes…
import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) # set up BCM GPIO numbering GPIO.setup(25, GPIO.IN) # set GPIO 25 as input
We’ve just set up port 25 as an input. Next we need to be able to “read” the input.
Inputs are Boolean values: 1 or 0, GPIO.HIGH or GPIO.LOW, True or False (this corresponds to the voltage on the port: 0V=0 or 3.3V=1). You can read the value of a port with this code…
But it may be more useful to use it as part of your logic…
if GPIO.input(25): # if port 25 == 1 print "Port 25 is 1/GPIO.HIGH/True"
…or store its value in a variable to use in a different part of the program…
button_press = GPIO.input(25)
So, building on what we’ve already done, here’s a very simple program to read and display the status of port 25, but it only does it once, then it cleans up and exits.
import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) # set up BCM GPIO numbering GPIO.setup(25, GPIO.IN) # set GPIO 25 as input if GPIO.input(25): # if port 25 == 1 print "Port 25 is 1/GPIO.HIGH/True" else: print "Port 25 is 0/GPIO.LOW/False" GPIO.cleanup() # clean up after yourself
The above is not really complete yet, what we need to do is add…
- a loop, so we can make it read more than once
- a time delay, so it won’t read the port thousands of times per second
- a circuit with a button, so we can change the status of the port and see the input status change on the screen
- a try: except KeyboardInterrupt: block so we can exit cleanly (we covered this yesterday)
So, let’s make a little circuit
In order to go any further with this, we need to make up a little circuit.
The resistors are used to “pull down” the GPIO25 pin to 0 Volts GND (0V, 0, LOW, False) unless the button is pressed. When the button is pressed, GPIO25 is connected to 3.3V. If you don’t use the resistors, it might still work, but you risk having a “floating” port. It’s not dangerous, (it could be if you had something like a motor attached) but it’s not fully in control either. We’ll cover a bit more on floating ports, pull-ups and pull-downs in another article (probably part 6).
If you don’t have a breadboard, resistors and buttons, you could cheat and just use a jumper wire to connect two pins directly, but you’ll need to be aware of what you’re doing.
Here’s the code with all the extras added to read and display the button’s status, and exit cleanly when CTRL+C is pressed…
import RPi.GPIO as GPIO from time import sleep # this lets us have a time delay (see line 12) GPIO.setmode(GPIO.BCM) # set up BCM GPIO numbering GPIO.setup(25, GPIO.IN) # set GPIO 25 as input try: while True: # this will carry on until you hit CTRL+C if GPIO.input(25): # if port 25 == 1 print "Port 25 is 1/GPIO.HIGH/True - button pressed" else: print "Port 25 is 0/GPIO.LOW/False - button not pressed" sleep(0.1) # wait 0.1 seconds except KeyboardInterrupt: GPIO.cleanup() # clean up after yourself
This is what the above program’s output looks like…
This program uses a polling loop. It checks (polls) the input port 10 times per second. It works well, but is not very efficient. A more efficient, and more advanced way to handle this is with interrupts. I’ve written about how you can use interrupts in RPi.GPIO here.
That was inputs with RPi.GPIO
So now you know how to use RPi.GPIO to set up and read the status of an input port. In part 5, we’ll cover Outputs.
A quick recap of what we’ve covered so far
So now we’ve covered…