Raspberry Pi Workshop - Lab Materials
Raspberry Pi Workshop - Lab Materials
Raspberry Pi Workshop - Lab Materials
1
Dario Schor, Troy Denton
Contents
Apparatus 3
Exercise 8 - SPI 12
SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Circuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Web Interface for ADC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Page 2 of 18
Dario Schor, Troy Denton
Apparatus
The following components are required for this lab
• 1x Raspberry Pi
• 1x SD Card
• 1x DVI Monitor
• 1x USB Mouse
• 1x USB Keyboard
• 1x MCP3001 IC
• 3x LEDs
• 1x pushbutton switch
Page 3 of 18
Dario Schor, Troy Denton
3. Install Win32DiskImager
5. Insert the SD card into your SD card reader, if you have not done so
7. Select the SD card reader as the destination device - make sure you don’t select your hard drive!
For Linux, Mac OSX, and Unix-variants, the procedure is slightly different:
4. use dmesg | tail to determine the path to your SD card ( should be /dev/sdX )
5. use sudo dd bs=4M if=/path/to/rpi.img of=/dev/(SD Card) to flash the image - this will take
a while!
Finally, plug your Raspberry Pi into a power supply (micro-B USB cable), keyboard, and monitor, and you
should see the Raspberry Pi logo and some scrolling text on the screen. If this did not work, please consult
one of the volunteers.
In Linux, Unix, and their variants, everything in the Operating System is a file - everything from programs,
to input and output devices, are represented as files in a directory-tree structure. If you have a mouse handy,
give Listing 2 a try:
When using a graphical desktop, the Operating System reads the same file to know when the mouse is
moving.
Listing 3 shows some linux commands for basic input and output.
#if you want to read the file, you can use the cat command
cat /home/pi/lol.txt
• /
• /etc
• /usr/bin
Page 5 of 18
Dario Schor, Troy Denton Exercise 2 - Shell Basics
• C/C++ libraries
• Python libraries
• Filesystem access
Each method has it’s merits - in this lab we will be primarily using the Filesystem methodology due to it’s
ease of use.
Under the filesystem methodology, if we wish to use a GPIO pin, we must first export it. This tells the
Operating System to create the necessary files to control the GPIO pin. Listing 4 shows how this is done,
using GPIO pin 4 as an example.
A pin need only be exported once to use it. Once exported, GPIO pins can be set up as either an input
or an output, but not both. Their configuration as input or output can however change at any time. To
configure a particular pin for output, we can use the echo command to write to a file - Listing 5 configures
pin 4 as an output:
Once a pin is configured as an output, you can assign it a logic value of 0 or 1 - this will determine the output
voltage for that pin (0 or 3.3VDC, respectively). Listing 6 shows examples of setting the output value on
pin 4:
Hook up an LED ala Figure 1 and observe the GPIO pin toggling as you echo 1 and 0 to the value file:
Once the pin is set as an input, you can read the value of the pin by simply reading the “value” file, as
shown in Listing 8:
Use the circuit diagrammed in 2 to toggle the value of GPIO pin 4, combined with the code in Listing 8 to
observe the GPIO working.
echo "testing.."
sleep 2
echo "some more output..."
sleep 2
echo "writing this to a file..." > /home/pi/test.txt
sleep 2
# variables in bash script files are created, assigned, and used as so:
TESTVARIABLE=15
echo "the contents of TESTVARIABLE: $TESTVARIABLE"
sleep 2
# we can use the ! operator instead the if[] statement to make it test
# the opposite - in this case, it’s chekcing if /home/pi/test does
# not exist
i f [ ! -e /home/pi/test.txt]; then
echo "/home/pi/text.txt does not exist!"
fi
sleep 2
done
To create a shell script, simply open a new file and start typing! To edit and create a new file, the nano pro-
gram is recommended. cd to your home directory (/home/pi) and run nano test.sh to start editing a new
file named test.sh, stored at /home/pi/test.sh. Enter some of the commands from 9 to start experimenting.
To run your script, you will first have to add execution permission to your script. Execute chmod +x /
home/pi/test.sh to tell the Operating System that this file is meant to be run as a program. Then, enter
/home/pi/test.sh on the command line, which will actually run your program. Note that you only need
to add the execution permission once.
Now that we have some shell scripting experience under our belts, lets start building some tools to use in
later examples:
1. Hook up the circuit in Figure 1. Create the script /opt/workshop/gpio out.sh. Have it accept two
arguments on the command line: the first argument is the GPIO pin to modify, and the second
argument is the value to set it to. For example: sudo /opt/workshop/gpio_out.sh 4 1 will set
GPIO pin 4 to value 1. Hint: the first argument is stored in the variable $1, and the second argument
is stored in $2.
2. Hook up the circuit in Figure 2. Create the script /opt/workshop/gpio in.sh. Have it accept one
argument on the command line - the GPIO pin to read. For example: /opt/workshop/gpio_in.sh 4
3. Modify both scripts so that they export the GPIO pin before doing any reading or writing, but only
if it has not been exported yet! Hint: If the pin has already been exported, the directory
/sys/class/gpio/gpioN will already exist, where N is the pin number.
We want apache to be able to run the scripts we created - /opt/workshop/gpio in.sh and /opt/workshop/g-
pio out.sh - so we need to give the user that runs apache the proper permissions to do so. This is accomplished
by running the command sudo visudo and adding the following line to the bottom of the file that comes up
for editing:
Note: hit Ctrl+O to save the file (output file), and Ctrl+x to exit.
#the ’exec’ command allows php to run a shell command, and return the result
echo "The current date is: ".exec(date)."\r\n";
?>
function buttonClick()
{
$.post("ex_7.php",{
NAME: "TROY"
}).done(function(result){
});
}
</script>
</head>
<body>
<button onClick=buttonClick()>Click me!</button>
</body>
</html>
When the user clicks the button labelled “Click me!”, the button’s onClick function gets executed. This
function uses the jQuery library to perform a POST to test.php, and alerts the user with the response in
a pop-up box. You may find the javascript syntax odd if you’ve never encountered it - we will not have
you perform javascript development in this lab, as such no explanation will be listed here. The instructors
will gladly answer any questions you have during or after the laboratory session. Note: jQuery is a popular
javascript library that provides easy-to-use AJAX functions, among many, many more things!
cd /var/www
sudo wget http://troydenton.ca/rpi/ex7.tar.gz
sudo tar xvzf ex7.tar.gz
sudo chown www-data:www-data *
Use the ifconfig eth0 command to determine your Raspberry Pi’s IP address, and navigate to
http://IP address/ex 7-1.html in a web browser.
2. Write a PHP script - /var/www/gpio out.php - that accepts the POST variables STATE and PIN, and
sets GPIO Pin #PIN to state STATE, where STATE is ‘1’ or ‘0’. Test this using the ‘GPIO Output’
tab of http://IP address/index.php
3. Write a PHP script - /var/www/gpio in.php - that accepts the POST variable PIN, and returns the
logic value of pin #PIN. Test this using the ‘GPIO Input’ tab of http://IP address/index.php
Hint: to use the exec() call with our /opt/workshop scripts, we will need to use sudo. The -t
option can be used to bypass the password prompt, if configured properly via visudo.
Exercise 8 - SPI
In order to read analog ports using the Raspberry Pi, one needs additional hardware to convert the analog
readings and then transmit that to the processor. Microchip’s MCP3001 is a small analog-to-digital converter
(ADC) integrated chip with 10-bit resolution that can convert a value and transmit it to a processor using
the Serial Peripheral Interface (SPI) bus.
SPI
SPI is a serial synchronous communication protocol developed by Motorola. This master/slave protocol uses
4 wires as described below:
The protocol can work with one or more slaves and expand to more CS pins as needed. In essence, it operates
as a full duplex protocol controlled by the master. When the master wants to send a byte, it generates an
8-bit clock used to synchronize the transmission. Then the data is sent serially by shifting out bits from the
LSB to the MSB. In this lab, we will be reading a byte. To do that, the master will send a dummy byte
that generates the clock signal to send the data. This is shown graphically in Fig. 3.
The Raspberry Pi has a set of dedicated SPI pins, but unlike the GPIOs, there are no commands to access
these pins. One option would be to write a full application in C, C++, Python, or other language. In this
workshop, we will utilize a pre-existing application called spincl. To install this tool, run the commands
from the following listings.
# use the arrow keys to move around and put a ’#’ in front of both blacklists
# when you are done editing, hit CTRL+O to save, then CTRL+X to exit
Circuit
Build the circuit shown in Figures 4 and 5 and try reading the analog reading using spincl with SPI mode
0, clock divider 15, chip select 0, and chip polarity low. Remember that this is a 10-bit converter, therefore
you need to read 2 bytes to get the full value. Once this works on the command line, write a full shell script
to read and print two bytes.
Hook up the circuit described in Figure 6 to use with the following code listing:
try:
# Set up the GPIO channels
GPIO.setup(18, GPIO.OUT)
# Output to pin 18
while True:
GPIO.output(18, True)
time.sleep(1)
GPIO.output(18, False)
time.sleep(1)
except KeyboardInterrupt:
GPIO.cleanup()
If you save the file in your home directory as ‘blink1.py’, you can run the program with sudo /home/pi/
blink1.py. The program will stop when you hit CTRL+C.
1. Enter the example program and observe the output - make the LED blink twice as fast
3. Listing 18 demonstrates how to read an input in Python - make the program blink the 3 LEDs in
sequence when a user presses the button
while True:
except KeyboardInterrupt:
GPIO.cleanup()
This is only one way to access the SPI bus in python - there are likely better ways. But this will work for
our experimenting purposes today. See listing 20 for the code, and Figure 4 for the connection diagram.
import spidev
import time
spi = spidev.SpiDev()
spi.open(0,0) #open spi channel 0
spi.mode = 0 #mode (0,0) = 0, (0,1) = 1, (1,0) = 2, (1,1) = 3
def read_mcp3001():
reading = spi.readbytes(2)
# format of bytes read in (2 bytes = 16 bits):
# XXX0123456789XXX relevant bits
# 0001111111111000 bitmask (= 0x1ff8)
hi = reading[0] & 0x1f
lo = reading[1] & 0xf8
vin = (hi<<5) + (lo>>3)
vin = vin * 3.3/1024 #VREF = 3.3, 10 bit adc gives us (2^10 = 1024) steps
.
return vin
try:
#enter an infinite loop while, and continuously output values
while True:
reading = read_mcp3001() #get a reading!
print "vin: %fV" % reading #output the reading
time.sleep(0.5) #wait for half a second
except KeyboardInterrupt:
spi.close()
1. Implement Listing 20 and Figure 4 - adjust the potentiometer while the program is running and
observe the output
2. Implement thresholds - have the program print “Too High” for voltages over 3.0VDC, and “Too Low”
for voltages under 1.0VDC
3. Hook up some LEDs - ala earlier examples - and have them turn on when the voltage exceeds 3.0VDC.
Have them turn off when the voltage falls below 1.0VDC
4. Hook up a row of LEDs, and have them display the magnitude of the voltage like a ‘Bar Graph’
This concludes the prepared material - thanks for coming out!
Page 18 of 18