My very own I/O expansion board arrived last week and
I’ve already
started programming the GPIO ports to make things with it.
The first thing to do is to read the manual that comes
with the board. Lots of goodies in it.
I’ve highlighted and selected the most important parts of the manual
to help you follow what to do.
First an overview of the board:
This annotated photo of a populated (fully assembled)
Gertboard shows where the functional blocksare located. Some of the blocks have
two areas marked. For example, the turquoise lines showing the Atmel ATmega chip not only surround the chip itself
and the header pins next to it (on the lower left) but also surround two header
pins near the bottom of the board, in the middle. These two pins are connected
to the Atmel chip and provide an easy way to interface the GPIO signals from
the Raspberry Pi (which are in the black box) with the Atmel chip.
There is no connection (other than power and ground)
between the different functional blocks on the Gertboard. The many headers (the
rows of pins sticking up from the board) allow you to make these connections,
using straps and jumpers.
To program the GPIO interface it’s
better to use the following diagram:
Have
a close look at the white text on the photo of the Gertboard above. These
labels provide information that is required in order to connect together the
various blocks of the Gertboard. Almost all of the components
have labels, and more importantly, the pins in the headers have labels. It isn’t
necessary to be too concerned about many of the components, such as resistors
and capacitors (labelled with Rn and Cn, where n is some number).
However the labels for headers, integrated circuits, diodes, and switches are important.
However the labels for headers, integrated circuits, diodes, and switches are important.
Diodes
are labelled Dn. The ones that
you will be interested in are D1 through D12, the LEDs (light emitting diodes).
The LEDs are near the top of the board, on the left. The labels for them are a
bit
crowded.
Each LED has a resistor next to it and thus each label Dn has an Rm next to it. The LEDs are easy to
find when you have the board powered up, as they are a row of bright red
lights. See
below,
in the section Power on the GertboardPower (page 9) for information on how to
provide power to the Gertboard.
Pushbutton
switches are labelled S1, S2, and S3 (they are located just beneath the LEDs).
Integrated
circuits (also known as ICs or chips), are marked Un. For example the I/O buffer chips
are U3, U4, and U5 (these are near the middle of the board), while the Atmel
microcontroller is U8 (this is below and to the left of U3 to U5). It is
important to understand IC pin numbering. If the chip is
orientated
so that the end with the semi-circle notch is to the left, then pin 1 is the
leftmost pin in the bottom row. Pin numbers increase in an anti-clockwise
direction from there, as shown in Figure 6.
Knowing
this means that the schematics in Appendix A can always be related to the pins
on the ICs on the Gertboard.
Headers
(the rows of pins sticking up from the board) will be a frequently used
component on the Gertboard. They are labelled Jn. For example, there is a collection
of headers along the left edge of
the
board. They allow you to access the three chips on the left side of the board:
J28 on top for the analogue to digital chip, J29 below that for the digital to
analogue chip, and J25 below that for the
Atmel
microcontroller. It is a bit difficult to see the boundary between these
headers on a fully assembled board; it’s much clearer on the blue and grey
diagram in Figure 5. On the Gertboard circuit board, each header with more than
two pins has pin 1 marked with a square around it and a dot next to it.
The dot is most useful on the assembled board, but these dots don’t appear in
the blue and grey diagram, so you can use the squares to find pin 1 there.
Not
everything labelled Jn is a collection of pins. J1, at the
bottom of the board, is the location of the
socket
that connects the Gertboard to the Raspberry Pi. J19, at the top of the board
(right of centre) is
a
block of screw terminals that allow you to easily connect wires from a power
supply and a motor.
Power
pins are marked with their voltage, e.g. 5V or 3V3 (this means 3.3V). A 5V
power supply comes onto the board from the Raspberry Pi, and if you need this
voltage it can be accessed from the lower pin (marked 5V) on header J24 on the
lower right-hand corner of the board. Ground is marked
with
GND.
The
supply voltage (the voltage that acts as high or logical 1 on the board) is
3.3V. This is generated from the 5V power pin in the J1 header by the
components in the lower right corner of the board. To send the 3.3V power
supply to the components on the Gertboard, you need to install a jumper over
the top two pins of the header J7. It is near the lower right corner of the board;
see the photo and diagram in Figure 7. The open collector and motor controllers
can handle higher voltages and have points to attach external power supplies.
GPIO Pins
The header J2,
to the right of the text ‘Raspberry Pi Gertboard’ on the board, provides access
to all the I/O pins on the GPIO header. There are 26 pins in J1 (the socket
which connects the Gertboard to the Raspberry Pi)
but only 17 pins in J2: 3 of the pins in J1 are power (3.3V and 5V) and ground,
and 6 are DNC (do not connect). The labels on these pins, GP0, GP1, GP4, GP7,
etc, may initially seem a little arbitrary, as there are some obvious gaps, and
the numbers do not correspond with the pin numbers on the GPIO header J1. These
labels are important however: they correspond with the signal names used by the
BCM2835, the processor on the Raspberry Pi (RPi).
Signal GPIOn on the BCM2835 datasheet corresponds to the pin labelled GPn on header J2. At least, this was true of the first version of the Raspberry Pi (“rev1”). Starting in September 2012, revision 2 Raspberry Pis (“rev2”) were starting to be shipped. On the rev2 RPis, some of the GPIO pins have been changed.
Signal GPIOn on the BCM2835 datasheet corresponds to the pin labelled GPn on header J2. At least, this was true of the first version of the Raspberry Pi (“rev1”). Starting in September 2012, revision 2 Raspberry Pis (“rev2”) were starting to be shipped. On the rev2 RPis, some of the GPIO pins have been changed.
The GPIO port
that used to be controlled by GPIO21 is now controlled by GPIO27, and the ports
that used to be controlled by GPIO0 and GPIO1 are now controlled by GPIO2 and
GPIO3. The rest have remained the same. The first three columns of Table 1
below summarize the current situation.
The best part of having a computer with GPIO pins is
that you can create programs to read the inputs and control the outputs
based on many different conditions, as easily as you’d
program your desktop computer. Unlike a typical microcontroller board,
which also has programmable GPIO pins, the Raspberry
Pi has a few extra inputs and outputs such as your keyboard, mouse,
and monitor, as well as the Ethernet port, which can
act as both an input and an output.
There are two GPIO systems that work in Python,
RPi.GPIO and WiringPi for Python.
It is desirable to have them in two versions, for both
RPi.GPIO and WiringPi.
Neither of these systems yet offers a fully finished
set of capabilities, but most of it is covered between them.
1) RPi.GPIO is included in Raspbian (September 2012
onwards)
If you want to run the RPi.GPIO files you don't need
to install anything unless you have an older version of Raspbian or other
distro.
The RPi.GPIO files are the ones with progname-rg.py
Run these with...
sudo python progname-rg.py
2) WiringPi for Python
If you don't have WiringPi for Python installed
already, the best way to install it
is...
sudo apt-get update
First I need to have setuptools for python installed,
the development package for python and git.
Then I get the code from git and do a setup install,
but there is one hiccup: there is a c source file that needs to be edited. But
you are a Pythonista (lol), so don’t panic, I provide a 1 line sed command to do the edit.
Altogether, here is what I needed to do to have the
wiringPi installed on my Pi:
sudo apt-get install python-setuptools python-dev
git-core
git clone
https://github.com/WiringPi/WiringPi-Python.git
cd WiringPi-Python
git submodule update --init
sed -i 's//"wiringPi.h"/g'
WiringPi/wiringPi/piNes.c
sudo python setup.py install
Either you run these commands one by one, or using
your favorite editor, you save the whole block in a file and then:
pi@raspberrypi ~ $ sh installwpi
Once that's done, you can run the WiringPi versions of
the programs with...
sudo python progname-wp.py
To make use of atod.py, dtoa.py and dad.py you MUST
have SPI enabled
sudo nano
/etc/modprobe.d/raspi-blacklist.conf
make sure there IS a # before blacklist spi-bcm2708,
so it looks like this...
#blacklist spi-bcm2708
Adding this # prevents SPI being disabled. If you had
to change it, you'll need to reboot to activate SPI.
sudo reboot
You will need to install the Python SPI wrapper:
(Python 2.7)
cd ~
git clone git://github.com/doceme/py-spidev
If you don’t have git installed, the above command will fail.
Install git with...
sudo apt-get update
sudo apt-get install git
When asked if
you want to continue, answer Y, then, after installation, try again
git clone git://github.com/doceme/py-spidev
then it should copy the files into a directory called
py-spidev. Go there next
cd py-spidev/
If you have already installed WiringPi for Python the
next step (python-dev) may not be necessary...
then type
sudo apt-get install python-dev
y (to confirm).
sudo python setup.py install
And after that you should be able to use the ADC/DAC
programs. No further reboot needed.
Now I had to install the python programs that have
already been ported from C to Python:
wget
http://raspi.tv/download/GB_Python.zip
This
should download the small file GB_Python.zip. Then type:
unzip
GB_Python.zip
cd
GB_Python
ls
Because I consider myself to be a Pythonista, I've
used only the Python libraries that I can use to interface the GPI interface.
The programs that I’m going to use in the following
posts:
dad.py - using SPI with spidev
dtoa.py - using SPI with spidev
atod.py - using SPI with spidev
motor-wp.py - using Hardware PWM and WiringPi
motor-rg.py - using sofware PWM and RPi.GPIO
leds-rg.py - leds program using RPi.GPIO
leds-wp.py - leds program
using WiringPi
ocol-rg.py - ocol program using RPi.GPIO - test
program for relay switching
ocol-wp.py - ocol program using WiringPi - test
program for relay switching
buttons-rg.py - buttons program using RPi.GPIO
butled-rg.py - butled program using RPi.GPIO
buttons-wp.py - buttons program using WiringPi
butled-wp.py - butled program using WiringPi
potmot-wp.py - potmot program using WiringPi &
spidev
Bold
in red my first GPIO program to test the I/O and Pi: leds-wp.py.
All
set to get things going.
The
schematics for the LEDS’ program:
It’s quite easy to follow. And the result on my board is:
The leds-wp.py source code:
#!/usr/bin/env python2.7
# Python 2.7 version by Alex Eames of http://RasPi.TV
# functionally equivalent to the Gertboard leds test
by
# Gert Jan van Loo & Myra VanInwegen
# Use at your own risk - I'm pretty sure the code is
harmless,
# but check it yourself.
import wiringpi
from time import sleep
def pi_rev_check(): # Function checks which Pi Board revision
we have
# make a
dictionary of known Pi board revision IDs
rev_dict={'0002':1,'0003':1,'0004':2,'0005':2,'0006':2,'000f':2}
# search the
cpuinfo file to get the board revision ID
revcheck =
open('/proc/cpuinfo')
cpuinfo =
revcheck.readlines()
revcheck.close()
# put
Revision ID line in a variable called matching
matching =
[s for s in cpuinfo if "Revision" in s]
# extract
the last four useful characters containing Rev ID
rev_num =
str(matching[-1])[-5:-1]
# look up
rev_num in our dictionary and set board_rev (-1 if not found)
board_rev =
rev_dict.get(rev_num, -1)
return
board_rev
board_revision = pi_rev_check() # check Pi Revision to
set port 21/27 correctly
if board_revision == 1:
# define
ports list Rev 1
ports = [25,
24, 23, 22, 21, 18, 17, 11, 10, 9, 8, 7]
else:
# define
ports list all others
ports = [25,
24, 23, 22, 27, 18, 17, 11, 10, 9, 8, 7]
# make a copy of ports list and then reverse it as we
need both directions
ports_rev = ports[:]
ports_rev.reverse()
wiringpi.wiringPiSetupGpio() # initialise wiringpi
for port_num in ports:
wiringpi.pinMode(port_num, 1)
# set up ports for
output
def reset_ports():
for port_num
in ports:
wiringpi.digitalWrite(port_num, 0) # switches off all LEDs
wiringpi.pinMode(port_num, 0) # and reset ports
def led_drive(reps, multiple, direction): # define function to drive
for i in
range(reps): #
repetitions, single or multiple
for
port_num in direction: #
and direction
wiringpi.digitalWrite(port_num, 1)
# switch on an led
sleep(0.11)
# wait for ~0.11 seconds
if
not multiple: # if
we're not leaving it on
wiringpi.digitalWrite(port_num, 0)
# switch it off again
# Print Wiring Instructions
print "These are the connections for the LEDs
test:"
print "jumpers in every out location (U3-out-B1,
U3-out-B2, etc)"
print "GP25 in J2 --- B1 in J3 \nGP24 in J2 ---
B2 in J3"
print "GP23 in J2 --- B3 in J3 \nGP22 in J2 ---
B4 in J3"
print "GP21 in J2 --- B5 in J3 \nGP18 in J2 ---
B6 in J3"
print "GP17 in J2 --- B7 in J3 \nGP11 in J2 ---
B8 in J3"
print "GP10 in J2 --- B9 in J3 \nGP9 in J2 ---
B10 in J3"
print "GP8 in J2 --- B11 in J3 \nGP7 in J2 ---
B12 in J3"
print "(If you don't have enough straps and
jumpers you can install"
print "just a few of them, then run again later
with the next batch.)"
raw_input("When ready hit enter.\n")
try:
# Call the
led driver function for each required pattern
led_drive(3,
0, ports)
led_drive(1,
0, ports_rev)
# run this
once, switching off each led before next one comes on, forwards
led_drive(1,
0, ports)
# run once,
switch led off before next one, reverse direction
led_drive(1, 0, ports_rev)
# (1, 1,
ports) = run once, leaving each led on, forward direction
led_drive(1,
1, ports)
led_drive(1,
0, ports)
led_drive(1,
1, ports)
led_drive(1,
0, ports)
except KeyboardInterrupt: # trap a CTRL+C keyboard interrupt
reset_ports() #
reset ports on CTRL-C exit
reset_ports() # reset ports on normal
exit
Executing the program:
And the life result after pressing ENTER above is:
Neat isn’t it? Just think of all the possibilities…
Happy hacking. You don’t learn to hack – you hack
to learn…
MAAntão
MAAntão


