Pages Menu
TwitterRssFacebook
Categories Menu

Posted by on Jul 25, 2014 in Featured, Raspberry Pi, Single Board Computers | 10 comments

Using the Raspberry Pi GPIO with Python

Using the Raspberry Pi GPIO with Python

So you got your Raspberry Pi, installed an OS and using it just like your computer. Great! Now what? You didn’t buy a Raspberry Pi just to replace your computer, did you? Well, Raspberry Pi can do a lot more… much more than your computer can do!

Raspberry Pi Model B GPIO

Raspberry Pi Model A/B GPIO

Did you notice that there are lots of tiny little pins on one corner of your RPi? These are called “General Purpose Input Output” pins (or GPIO pins). These pins allow your RPi to be connected to the external world. Raspberry Pi Models A and B have 26 pins (17 GPIO) whereas the new model B+ comes with 40 pins (26 GPIO). The model B+ is pin compatible with models A and B.

The easiest way to control these pins is to use the RPi.GPIO Python library. The library comes pre-installed with the latest Raspbian OS. In any case, we’ll learn how to install the library, just in case you find it missing. After this post, you should be able to perform simple I/O operations using your RPi’s GPIO pins.

Contents

Raspberry Pi Pin Configuration

As mentioned earlier, RPi models A/B and B+ are pin compatible. The following image (source raspberrypi-spy.co.uk) shows the pin layout of models A/B (rev 2) and B+.

RPi Pin Layout for Model B Rev 2 and Model B+ (Image source raspberrypi-spy.co.uk). Compare this image to the top right corner of your Raspberry Pi.

RPi Pin Layout for Model B Rev 2 and Model B+ (Image source raspberrypi-spy.co.uk)

Model B had two revisions in which the pin configuration changed a little. The RPi model B consists of pins 1 through 26, of which only 17 of them can be used as GPIO. The remaining pins consist of power supply (5v and 3.3v), ground and serial pins. The RPi model B+ consists of all the pins shown above, out of which 26 can be used as GPIO.

The labels mentioned on the left and right of the pins refer to the pin numbers on the BCM2835 CPU. For instance, pin GPIO16 of BCM2835 CPU is connected to pin 36 of RPi B+. Makes sense? What difference does it make to you – we’ll see in a while! :)

The RPi.GPIO Python Library

Now let’s get to the point. In order to control the GPIO pins of the RPi, we’ll use the RPi.GPIO Python library. Starting version 0.5.6, the library has support for RPi model B+ as well. While the library is the best way to access and control the GPIO pins, it still lacks support for SPI, I2C, hardware PWM and serial functionality, which are planned to be added (this is with respect to version 0.5.6. In future, this might change).

This is a really simple library which allows you to read to and write from any GPIO pin by various means (like polling, triggers, events, etc). In this post, we’ll discuss the polling method (don’t worry about the name, we’ll deal with it later. The concept is rather simple), whereas I’ll deal with the other methods in my next post.

Installation

Method 1 – Install from Repositories

The RPi.GPIO library comes pre-installed with the latest version of Raspbian. In case it doesn’t, all you need to do is to install the latest version from the repositories by running the following in the terminal (holds good for Raspbian only)–

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install python-rpi.gpio python3-rpi.gpio

That’s all you need to do! Simple, eh?! :)

Method 2 – Build from Source

If you want to build from the source, first download the library from here. Once downloaded, you need to extract it. Open up the terminal, browse to the directory where you downloaded the library and type in the following to extract (replace the name of the file with the one that you downloaded)–

tar zxvf RPi.GPIO-0.5.6.tar.gz

Then enter into the extracted folder.

cd RPi.GPIO-0.5.6

Before we proceed towards installation, make sure Python is installed in your system (which should be since it comes pre-installed in all OS images). In case there’s no Python installed, type the following to install–

sudo apt-get install python-dev python3-dev

And then, install the package by typing–

sudo python setup.py install
##or
sudo python3 setup.py install

That should be it! You’re all set to blink some LEDs! :)

Hello World with Raspberry Pi – LED Blinky

A “Hello world” program is a typically one of the simplest programs that one can possibly write to illustrate the basic functionality of any device. In case of Raspberry Pi, it is, like any other embedded system, blinking an LED. This not only gives beginners an idea of how things generally work, but also makes sure that all the tools and devices are properly set up and working properly.

In this post, we’ll program in Python. It can be programmed in a ton other languages as well, but we’ll stick to Python for now because of its simplicity. I’ll dedicate another post on how to do the same using C, and may be another post on how to write your own Linux kernel modules to control the GPIO. :)

