submit to reddit       

Raspberry Pi GPIO

GPIO pins can be used to connect devices to a computer so that it can control and monitor them. The GPIO pins can be controlled by programs written in almost any programming language. The Raspberry Pi's GPIO pins are in two rows of 13 pins next to the RCA video socket.

There are two libraries that allow programs written in Python to control the Rasperry Pi's GPIO, wiringPi, and the RPi.GPIO module that's installed in Raspbian by default.

You need to be careful about how you connect devices to the GPIO pins. For example, if you connect a motor directly to one of the pins, the current that the motor draws will burn out some of the GPIO circuitry and permanently damage your Pi. It's usually necessary to use transistors, amplifiers or some other buffering mechanism to drive large currents.

Several manufacturers have released interface boards that you can connect to the GPIO pins. One of the easiset to work with is the Pi Face. Another popular interface board is the Gert Board, which is more complex than the Pi Face, but much more flexible.

Different GPIO pins have different functions. Pins 2 and 4 supply power at 5V. Pins 1 and 17 supply power at 3.3V. Pins 6, 9, 14 and 20 are connect to 0V. The remaining pins can be configured for use as inputs or outputs.

See also: elinux.org/RPi_Low-level_peripherals.


Controlling GPIO with wiringPi

The wiringPi libraries are a set of functions written in C that make it easy to control the Raspberry Pi's GPIO pins. You can use the functions in this library to control GPIO pins in your own programs.

You can also use wiringPi on the command line. This is very useful for debugging problems with circuits connected to GPIO pins. It's also useful for controlling GPIO with Bash scripts.

In order to install the libraries, you have to install the 'git' source code management system. Make sure your Pi can access the internet. You can install git by opening a terminal and typing these commands:

$ sudo apt-get install git-core
$ sudo apt-get update
$ sudo apt-get upgrade

Get the wiringPi project using this command:

$ git clone git://git.drogon.net/wiringPi

Change to the new directory, and get the code from the repository at drogon.net:

$ cd wiringPi
$ git pull origin

Build the code:

$ ./build

Test wiringPi by typing this command:

$ gpio readall
+----------+-Rev2-+------+--------+------+-------+ | wiringPi | GPIO | Phys | Name | Mode | Value | +----------+------+------+--------+------+-------+ | 0 | 17 | 11 | GPIO 0 | IN | Low | | 1 | 18 | 12 | GPIO 1 | IN | Low | | 2 | 27 | 13 | GPIO 2 | IN | Low | | 3 | 22 | 15 | GPIO 3 | IN | Low | | 4 | 23 | 16 | GPIO 4 | IN | Low | | 5 | 24 | 18 | GPIO 5 | IN | Low | | 6 | 25 | 22 | GPIO 6 | OUT | High | | 7 | 4 | 7 | GPIO 7 | IN | Low | | 8 | 2 | 3 | SDA | IN | High | | 9 | 3 | 5 | SCL | IN | High | | 10 | 8 | 24 | CE0 | ALT0 | High | | 11 | 7 | 26 | CE1 | ALT0 | High | | 12 | 10 | 19 | MOSI | ALT0 | Low | | 13 | 9 | 21 | MISO | ALT0 | Low | | 14 | 11 | 23 | SCLK | ALT0 | Low | | 15 | 14 | 8 | TxD | ALT0 | High | | 16 | 15 | 10 | RxD | ALT0 | High | | 17 | 28 | 3 | GPIO 8 | IN | Low | | 18 | 29 | 4 | GPIO 9 | IN | Low | | 19 | 30 | 5 | GPIO10 | IN | Low | | 20 | 31 | 6 | GPIO11 | IN | Low | +----------+------+------+--------+------+-------+

You should see a table listing the state of the GPIO pins. Before you can use any of the pins, you must configure them as either outputs or inputs. The following command sets up pin 17 for use as an output:

$ gpio -g mode 17 out

This command sets pin 17 to logic 1:

$ gpio -g write 17 1

The -g option tells the gpio command to use the standard pin numbering scheme rather than the numbering scheme invented for wiringPi. You can test the voltage of pin 17 with a multimeter to see if it changes when you execute the command above.

See also: wiringPi.com


Connecting your Pi's GPIO to a breadboard

A breadboard is a great way of building simple prototype ciruits. They have a grid of holes that wires can be inserted into. The holes are connected to each other in numbered rows in rows across the breadboard.

I used the Ada Fruit Pi Cobbler cable kit to connect my Pi to a breadboard. This kit comes in parts, so you need to solder it together as shown in the images. First solder the rectangular black socket on to the printed circuit board. Make sure to attach the socket the right way round. The notch in the side of the socket should be above the notch in the white outline on the circuit board.

Next, break off two rows of 13 pins from the strip of pins provided, and put them in a breadboard. Put the circuit board on top, and solder the pins in place.

Attach one end of the ribbon cable to the GPIO header on your Pi, and connect the other end to the socket on the newly assembled connector, and you're done.


Detecting a button press through GPIO

Button circuit diagram Button circuit
Button circuit Button circuit

