Friday, May 11, 2012

GPIO LED blink from Python using Slice of Pi

You take the life of your Raspberry Pi in your hands when you start messing with the GPIO pins. The safe approach is to use a proper buffered board that protects the Pi's system on a chip, or use an Arduino as described in a previous post of mine.

However, I just couldn't resist trying out the GPIO pins directly.

IF YOU DESTROY YOUR RASPBERRY PI DON'T BLAME ME. YOU HAVE BEEN WARNED!




So, what I have done is use the Slice of Pi and attach an LED and current limiting resistor to it. Then use the RPi.GPIO library to control the LED from the Raspberry Pi.

The 'Slice' is a very low cost entirely passive breakout board for the Pi's GPIO connector.

   


It is primarily intended to house X-bee format radio modules and I hope to try these out in a later post, but for now I was just using it as a convenient means of connecting to the GPIO pins.

If you prefer, you could just connect header sockets to the appropriate pins on the Pi board itself, but this avoids the risk of accidental shorting of pins.

My first step was to assemble the 'Slice', which comes as a kit that you have to solder together yourself. Its all nice big pads and easy to solder.

I also added a 3 pin header socket for the three power connections 5V, 3.3V and GND. IMHO it would be nice if the slice came with this. It does however come with a header kit in case your Pi does not have one ready soldered. My Pi came with one of these already soldered in, so I didn't need the one that came with the Slice.


The low profile header sockets are for radio modules. Definitely something to look forward to there!

The Pi's GPIO pins are 3.3V and low current. Low An LED will glow with just 1 or 2 mA flowing through it, which shouldn't do the Pi any harm. By using a 1kΩ resistor, if the LED forward voltage is 2V, and the supply voltage is 3.3V, that leaves 1.3V across the resistor, using Ohms Law, I = V / R so I = 1.3mA.

I just twisted one leg of the resistor around the negative lead of the LED. The negative lead is the shorter lead.



Put the positive lead of the LED into the 3.3V power socket on the slice and the free end of the resistor into the socket on the Slice labelled GP0.

You can now fit the slice onto your Pi.



Now its time to sort out the software side of things.

Step 1. If you are not reading this page on your Pi, then switch now, so you can copy and paste.

Step 2. Browse to here and download RPi.GPIO-0.1.0.tar.gz and save it somewhere convenient. I saved it to the 'other' folder on the Desktop.

Step 3. This is a gziped tar file. Which needs unzipping and untaring. To unzip it open a Terminal, which you will find from the 'start menu' under 'accessories'. Now paste the following commands into it.
cd /home/pi/Desktop/other
gunzip FPi.GPIO-0.1.0.tar.gz
tar - xvf FPi.GPIO-0.1.0.tar

Step 4. Install GPIO, by typing these lines in your terminal window:
cd FPi.GPIO-0.1.0
sudo python setup.py install



Step 5. Run Python 2. You will find this from the menu under Programming - Use Python 2 not 3.

We now need to enter some commands:

>>> import RPi.GPIO as GPIO
>>> GPIO.setup(11, GPIO.OUT)

After we enter this second command, the LED should light. That is because the pin will have been set to an output and initially be low. A low pin will light the LED, a high pin and it will turn off.

>>> GPIO.output(11, True)

This should have turned the LED back off.

Let's now write a little program to make the LED blink.

>>> import time
>>> while True :
>>>    GPIO.output(11, True)
>>>    time.sleep(1)
>>>    GPIO.output(11, False)

>>>    time.sleep(1)

Press the enter key twice. When you have had enough of the LED blinking press the key combination ctrl-C.

Here is a short video of this.



You may have noticed that the LED is connected to pin GPIO0 and not 11 as we are using in Python. The library uses different pin numbers to the names on the Pi. I'm not sure why. But anyway, I mapped a few of them as shown below.

library name     Pi name
11               0
12               1
13               2

After that, the mapping changes.

I wanted to know how fast the GPIO library was, so I took off the LED and attached my oscilloscope to the output and then ran the following test program.