A little background

Detailed Diagram of an LED

Detailed Diagram of an LED

For those who are not familiar with circuits, this might seem a challenging task. So here’s a little background on the concept of blinking LEDs. If you are not already familiar, LEDs are little devices that glow and emit light of some color (red, blue, green, yellow, white, etc) upon providing a positive voltage across its pins (forward bias). If you reverse the polarity, the LED does not glow. In the adjoining figure of an LED, you must make sure that the voltage drop across the LED (from +ve to -ve pin) is positive to make it glow.

If you connect a 5 volts supply across an LED directly, it’ll simply blow up since it exceeds the voltage rating of the LED. To prevent that, we usually connect a current limiting resistor in series with the LED to divide the voltage drop, so that your LED is safe and keeps on glowing. Usually any resistor having value in between 100 ohms and 1kohms will work good for this. But don’t connect a resistor having too high resistance. This will not leave enough voltage across the LED to make it glow.

The GPIO pins of your RPi are capable of generating these different voltage levels. This is why you program the RPi – to generate a particular voltage level on a particular pin.

Alright, now let’s get to the circuit diagram.

Circuit

Disclaimer: We ABSOLUTELY DO NOT take any responsibility of you messing things up. The circuit shown below is tested and works just fine, however if you make wrong connections and/or short the board and damage your Raspberry Pi, it’s all on you. In short, PROCEED AT YOUR OWN RISK. Also, beware of ELECTROSTATIC DISCHARGE. The GPIO pins of your Raspberry Pi are connected directly to the BCM2835 CPU’s pins. There is no protection. So don’t mess around. If you don’t feel confident, try using something like a Gertboard as an intermediate interface.

We’ll be using a solderless breadboard to make the circuit. If you don’t know how to make circuits on a breadboard, try watching this video first. Things that we’ll need are–

  • Raspberry Pi and accessories
  • F/M jumper wires (a combination of F/F and M/M will also work)
  • An LED (3mm or 5mm)
  • Two 330 ohms resistor
  • One push button

Check out the following circuit. We’ll implement the region marked in red for now, which is the LED blinky. Notice that pin 7 of RPi is connected to the positive end of the circuit and pin 6 (which is ground) is connected to the negative end of the circuit.

This means that when pin 7 is driven high, a high voltage level (usually 5v) is generated at pin 7, which glows the LED. And when pin 7 is driven low, a low voltage level (usually 0v) is generated at pin 7, which turns off the LED.

Cool! Once you’re done making the circuit in the red region, proceed to the next section where we learn how to program your RPi using the RPi.GPIO library.

Raspberry Pi GPIO Example Circuit. The RED region is the LED blinky circuit.

Raspberry Pi GPIO Example Circuit. The RED region is the LED blinky circuit.

Here are some pictures of how the circuit should look like on a breadboard–

LED Blinky Breadboard Circuit

LED Blinky Breadboard Circuit

Raspberry Pi LED Blinky

Raspberry Pi LED Blinky

Using RPi.GPIO Library

Importing Module

The RPi.GPIO package allows us to control the GPIO pins by means of classes. We start by importing the modules by typing–

import RPi.GPIO as GPIO

This allows us to refer the module by simply mentioning GPIO instead of its full name RPi.GPIO.

Specify Mode of Operation

The next step is to specify the mode in which we’ll be using the module. Remember that we mentioned that RPi (BOARD) and the CPU (BCM) have different pin numbers? This is where this matters. You need to choose between the two systems. You can do so by typing–

GPIO.setmode(GPIO.BOARD)  # for RPi numbering
  # or
GPIO.setmode(GPIO.BCM)    # for CPU numbering

Set up a Channel

Next we need to set up the desired channel as either input or output. This can be done by typing–

GPIO.setup(channel, GPIO.IN)   # input channel
  # or
GPIO.setup(channel, GPIO.OUT)  # output channel

For instance, for the LED blinky, we connected pin 7 on the board to the LED. This means that we must configure that pin as an output channel. Also, recall that that pin 7 on board is mapped to GPIO4 of the CPU. So this is how you do–

GPIO.setup(7, GPIO.OUT)  # if BOARD numbering system is used
  # or
GPIO.setup(4, GPIO.OUT)  # if BCM numbering system is used

It is recommended that you follow the BOARD numbering system since it is easier to follow. In the end it doesn’t matter which one you follow, just choose one and stick to it.

Drive a Channel

Next step is to drive the channel high or low. This can be done by typing–

GPIO.output(channel, state)

For instance, to drive pin 7 high, we type any of the following–

GPIO.output(7, True)
  # or