If you want to build electronic devices, at some point you're going to need to read data through GPIO. In this exercise, we're going to read the value of a push button on a breadboard.

Set up the circuit as shown in the pictures on the right. Note that one end of the 4.7kOhm resistor connected to pin 23 is connected to the positive supply rail. The red jum[er cable links the positive rail on the breadboard to the 3.3V pin on the GPIO header. The green jumper wire connected to one of the pins on the button is connected to the negative rail on the breadboard, and there's another jumper cable linking that negative supply rail to a GND pin on the GPIO header.

The resistor is used to pull up the voltage on pin 23 to logic 1. Without it, pin 23 would have an indeterminate value. When the button is pressed, pin 23 is connected directly to ground, so it switches to logic 0.

Save the following code in a file called button.py

#!/usr/bin/env python import time import RPi.GPIO as GPIO def main(): # tell the GPIO module that we want to use the # chip's pin numbering scheme GPIO.setmode(GPIO.BCM) # setup pin 25 as an output GPIO.setup(23,GPIO.IN) GPIO.setup(24,GPIO.OUT) GPIO.setup(25,GPIO.OUT) GPIO.output(25,True) while True: if GPIO.input(23): # the button is being pressed, so turn on the green LED # and turn off the red LED GPIO.output(24,True) GPIO.output(25,False) print "button true" else: # the button isn't being pressed, so turn off the green LED # and turn on the red LED GPIO.output(24,False) GPIO.output(25,True) print "button false" time.sleep(0.1) print "button pushed" GPIO.cleanup() if __name__=="__main__": main()

Make it executable with this command:

$ sudo chmod +x button.py

This code uses GPIO pins 24 and 25 to control two LEDs, so they are set up as outputs. Pin 23 is used to read the button, so it's set up to be an input.

In the while loop, the 'if' statement checks to see if the button is being pushed. If it is, the green LED is turned on and the red LED is turned off. When the button is released, the green LED goes back off and the red one is turned on again.

The program pauses for 0.1 seconds after the if statment, and then goes back to the top of the while loop.

To run the program, type this command:

$ sudo ./button.py


Using Interrupt Driven GPIO

In the previous post, a program keeps executing a while loop checking to see if a button has been pressed. This is called polling, and it's not very efficient because the program can't do anything else while waiting for the button to be pressed. It would be better if the program could do something else while it was waiting.

This can be achieved using interrupt driven IO. An interrupt is a signal generated by a peripheral device that lets the processor know that an event has happened. The RPi GPIO library makes this easy. You simply need to use the add_event_detect function to specify what type of event you're waiting for, and add_event_callback to specify what should happen when the event occurs.

In this exercise I used the same circuit as in the previous exercise, and I used the code below:

#!/usr/bin/env python import time import RPi.GPIO as GPIO # handle the button event def buttonEventHandler (pin): print "handling button event" # turn the green LED on GPIO.output(25,True) time.sleep(1) # turn the green LED off GPIO.output(25,False) # main function def main(): # tell the GPIO module that we want to use # the chip's pin numbering scheme GPIO.setmode(GPIO.BCM) # setup pin 23 as an input # and set up pins 24 and 25 as outputs GPIO.setup(23,GPIO.IN) GPIO.setup(24,GPIO.OUT) GPIO.setup(25,GPIO.OUT) # tell the GPIO library to look out for an # event on pin 23 and deal with it by calling # the buttonEventHandler function GPIO.add_event_detect(23,GPIO.FALLING) GPIO.add_event_callback(23,buttonEventHandler,100) # turn off both LEDs GPIO.output(25,False) GPIO.output(24,True) # make the red LED flash while True: GPIO.output(24,True) time.sleep(1) GPIO.output(24,False) time.sleep(1) GPIO.cleanup() if __name__=="__main__": main()

This program tells the GPIO library to look out for an event on pin 23 of the GPIO header. The event to look out for is a falling edge, where the voltage goes from 1 to 0. This example detects the GPIO.FALLING event, but it's also possible to detect GPIO.RISING and GPIO.BOTH. The function named buttonEventHandler is registered as the callback for the event.

The program then goes round the while loop making the red LED blink. When the button is pressed, buttonEventHandler is called, and the green LED is turned on for one second. The event is handled by a different thread, so while the green button is on, the red light continues to blink uninterrupted.

If your program doesn't need to do anything while its waiting for an event, you can call GPIO.wait_for_edge() which will make your program sleep until an event wakes it up. If your program no longer needs to wait for an event, you can unregister it by calling GPIO.remove_event_detect().

See also: https://code.google.com/p/raspberry-gpio-python/wiki/Inputs


Use GPIO to turn on an LED

The picture on the right shows a breadboard. Cables and component leads can be inserted into the holes to build circuits. The holes are linked by copper strips underneath the surface of the breadboard.

The holes at the edge are connected lengthways in two lines along the breadboard. The line of holes nearest the blue line is used as the negative supply line, and the line nearest the red line is used for the positive supply line. The rest of the holes are connected to each other in rows of five.

Connect the socket built in the previous post to the breadboard.

Many LEDs only need about 20mA to light up. If too much current flows through them, they burn out. A 330 Ohm resistor is needed to limit the current flowing through the LED.

Take a 330 Ohm resistor, and connect one lead to a hole in line with pin 25 on the GPIO cable socket. The other resistor lead should be placed in a hole past the end of the socket. This page on Wikipedia shows how to read resistor colour codes.

Connect a jumper cable from one of the GND pins to the negative supply rail.

Next you need to place the LED in the breadboard. LEDs only allow current to flow in one direction, so you have to get it the right way round. The negative lead is slightly shorter than the positive lead. One side of the circular rim of the LED may be flattened to show that it is the negative side. The negative lead should be inserted into the negative supply line. The LED's positive lead should be inserted into a hole in the same row as the resistor lead.

Now all you need to do is turn on pin 25 of the GPIO header. If you have installed wiringPi, you can use the 'gpio' command to control GPIO pins from the command line.

Run these commands in a terminal to test your LED:

$ gpio -g mode 25 out
$ gpio -g write 25 1
$ gpio -g write 25 0

You should see the LED light up when you write a '1' to pin 25, and it should go off when you write a '0'.

See also: Using Python to control GPIO


Using Python to control GPIO pins

The Raspberry Pi comes with Python libraries for controlling GPIO. You can use the functions in these libraries to set the voltages of the GPIO pins and control circuits like the one in the previous post where I connected an LED to my Pi's GPIO.

Before you can acess GPIO, you need to set up the library by calling the 'setmode' function. This determines which pin numbering scheme will be used in future calls to the GPIO library. It's also important to set up one of the GPIO pins as an output.

The next lines of code turn on pin 25, sleep for three seconds, turn off pin 25, and then clean up the GPIO library.

#!/usr/bin/env python

import RPi.GPIO as GPIO
import time

def main():

    print "executing script"

    # tell the GPIO module that we want 
    # to use the chip's pin numbering scheme
    # setup pin 25 as an output

    # turn pin on 
    # sleep for 3 seconds
    # turn the pin off


if __name__=="__main__":

Save this code in your home directory in a file named led.py, and make sure it's executable with this command:

chmod +x led.py

Run the script by typing this command:

sudo ./led.py

You need to use sudo because the GPIO libraries access operating system resources.


Connecting a temperature sensor to GPIO

In this exercise, we're going to connect a Dallas DS18B20 temperature sensor to a breadboard, and read the temperature through the Raspberry Pi's GPIO pins.

The DS18B20 has a 1-Wire interface, which means that one of its leads is used for serial communications. The other two leads need to be connected to 3.3V and 0V. The sensor itself contains a small circuit that generates serial output. It also contains a unique serial number so that several sensors can be connected in parallel and still be addressed individually.

The circuit diagram and photoraphs on the right show how I set up my bread board. Pin 1 of the sensor is connected to either of the 3.3V pins on the GPIO connector. Pin 3 of the sensor must be connected to one of the ground pins on the GPIO connector. Pin 2 of the sensor is connected to GPIO pin 4. Pin 2 must not be allowed to float, so a pull up 4.7kOhm resistor must be used to connect pin 2 to 3.3V.

Before you can use the sensor, you need to load two kernel modules with these commands:

sudo modprobe w1-gpio
sudo modprobe w1-therm

These modules are device drivers that interpret data from the DS18B20.

Next, you need to type these commands to find the address of the DS18B20 and read from it:

cd /sys/bus/w1/devices/28*
cat w1_slave

When the sensor is detected, a directory is created using the serial number as the name of the directory. All serial numbers for this type of device start with '28', so we can use the '*' operator to change to any directory that starts with '28'. The sensor is represented by the file w1_slave, and you can get a reading from it using the 'cat' command. You should see output similar to this:

67 01 4b 46 7f ff 09 10 3b : crc=3b YES
67 01 4b 46 7f ff 09 10 3b t=22437

The temperature is shown in the last five digits on the second line. You need to divide this number by 1000 to get the temperature in degrees celcius.

As well as getting readings from the sensor by accessing it via the command line, we can also use a python script to get readings. The python script below goes through the same steps as above.

#!/usr/bin/env python

import os
import glob
import time

# load the kernel modules needed to handle the sensor
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

# find the path of a sensor directory that starts with 28
devicelist = glob.glob('/sys/bus/w1/devices/28*')
# append the device file name to get the absolute path of the sensor 
devicefile = devicelist[0] + '/w1_slave'

# open the file representing the sensor.
fileobj = open(devicefile,'r')
lines = fileobj.readlines()

# print the lines read from the sensor apart from the extra \n chars
print lines[0][:-1]
print lines[1][:-1]

Save this code as ds18b20.py, and make sure it's executable with this command:

chmod +x ds18b20.py

Run this script by typing this command:


You should see the same output as before:

67 01 4b 46 7f ff 09 10 3b : crc=3b YES
67 01 4b 46 7f ff 09 10 3b t=22437


Follow me