>>> state = True
>>> while True :
        GPIO.output(11, state)
        state = not state

The 'scope measured the frequency as 800Hz. Not very fast, but fast enough for PWM and servo control.


About the Author
These are my books. Click on the image below to find out more about them.





                                                                                                                           

11 comments:

Ben Croston said...

The python package uses board pin numbers because it can drive 17 of the pins on the board. The diagram that labels the pins only goes up to GPIO 7. You can also drive other pins such as the SPI and I2C pins as GPIO pins so it didn't make sense to use the GPIO 0-7 numbering scheme. That is why I used board pin numbers when I wrote the library.

Simon Monk said...

Hi Ben, thanks for that, and thanks for a very useful library.

I couldn't find a list of the pin mappings. Is there one somewhere?

Ben Croston said...

Something like this --> http://elinux.org/RPi_Low-level_peripherals ?

scottbouch said...

Can't wait to get mine and play with the I/O! End of June is my dly date!

Simon Monk said...

I should pont out - there is no video or USB connectors plugged into the Pi, because it is running a VNC server. The monitor is my Mac monitor mirroring whats on the Pi. So just Ethernet and power connections.

Sam Worm said...

I was considering using the GPIO to drive a very simple LED Matrix, purely as an exercise rather than because it'll be a particularly useful display.

With only eight outputs some kind of multiplexed display would be needed, and the LED rows pulsed fast enough to fool the eye. I have no idea if 800Hz would be fast enough for that, but it seems likely. Obviously something like a Arduino would be a more orthodox way to drive a display like that, but where would the fun be in doing the orthodox route?

Now.. if only my Pi would ship... :)

J.P. Godfrey said...

This looks great and will be my first project. I already have my Pi & Slice so just need to get some leds now.

I didn't have a spare header to put on the 5, 3.3 & 0 V but http://www.faludi.com/images/blog/XBee_Direct_Wiring-thumb.jpg gives the pinout of the XBee radio module. We should be able to connect to the 3V3 and GND from the top and bottom of the right hand XBee header. XBee doesn't use 5V so it's not available on the header.

J.P. Godfrey said...

This looks great and will be my first project. I already have my Pi & Slice so just need to get some leds now.

I didn't have a spare header to put on the 5, 3.3 & 0 V but http://www.faludi.com/images/blog/XBee_Direct_Wiring-thumb.jpg gives the pinout of the XBee radio module. We should be able to connect to the 3V3 and GND from the top and bottom of the right hand XBee header. XBee doesn't use 5V so it's not available on the header.

jorygen said...

Testing this with RPi.GPIO-0.3.1a I find, that
sudo apt-get install python-dev
is needed before
sudo python setup.py install
would succeed. It's written in C now, and needs Python.h to compile.

massimo negro said...

Hi all, I would like to ask a little help:
I have this script :

import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()
status = (1)
GPIO.setup(29, GPIO.OUT)
GPIO.setup(28, GPIO.IN)
GPIO.setup(30, GPIO.IN)
while time:
if GPIO.input(28) == False:
if status == 0:
GPIO.output(29, False)
print "OFF"
status = 1
time.sleep(0.3)
continue

if status == 1:
print "ON"
GPIO.output(29, True)
status = 0
time.sleep(0.3)
continue


and I would add a second switch (30) :
if this low is disabled all the rest

massimo negro said...

Hi all, I would like to ask a little help:
I have this script :

import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()
status = (1)
GPIO.setup(29, GPIO.OUT)
GPIO.setup(28, GPIO.IN)
GPIO.setup(30, GPIO.IN)
while time:
if GPIO.input(28) == False:
if status == 0:
GPIO.output(29, False)
print "OFF"
status = 1
time.sleep(0.3)
continue

if status == 1:
print "ON"
GPIO.output(29, True)
status = 0
time.sleep(0.3)
continue


and I would add a second switch (30) :
if this low is disabled all the rest