GPIO.output(7, GPIO.HIGH)
  # or
GPIO.output(7, 1)

To drive the same pin 7 low, we type–

GPIO.output(7, False)
  # or
GPIO.output(7, GPIO.LOW)
  # or
GPIO.output(7, 0)

Read a Channel

In order to read the value of any GPIO pin, simply type–

GPIO.input(channel)

We’ll learn how to use in later in this tutorial. We don’t need it for LED blinky since all our pins are output pins.

Cleanup

And once we are done with all the GPIO operations, we need to clean up and free any resources that we might have used. This is not required but is considered a good programming practice. All you need to do is to type–

GPIO.cleanup()

Timing Considerations

Another thing that you need to know is the concept of delay. The thing is that when the LED blinks, you actually want to see it blink. It shouldn’t blink so fast that you always see it on, and it shouldn’t blink so slow that you always see it off/on. Also, you need to control the rate at which the LED blinks (say you want the LED to blink every quarter of a second). So here’s the flow how it goes–

  1. Turn LED on.
  2. Wait for a while.
  3. Turn LED off.
  4. Wait for a while.
  5. Repeat steps 1-4.

In order to achieve steps 2 and 4 mentioned above, Python has a time library which has a function called sleep() which does exactly the same thing! Here’s how we use it–

import time       # import 'time' library
time.sleep(n)     # sleep for 'n' seconds

I think that’s all you need to know to start programming. I assume that you’re familiar with some basic Python procedures. If not, please learn them first and then come back!

Let’s Code!

Alright fellas, time to get our hands dirty and start programming! We are going to use Python 2.7.3 to write the code. To write the code, open up your favorite text editor (like gedit, Geany, etc). Usually for Python, we prefer to use IDLE. So go to the terminal and type–

sudo idle

We need to run IDLE as superuser since RPi.GPIO library needs those privileges to control the hardware pins. Do not open IDLE 3, we’re not using Python 3.

Next, type in the following code–

import RPi.GPIO as GPIO         ## Import GPIO Library
import time                     ## Import 'time' library (for 'sleep')

pin = 7                         ## We're working with pin 7
GPIO.setmode(GPIO.BOARD)        ## Use BOARD pin numbering
GPIO.setup(pin, GPIO.OUT)       ## Set pin 7 to OUTPUT

GPIO.output(pin, GPIO.HIGH)     ## Turn on GPIO pin (HIGH)
time.sleep(1)                   ## Wait 1 second
GPIO.output(pin, GPIO.LOW)      ## Turn off GPIO pin (LOW)
time.sleep(1)                   ## Wait 1 second

GPIO.cleanup()                  ## Cleanup

Once you are done, save the file and give it any name you wish (like blinky.py). Once you are done, run it by hitting F5. If you have typed anything wrong, you will see the error box popped up. If it says some kind of syntax error, double check that you are running IDLE and not IDLE 3. If it says insufficient permission, make sure that you are running IDLE as a superuser (by using sudo).

You can also run it from the terminal by typing the following from the working directory–

sudo python blinky.py

What did you see? Did your LED blink? If everything went okay, your LED would have blinked, but just once. That’s because we haven’t implemented the loop yet! Let’s modify the code as–

import RPi.GPIO as GPIO         ## Import GPIO Library
import time                     ## Import 'time' library (for 'sleep')

pin = 7                         ## We're working with pin 7
GPIO.setmode(GPIO.BOARD)        ## Use BOARD pin numbering
GPIO.setup(pin, GPIO.OUT)       ## Set pin 7 to OUTPUT

for i in range (0, 20):         ## Repeat 20 times
    GPIO.output(pin, GPIO.HIGH) ## Turn on GPIO pin (HIGH)
    time.sleep(1)               ## Wait 1 second
    GPIO.output(pin, GPIO.LOW)  ## Turn off GPIO pin (LOW)
    time.sleep(1)               ## Wait 1 second

GPIO.cleanup()                  ## Cleanup

Make sure you indent your code properly using TAB rather than spaces. Python depends heavily upon proper indentation of code. Save it and run it. What do you see? Did the LED blink 20 times?! Woah, that’s a big deal! Good job! :)

Now try playing around! Change the number of times the loop has to repeat, change the delay, etc.

But why blink it only 20 times? What if you want to blink it forever?! For that, you would need to replace the for statement with the following–

while True:
    # loop code goes here
    # This loop iterates infinitely
    # since the condition of the
    # while loop is ALWAYS True

And there you go! You’re all set! I prepared a video of my LED blinky that can be found below. I used the following code. The code takes in user inputs and implements the blinky as a function.

