open('/dev/real_world')
Raspberry Pi Sensor and Actuator Control
Jack Minardi
Enthought Inc.
jminardi.github.io
Typical Computing
Data
0000-0010: 2f 2a 20 42-43 43 2e 68-0a 20 2a 20-30 33 2f 30
0000-0020: 36 2f 30 37-20 43 72 65-61 74 65 64-20 74 68 69
0000-0030: 73 20 61 73-20 61 20 73-75 62 63 6c-61 73 73 20
0000-0040: 6f 66 20 4c-61 74 74 69-63 65 52 65-67 75 6c 61
0000-0050: 72 33 64 2e-0a 2a 2f 0a-0a 23 69 6e-63 6c 75 64
0000-0060: 65 20 22 42-43 43 2e 68-22 0a 23 69-6e 63 6c 75
0000-0070: 64 65 20 3c-76 65 63 74-6f 72 3e 0a-23 69 6e 63
0000-0080: 6c 75 64 65-20 3c 63 6d-61 74 68 3e-0a 0a 76 6f
0000-0090: 69 64 20 42-43 43 3a 3a-53 65 74 75-70 28 20 73
0000-00a0: 68 6f 72 74-20 70 62 63-20 29 0a 7b-0a 20 20 20
0000-00b0: 20 2f 2a 20-49 66 20 6e-75 6d 5f 73-69 74 65 73
0000-00c0: 20 77 61 73-20 63 68 61-6e 67 65 64-20 69 6e 20
0000-00d0: 74 68 65 20-63 6f 6e 73-74 72 75 63-74 6f 72 2c
0000-00e0: 20 74 68 69-73 20 6d 61-6b 65 73 20-73 75 72 65
0000-00f0: 20 74 68 61-74 0a 20 20-20 20 20 2a-20 6c 65 6e
0000-0100: 67 74 68 20-69 73 20 70-72 6f 70 65-72 6c 79 20
0000-0110: 64 65 66 69-6e 65 64 2e-0a 20 20 20-20 20 2a 2f
0000-0080: 6c 75 64 65-20 3c 63 6d-61 74 68 3e-0a 0a 76 6f
0000-0090: 69 64 20 42-43 43 3a 3a-53 65 74 75-70 28 20 73
0000-00a0: 68 6f 72 74-20 70 62 63-20 29 0a 7b-0a 20 20 20
0000-00b0: 20 2f 2a 20-49 66 20 6e-75 6d 5f 73-69 74 65 73
0000-00c0: 20 77 61 73-20 63 68 61-6e 67 65 64-20 69 6e 20
0000-00d0: 74 68 65 20-63 6f 6e 73-74 72 75 63-74 6f 72 2c
0000-00e0: 20 74 68 69-73 20 6d 61-6b 65 73 20-73 75 72 65
Pictures
Physical Computing
http://www.flickr.com/photos/alpi-costerni
Today's Goal
ZMQ
RPi.GPIO
ServoBlaster
spidev
Overview / Definitions
Raspberry Pi
GPIO Pins
Sensor
Actuator
Parts needed
Operating System
Occidentals - Wheezy based
Comes preloaded with most everything you will need
http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/occidentalis-v0-dot-2
1Blink an LED.
2Read a pot.
3Stream data.
4
Servo control.
1Blink an LED.
2Read a pot.
3Stream data.
4
Servo control.
1. Blink an LED.
Typical LEDs work with 10-30 mA and drop about 2-3 volts
Calculate resistor needed based on max current and LED voltage ( R = (VS - VL) / I )
If you don't feel like doing math choose a resistance between 500 and 1500 ohms.
wikimedia.org
1. Blink an LED.
RPi.GPIO python package
code.google.com/p/raspberry-gpio-python/
It comes with Occidentals, if using another distro:
apt-get install python-rpi.gpio
or
pip install rpi.gpio
1. Blink an LED.
Software
import time
from itertools import cycle
import RPi.GPIO as io
io.setmode(io.BCM)
io.setup(12, io.OUT)
o = cycle([1, 0])
while True:
io.output(12, o.next())
time.sleep(0.5)
Hardware
1. Blink an LED.
Software
import time
from itertools import cycle
import RPi.GPIO as io
io.setmode(io.BCM)
io.setup(12, io.OUT)
o = cycle([1, 0])
while True:
io.output(12, o.next())
time.sleep(0.5)
Hardware
1Blink an LED.
2Read a pot.
3Stream data.
4
Servo control.
2. Read a pot.
A potentiometer (pot) is a
variable resistor.
A voltage is applied across the
outer pins and the knob position is sensed on the inner pin
This is an analog sensor, and the raspi can not read it without help.
wikimedia.org
2. Read a pot.
MCP3008 http://adafru.it/856
This chip is an Analog-to-Digital Converter (ADC)
It has 8 10-bit channels
Raspberry Pi uses SPI to communicate with it.
2. Read a pot.
spidev python package
github.com/doceme/py-spidev
To install:
git clone git://github.com/doceme/py-spidev
cd py-spidev/
sudo python setup.py install
For more information:
http://jeremyblythe.blogspot.co.uk/2012/09/raspberry-pi-hardware-spi-analog-inputs.html
2. Read a pot.
Software
import spidev
import time
spi = spidev.SpiDev()
spi.open(0,0)
def readadc(adcnum):
if not 0 <= adcnum <= 7:
return -1
r = spi.xfer2([1, (8+adcnum)<<4, 0])
adcout = ((r[1] & 3) << 8) + r[2]
return adcout
while True:
val = readadc(0)
print val
time.sleep(0.5)
Hardware
2. Read a pot.
Software
import spidev
import time
spi = spidev.SpiDev()
spi.open(0,0)
def readadc(adcnum):
if not 0 <= adcnum <= 7:
return -1
r = spi.xfer2([1, (8+adcnum)<<4, 0])
adcout = ((r[1] & 3) << 8) + r[2]
return adcout
while True:
val = readadc(0)
print val
time.sleep(0.5)
Hardware
1Blink an LED.
2Read a pot.
3Stream data.
4
Servo control.
3. Stream data.
ØMQ networking library
http://www.zeromq.org/
To install:
apt-get install python-zmq
pip install pyzmq
Described as "TCP on steroids"
REQUEST/REPLY pattern
3. Stream data.
Server
import zmq
context = zmq.Context()
socket = context.socket(
zmq.REP)
socket.bind('tcp://*:1980')
while True:
message = socket.recv()
print message
socket.send("I'm here")
Client
import zmq
context = zmq.Context()
socket = context.socket(
zmq.REQ)
a = 'tcp://192.168.1.6:1980'
socket.connect(a)
for request in range(10):
socket.send('You home?')
message = socket.recv()
print message
3. Stream data.
Server
import zmq
context = zmq.Context()
socket = context.socket(
zmq.REP)
socket.bind('tcp://*:1980')
while True:
message = socket.recv()
print message
socket.send("I'm here")
Client
import zmq
context = zmq.Context()
socket = context.socket(
zmq.REQ)
a = 'tcp://192.168.1.6:1980'
socket.connect(a)
for request in range(10):
socket.send('You home?')
message = socket.recv()
print message
3. Stream data.
Chaco - Interactive plotting library
Enaml - GUI development library
To install:
Download and install Enthought Canopy from enthought.com
or
Install the "Enthought Tool Suite" from PyPI
pip install ets
3. Stream data.
Model
class PlotModel(HasTraits):
plot = Instance(Plot)
def _plot_default(self):
data = ArrayPlotData()
x = np.arange(-3, 3, 0.1)
data['x'] = x
data['y'] = np.sin(x)
plot = Plot(data)
plot.plot(('x', 'y'))
plot.padding = (0, 0, 0, 0)
return plot
View
from enaml.widgets.api import (
MainWindow, EnableCanvas,
Container)
from plotmodel import PlotModel
enamldef Main(MainWindow):
id: main
attr model = PlotModel()
Container:
EnableCanvas:
component = model.plot
3. Stream data.
Model
class PlotModel(HasTraits):
plot = Instance(Plot)
def _plot_default(self):
data = ArrayPlotData()
x = np.arange(-3, 3, 0.1)
data['x'] = x
data['y'] = np.sin(x)
plot = Plot(data)
plot.plot(('x', 'y'))
plot.padding = (0, 0, 0, 0)
return plot
View
from enaml.widgets.api import (
MainWindow, EnableCanvas,
Container)
from plotmodel import PlotModel
enamldef Main(MainWindow):
id: main
attr model = PlotModel()
Container:
EnableCanvas:
component = model.plot
3. Stream data.
1Blink an LED.
2Read a pot.
3Stream data.
4
Servo control.
4. Servo control.
A servo can be set to a
given position.
Controlled with Pulse Width Modulation (PWM)
Min Position: 0.5 ms pulse
Max Position: 2.5 ms pulse
Period: ~20 ms
wikimedia.org
2.5 ms
.5 ms
~20 ms
4. Servo control.
ServoBlaster - Servo kernel module
https://github.com/richardghirst/PiBits
$ echo 3=120 > /dev/servoblaster
Servo Number
Pulse Width in 10 μs
Servo Number | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Pin Number | 4 | 17 | 18 | 21 | 22 | 23 | 24 | 25 |
4. Servo control.
Software
import time
import numpy as np
from robot_brain.servo import Servo
servo = Servo(0, min=60, max=200)
for val in np.arange(0, 1, 0.05):
servo.set(val)
time.sleep(0.1)
Hardware
https://github.com/jminardi/RobotBrain
4. Servo control.
Software
import time
import numpy as np
from robot_brain.servo import Servo
servo = Servo(0, min=60, max=200)
for val in np.arange(0, 1, 0.05):
servo.set(val)
time.sleep(0.1)
Hardware
https://github.com/jminardi/RobotBrain
Thanks! Questions?
All code can be found here:
jminardi.github.io
Contact:
jminardi@enthought.com
@jackminardi