sábado, março 16, 2013

Setting-up the Gertboard I/O expansion board and the Raspberry Pi

My very own I/O expansion board arrived last week and Ive 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.

Ive 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.
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.

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.
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

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 dont 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 dont 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

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 Im 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:

Its 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

    # search the cpuinfo file to get the board revision ID
    revcheck = open('/proc/cpuinfo')
    cpuinfo = revcheck.readlines()

    # 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]
    # 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[:]

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")

    # 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 isnt it? Just think of all the possibilities

Happy hacking. You don’t learn to hack – you hack to learn…


5 comentários:

Anónimo disse...

Onde compraste e quanto custou?

Tiveste de fazer algum coisa em termos de HW, para além de ligares os cabos?


Manuel Antão disse...

eBay. Cerca de 40 e tal euros.

Em termos de HW é apenas a colocação de cabos na Pi e na Gertboard. Depois é Python. Existem uns periféricos muito giros para a gertboard... Domótica, energia solar, etc.

Anónimo disse...

Der RasPiComm ist eine andere Erweiterungsplatine für den Pi, die vor allem für die Steuerung von Schrittmotoren verwendet werden soll.

Besser als die Gertboardplatine oder nicht?


Manuel Antão disse...

Ich glaube nicht. Es gibt viel Information über die Pi-Platine im Internet. über die RaspiCom-platine ich weiss es nicht.

Anónimo disse...

Manuel, tens links que recomendes para quem começa com o Python agora?

Concordo contigo que fazer programação de baixo nível nesta altura do campeonato em C já não compensa...

Vais passar a ponte 25 Abril no Domingo...?