# LED Blinky code for Raspberry Pi
# Written in Python 2.7.3
import RPi.GPIO as GPIO     ## Import GPIO Library
import time                 ## Import 'time' library (for 'sleep')

## Define function named ledBlink()
def ledBlink(pin, numTimes, delay):
    for i in range(0,numTimes):         ## Run loop numTimes
        print "Iteration " + str(i+1)   ## Print current loop
        GPIO.output(pin, GPIO.HIGH)     ## Turn on GPIO pin (HIGH)
        time.sleep(delay)               ## Wait
        GPIO.output(pin, GPIO.LOW)      ## Turn off GPIO pin (LOW)
        time.sleep(delay)               ## Wait
    print "Done"            ## When loop is complete, print "Done"

## Prompt user for input
pin = raw_input("Enter GPIO pin to blink: ");
nTimes = raw_input("Enter the number of times to blink: ")
delay = raw_input("Enter the duration of each blink in seconds: ")

GPIO.setmode(GPIO.BOARD)        ## Use BOARD pin numbering
GPIO.setup(int(pin), GPIO.OUT)  ## Set GPIO pin to OUTPUT

## Call ledBlink() function for GPIO pin
ledBlink(int(pin), int(nTimes),float(delay))

## Finally, clean up!
GPIO.cleanup()

Video

Errata: There’s an error in the video where I mention that pin 1 of Raspberry Pi gives 5v supply. That’s not true, it should be 3.3v. I’m sorry for being lazy and not re-recording the video! :)

A Level-up: Reading Inputs

So far we have been using a pin in output mode. Let’s explore how to use a pin in input mode. Let’s look at the same circuit diagram mentioned earlier. I’ll re-include it here so that you don’t have to scroll all the way up again and again. It sucks, I know!

Raspberry Pi GPIO Example Circuit. The RED region is the LED blinky circuit.

Raspberry Pi GPIO Example Circuit. The RED region is the LED blinky circuit.

So here our aim is to light up the LED only and only when the switch SW1 is pressed. If you’re familiar with electrical connections, you’ll notice that the switch SW1 is connected in active low mode. This means that when the switch SW1 is pressed, pin 13 receives a low voltage (ground in this case) and when the switch is released, pin 13 receives a high signal (something less than 5v in this case due to the pull-up resistor).

Algorithm

Let’s develop an algorithm for this problem statement. We need to glow the LED only when the switch is pressed. So the algorithm goes something like this–

  1. Read the state of pin 13.
  2. If the state is high, drive pin 7 low, or else drive it high (remember, active low).
  3. Go back to step 1.

Let’s Code!

Let’s code it now! Recall that we use GPIO.input() to take input from a channel.

import RPi.GPIO as GPIO         ## Import GPIO Library
import time                     ## Import 'time' library (for 'sleep')

outPin = 7                      ## LED connected to pin 7
inPin = 13                      ## Switch connected to pin 13
GPIO.setmode(GPIO.BOARD)        ## Use BOARD pin numbering
GPIO.setup(outPin, GPIO.OUT)    ## Set pin 7 to OUTPUT
GPIO.setup(inPin, GPIO.IN)      ## Set pin 13 to INPUT

while True:                     ## Do this forever
    value = GPIO.input(inPin)   ## Read input from switch
    if value:                   ## If switch is released
        GPIO.output(outPin, 0)  ## Turn off LED
    else:                       ## Else switch is pressed
        GPIO.output(outPin, 1)  ## Turn on LED

GPIO.cleanup()                  ## Cleanup

The thing to note is that the result of GPIO.input() is a boolean value. If the input is high, it returns True and if the input is low, it returns False. There is no middle. In case you provide the pin with some random analog value, then the hardware itself thresholds the signal to give a high/low value. But let’s not worry about it now, it’s outside the scope of this post.

You could have replaced the if condition with the following. It would be the same–

    if value == True:  ## if value == GPIO.HIGH also works
        # do something
    else:
        # do something else

Another possible and efficient method to achieve the same would be to replace the entire while loop with the following. I won’t explain you how, figure it out on your own! :)

while True:
    GPIO.output(outPin, not GPIO.input(inPin))

Test: Design a Counter

Time to check what you have learned till now! Let’s have a test!

Problem Statement: Using the same hardware connections as above, write a code in Python which counts the number of times you have pressed the switch and display the value on the screen. At the same time, toggle the LED’s glowing pattern from before i.e. when switch is pressed, the LED is turned off and when the switch is released, turn on the LED.

Go ahead! You know everything that you have to know. Program it! The solution is down below just in case you are lost, but give your best shot before viewing the answer.

Hint: Use some delay for switch debouncing so that false readings to do not count.

import RPi.GPIO as GPIO         ## Import GPIO Library
import time                     ## Import 'time' library (for 'sleep')

outPin = 7                      ## LED connected to pin 7
inPin = 13                      ## Switch connected to pin 13
count = 0                       ## Initialize counter to 0
GPIO.setmode(GPIO.BOARD)        ## Use BOARD pin numbering
GPIO.setup(outPin, GPIO.OUT)    ## Set pin 7 to OUTPUT
GPIO.setup(inPin, GPIO.IN)      ## Set pin 13 to INPUT

while True:                     ## Do this forever
    value = GPIO.input(inPin)   ## Read input from switch
    if value:                   ## If switch is released
        GPIO.output(outPin, 1)  ## Turn on LED
    else:                       ## Else switch is pressed
        GPIO.output(outPin, 0)  ## Turn off LED
        count = count + 1       ## Increment counter
        print "count=" +str(count) ## Display counter on screen
    time.sleep(0.2)             ## Wait for things to settle down - debouncing

GPIO.cleanup()                  ## Cleanup

So, did you pass the test? I hope so! :)

The delay technique used here is one of the simplest methods for debouncing. Debouncing is necessary to disregard false readings. In the above code we have assumed that there needs to be at least 200 ms time interval between two legitimate button presses. This is good enough to detect any human press and disregard any false readings.

But there’s a loophole. What if the user presses and holds the switch for longer than 200 ms? With the current implementation, the counter will read them as two separate inputs which is not the case! We’ll deal with such issues in our next post, which will be about triggers and events.

What now?

Go ahead, hook up more LEDs, more switches and create something really new! Try creating some cool LED patterns as well! Go wherever imagination takes you!

Summary

In this post, we learned about the GPIO pins of RPi and how they are mapped to the underneath CPU. We explored the RPi.GPIO Python library, made physical circuits and connected them to the RPi’s GPIO pins. We wrote a simple Python code to blink an LED and also take input a the switch. Towards the end we discussed about debouncing and an example demonstrating a counter.

That’s it for now. Stay tuned for more!

References

Written by Mayank Prasad (aka Max)
support@maxEmbedded.com

Max

Max is the founder and admin of maxEmbedded. He describes himself as an 'embedded electronics freak' and an Apple/Linux fan. He likes to experiment, learn and share new things in this field. Furthermore, he likes to write stuffs on his website for techie newbies and loves to teach others. In his spare time, you will find him with volunteering somewhere!

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle Plus

10 Comments

  1. Max you always Rock..That’s a great tutorial in simple language.

    • Thanks Saravanan! :)

  2. thanks sir this is a awesome tutorial. going to market for purchasing a raspberry pi and waiting for next tutorials………

  3. Hi max,

    It ask’s for which pin, what time ? etc ? is it built it in functionality of the GPIO Library ?

    • No, that’s in the Python code that you wrote (the one given above). Try following the tutorial from the beginning to learn what’s covered in the GPIO library. Taking in user input is a functionality of Python and not the GPIO library.

  4. Dear Sir,

    Thanks for the GPIO raspberry Pi tutorial, do you know what IDE I can use to port Rapsberry Pi GPIO?

    Kind Regards

    Uche Nwoko
    Aberdeen, Scotland.

    • You can use IDLE, which comes pre-installed with the Raspbian distribution.

  5. Dear Sir,

    I am working on Raspberry pi(ARM11 processor SOC) and I would
    like to control the electrical devices like fan,bulb and Ac.

    What i have done is I have connected the rf transmitter pin to
    the raspberry pi and the rf receiver of(data) to another pin in
    raspberry pi(ie i am using single raspberry pi).Now i can control
    the load that is connected to the rf receiver side and when i click
    a button on rf transmitter i was able to control the light bulb(ac)
    on and off. Now, my question is whether I can control the light bulb
    from rf receiver side without connecting to the raspberry pi pin.(i.e, can
    I control the rf receiver without giving the connection to the microcontroller
    or raspberry pi.).Is itpossible? If yes,give me a solution.

    Note: I have an encoder and decoder ciruit inbuilt with rf tx, and rx module.

    • So let me be clear in what you are trying to say. This is your flow now, isn’t it?
      RPi —> RF Tx —> RF Rx —> Same RPi —> Bulb
      If yes, then it might be difficult to skip the RPi in the receiver’s end. This is because the Bulb doesn’t understand what RF Rx receives. The RPi understands it and then controls the bulb.

Post a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>