Shallow Thoughts : tags : raspberry pi
Akkana's Musings on Open Source Computing, Science, and Nature.
Wed, 29 Jan 2014
The first batch of hardware has been ordered for Rupa's and my
tutorial at PyCon in Montreal this April!
your own PiDoorbell - Learn Home Automation with Python on
the afternoon of Wednesday, April 9.
It'll be a hands-on workshop, where we'll experiment with the
Raspberry Pi's GPIO pins and learn how to control simple things like
an LED. Then we'll hook up sonar rangefinders to the RPis, and
build a little device that can be used to monitor visitors at your
front door, birds at your feeder, co-workers standing in front of your
monitor while you're away, or just about anything else you can think of.
Participants will bring their own Raspberry Pi computers and power supplies
-- attendees of last year's PyCon got them there, but a new Model A
can be gotten for $30, and a model B for $40.
We'll provide everything else.
We worried that requiring participants to bring a long list of esoteric
hardware was just asking for trouble, so we worked a deal with PyCon
and they're sponsoring hardware for attendees. Thank you, PyCon!
CodeChix is fronting the money
for the kits and helping with our travel expenses, thanks to donations
from some generous sponsors.
We'll be passing out hardware kits and SD cards at the
beginning of the workshop, which attendees can take home afterward.
We're also looking for volunteer T/As.
The key to a good hardware workshop is having lots of
helpers who can make sure everybody's keeping up and nobody's getting lost.
We have a few top-notch T/As signed up already, but we can always
use more. We can't provide hardware for T/As, but most of it's quite
inexpensive if you want to buy your own kit to practice on. And we'll
teach you everything you need to know about how get your PiDoorbell
up and running -- no need to be an expert at hardware or even at
Python, as long as you're interested in learning and in helping
other people learn.
This should be a really fun workshop! PyCon tutorial sign-ups just
opened recently, so sign up for the tutorial (we do need advance
registration so we know how many hardware kits to buy). And if you're
going to be at PyCon and are interested in being a T/A, drop me or
Rupa a line and we'll get you on the list and get you all the
information you need.
See you at PyCon!
[ 19:32 Jan 29, 2014
More hardware |
permalink to this entry |
Sat, 25 May 2013
When I'm working with an embedded Linux box -- a plug computer, or most
recently with a Raspberry Pi -- I usually use GNU screen as my
screen /dev/ttyUSB0 115200 connects to the appropriate
USB serial port at the appropriate speed, and then you can log in
just as if you were using telnet or ssh.
With one exception: the window size. Typically everything is fine
until you use an editor, like vim. Once you fire up an editor, it
assumes your terminal window is only 24 lines high, regardless of
its actual size. And even after you exit the editor, somehow your
window will have been changed so that it scrolls at the 24th line,
leaving the bottom of the window empty.
Tracking down why it happens took some hunting.
Tthere are lots of different places the
screen size can be set. Libraries like curses can ask the terminal
its size (but apparently most programs don't). There's a size built
into most terminfo entries (specified by the TERM environment
variable) -- but it's not clear that gets used very much any more.
There are environment variables LINES and COLUMNS,
and a lot of programs read those; but they're often unset, and even if
they are set, you can't trust them. And setting any of these didn't
help -- I could change TERM and LINES and COLUMNS all I wanted, but
as soon as I ran vim the terminal would revert to that
In the end it turned out the important setting was the tty setting.
You can get a summary of what the tty driver thinks its size is:
% stty size
But to set it, you use rows and columns rather than
I discovered I could type
stty rows 32 (or whatever my
current terminal size was), and then I could run vim and it would stay
at 32 rather than reverting to 24. So that was the important setting vim
The basic problem was that screen, over a serial line, doesn't have a
protocol for passing the terminal's size information, the way
a remote login program like ssh, rsh or telnet does. So how could
I get my terminal size set appropriately on login?
Auto-detecting terminal size
There's one program that will do it for you, which I remembered
from the olden days of Unix, back before programs like telnet had this
nice size-setting built in. It's called resize, and on Debian,
it turned out to be part of the xterm package.
That's actually okay on my current Raspberry Pi, since I have X
libraries installed in case I ever want to hook up a monitor.
But in general, a little embedded Linux box shouldn't need X,
so I wasn't very satisfied with this solution. I wanted something with
no X dependencies. Could I do the same thing in Python?
How it works
Well, as I mentioned, there are ways of getting the size of the
actual terminal window, by printing an escape sequence and parsing
But finding the escape sequence was trickier than I expected. It isn't
written about very much. I ended up running
capturing the output that resize sent, which seemed a little crazy:
'\e[7\e[r\e[999;999H\e[6n' (where \e means the escape character).
Holy cow! What are all those 999s?
Apparently what's going on is that there isn't any sequence to ask
xterm (or other terminal programs) "What's your size?" But there is
a sequence to ask, "Where is the cursor on the screen right now?"
So what you do is send a sequence telling it to go to row 999 and
column 999; and then another sequence asking "Where are you really?"
Then read the answer: it's the window size.
(Note: if we ever get monitors big enough for 1000x1000 terminals,
this will fail. I'm not too worried.)
Reading the answer
Okay, great, we've asked the terminal where it is, and it responds.
How do we read the answer?
That was actually the trickiest part.
First, you have to write to /dev/tty, not just stdout.
Second, you need the output to be available for your program to read,
not just echo in the terminal for the user to see. Setting the tty
to noncanonical mode
Third, you can't just do a normal blocking read of stdin -- it'll
never return. Instead, put stdin into non-blocking mode and use
to see when there's something available to read.
And of course, you have to make sure you reset the terminal back
to normal canonical line-buffered mode when you're done, whether
or not your read succeeds.
Once you do all that, you can read the output, which will look
something like "\e[32;80R". The two numbers, of course, are the
lines and columns values you want; ignore the rest.
stty in python
Oh, yes, and one other thing: once you've read the terminal size,
how do you set the stty size appropriately? You can't just run
system('stty rows %d' % (rows) seems like it should work,
but it doesn't, probably because it's using stdout instead of /dev/tty.
But I did find one way to do it, the enigmatic:
struct.pack("HHHH", rows, cols, 0, 0))
Here it all is in one script, which you can install on your Raspberry Pi
(or other embedded Linux box) and run from .bash_profile:
set stty size to the size of the current terminal window.
[ 18:47 May 25, 2013
More hardware |
permalink to this entry |
Sat, 18 May 2013
In my post about
a toy car with a Raspberry Pi, I skipped over one important detail:
the battery. How do you power the RPi while it's driving around the room?
Most RPi sites warn that you shouldn't use the Pi with a power supply
drawing less than an amp. I suspect that's overstated, and it probably
doesn't draw more than half of that most of the time; but add the draw
of two motors and we're talking a fairly beefy battery, not a couple
of AAs or a 9V.
Luckily, as an R/C plane pilot,
I have a fridge full of small 2- and 3-cell lithium-polymer batteries
(and a li-po charger to go with them). The problem is:
the Pi is rather picky about its input voltage. It wants 5V and nothing
else. A 2-cell li-po is 7.4V. So I needed some sort of voltage regulator.
It's easy enough to get a simple
voltage regulator (pictured at right) -- 30c at Jameco, not much
more locally. But they're apparently fairly inefficient, and need a
heat sink for high current loads.
So I decided to blow the big bucks ($15) for a
5V step-down power
converter (left) that claims to be 94% efficient with no need for
a heat sink.
Unlike most of Adafruit's products, this one comes with no tutorials
and no hints as to pinouts, but after a little searching, I determined
that the pins worked the same way as the cheap voltage regulators.
With the red logo facing you, the left pin (your left) is input power
from the battery; middle is ground (connect this to the battery's
ground which is shared with the Pi's ground); the right pin is the
regulated 5V output, which goes to pin 2 on the Pi's GPIO connector.
I was able to run both the RPi and the motor drive circuit off the
same 7.4 volt 2-cell li-po battery (which almost certainly wouldn't
work with 4 AAs, though it might work with 8). A 500 mAh battery seems
to be plenty to drive the RPi and the car, though I don't know how long
the battery life will be. I'll probably be using 610 mAh batteries for
most of my testing, since I have a collection of them for the aerial
Here's a wiring diagram made with Fritzing
showing how to hook up the battery to power a RPi. If you're driving motors,
you can run a line from the battery's + terminal (the left pin of the
voltage regulator) as your motor voltage source, and use the right pin
as your 5V logic source for whatever motor controller chip you're using.
[ 16:50 May 18, 2013
More hardware |
permalink to this entry |
Sun, 12 May 2013
In my previous article about
modulation on Raspberry Pi, I mentioned that the reason I wanted
PWM on several pins at once was to drive several motors, for a robotic car.
But there's more to driving motors than just PWM. The GPIO output pins
of a Pi don't have either enough current or enough voltage to drive
a motor. So you need to use a separate power supply to drive the motors,
and do some sort of switching -- at minimum, a transistor or relay for
There are lots of motor driver chips. For Arduinos, "motor shields",
and such things are starting to become available for the Pi as well.
But motor shields are expensive, usually more than the Pi costs
itself. If you're trying to outfit a robotics class, or to help
low-income students build robots, it's not a great solution.
When I struggled with this problem for the Arduino, the solution I
eventually hit on was a
H-bridge chip. For under $2, you get bidirectional control of two
DC motors. For each motor, you send input to the chip via a PWM line
and two directional control lines.
The only problem is the snarl of wiring. One PWM and two direction
lines per motor is six wires, plus power for the chip's logic side,
power for the motors, and ground, and the three pins for a serial cable,
and you're talking a lot of wires to plug in.
Although this is all easy in comcept, it's also easy
to get a wire plugged in one spot over on the breadboard from where
it ought to be, and then nothing works.
I spent too much time making tables of what should get plugged into where.
I ended up with a table like this:
|Pi connector pin ||GPIO (BCM) ||SN754410 pin
|Pi 2 ||5V power ||Breadboard bottom V+ row
|Pi 18 ||24 ||1 (motor 1 PWM)
|Pi 15 ||22 ||1 (motor 0 PWM)
|Pi 24 ||8 (SPI CE0) ||4 (motor 1 direc 0)
|Pi 26 ||7 (SPI CE1) ||14 (motor 1 direc 1)
|Pi 25 ||Gnd ||Breadboard both grounds
|Pi 19 ||10 (MOS1) ||3 (motor 0 direc 0)
|Pi 21 ||9 (MOS0) ||13 (motor 0 direc 1)
|motor 0 || ||5, 11
|motor 1 || ||6, 12
... though, as you'll see, some of those pin assignments ended up
getting changed later.
One more thing: I found that I had to connect the chip's logic V+
(pin 2 on the SN754410) to the 5v pin on the RPi, not the 3.3V pin.
The SN754410 is okay with 3.3V logic signals, but it seems to need
a full 5V of power.
The software control is a little trickier than it ought to be, too,
because of the 2-wire control lines on each motor. With both lines high
or both lines low, nothing moves. (Some motor driver chips distinguish
between those two states: e.g. both low might be a brake, while both
high lets the motor freewheel; but I haven't seen anything indicating
the SN754410 makes any distinction.) Then set one line high, the other
low, and the motor spins one way; reverse the lines, and the motor
spins the other way. Assuming, of course, the PWM line is sending
Of course, you need RPI.GPIO version 0.5.2a or later to do any of this
PWM control. Get it via
pip install --upgrade RPi.GPIO
-- the RPI.GPIO in Raspbian mis-reports its version and is really 0.5.1a.
Simple enough in concept. Okay, now try explaining that to beginning
programmers. No, thanks! So I wrote a
PiMotor class in
Python that takes care of all those details. Initialize it with the pins
you want to use, then use calls like
stop(). It's on GitHub at
I put the H-bridge chip on a breadboard, wired up all the lines to the
Pi and a lithium-polymer airplane battery, and (after several hours of
head-banging while I found all the errors in my wiring), sure enough,
I could get the motors to spin.
But one thing I found while wiring was that I couldn't always use the
GPIO lines I'd intended to use. The RPi has seemingly a lot of GPIO
lines -- but
nearly all of
the GPIO lines have other purposes, except I haven't found any
good explanation of what those uses are and how to know when they're
in use. I found that quite frequently, I'd try a
GPIO.setup(pin, GPIO.OUT) and get
"This channel is already in use". Sometimes
helped, and sometimes it didn't. None of this stuff has much
documentation, and I haven't found any IRC channel or mailing list
for discussing RPi GPIO. And of course, there's no relation between
the pin number on the header and the GPIO pin number. So I spent a lot
of time counting breadboard rows and correlating to a printout I'd made
of the RPi's GPIO socket.
Putting the circuit on a proto-board
Once I got it working, I realized how much I didn't relish the
thought of ever doing it again -- like whenever I needed to unplug
the motors from the Pi and use it for something else.
Fortunately, at some point I'd bought an
Adafruit Pi Plate,
sort of the RPi equivalent of Adafruit's Arduino ProtoShield. I love
protoshields. I have a bunch of them, and I use them for all sorts of
Arduino projects, so I'd bought the Pi Plate thinking it might come in
handy some day. It's not quite like a protoshield, because it's
expensive and heavy, loaded up with lots of pointless screw terminals.
But you don't have to solder the screw terminals on; just solder the
headers and you have a protoshield for your RPi on which you can put
a mini breadboard and build your motor circuit.
I do wish, though, that Adafruit or someone made a simple, basic
proto board PCB with headers for the Pi. No screw terminals, no extra
parts, just the PCB and headers, to make it easy and cheap to swap
between different RPi projects. The
Slice of Pi looks intriguing, but the GPIO pins it exposes don't seem
to be the same ones exposed on the RPI's GPIO header. I'd be
interested in hearing from anyone who's tried one of these.
Anyway, with the Pi Plate shield, my motor circuit looks much neater,
and I can unplug it from my RPi without fear that it'll mean
another half hour if I ever want to get the motors hooked up again.
I did have to change some of the pin assignments yet again, because
the Pi Plate doesn't expose all the GPIO pins available on the RPi header.
I ended up using 25, 23, 24 for the first motor, and 17, 21, 22 for
I wanted to make a circuit diagram with Fritzing, but it turns out the
Fritzing I have can't import part definitions like the one for
Raspberry Pi, and the current Fritzing doesn't work on Debian Wheezy.
So that'll have to wait. But here's a photo of my
breadboarded circuit on the Pi Plate, and a link to my
breadboarded circuit using a cable to the GPIO.
Kevin Mark tipped me off that Fritzing is quite easy to build under
Debian, if you first
apt-get install qt4-qmake libqt4-dev libboost1.49-dev
I had to add one more package to Kevin's list,
or I got a lot of QSQLITE driver not loaded and other errors
on the terminal, and a dialog saying "Unable to find the following 114 parts"
followed by another dialog too big to fit on the screen with a list of
all the missing parts.
Once those packages are installed, download the Fritzing source tarball,
qmake, make, and sudo make install.
And my little car can go forward, spin around in both directions, and
then reverse! Now the trick will be to find some sensors I can use with
the pins remaining ...
[ 13:08 May 12, 2013
More hardware |
permalink to this entry |
Sat, 04 May 2013
I've written about how to
small DC motors with an Arduino, in order to
a little toy truck around.
But an Arduino, while great at talking to hardware, isn't very powerful.
It's easy to add simple sensors to the truck so it can stop before hitting
the wall; but if I wanted to do anything complicated -- like, say,
image processing with a camera -- the Arduino really isn't enough.
Enter Raspberry Pi. It isn't a super-fast processor either, but it's
fast enough to run Linux, Python, and image processing packages like
A Raspberry-Pi driven truck would be a lot more powerful: in theory,
I could make a little Mars Rover to drive around my backyard.
If, that is, I could get the RPi driving the car's motors.
Raspberry Pi, sadly, has a lot of limitations as a robotics platform.
It's picky about input voltages and power; it has no analog inputs,
and only one serial port (which you probably want to use for a console
if you're going to debug your robot reliably).
But my biggest concern was that it has only one pulse-width modulation
(PWM) output, while I needed two of them to control the car's two motors.
It's theoretically possible to do software PWM on any pin -- but
until recently, there were no libraries supporting that.
Until recently. I've been busy for the last month or two and haven't
been doing much RPi experimenting. As I got back into it this week, I
discovered something delightful: in the widely available python library
Software PWM is available starting with 0.5.2a.
Getting the right RPi.GPIO
Just what I'd been wanting! So I got an LED and resistor and plugged
them into a breadboard.
I ran a black wire from the RPi's pin 6, ground, to the short LED pin,
and connected the long pin via the resistor to the RPi's pin 18
(GPIO 24) (see the
peripherals for the official GPIO pin diagrams).
With the LED wired up, I
in my serial cable, powered up the RPi with its Raspbian SD card,
and connected to it with
screen /dev/ttyUSB0 115200.
I configured the network to work on my local net and typed
sudo apt-get install python-rpi.gpio
to get the latest version. It got 0.5.2a-1. Hooray!
I hurried to do a test:
pi@raspberrypi:~$ sudo python
Python 2.7.3 (default, Jan 13 2013, 11:20:46)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO as GPIO
>>> GPIO.setup(24, GPIO.OUT)
>>> led = GPIO.PWM(24, 100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'PWM'
Whoops! But Raspbian said it was the right version ...
I checked again with
aptitude show python-rpi.gpio --
yep, 0.5.2a-1. Hmph!
After some poking around, I discovered that help(GPIO),
after printing out an interminable list of exception classes,
eventually gets to this:
VERSION = '0.5.1a'
In other words, Rapsbian is fibbing: that package that Raspbian says
is version 0.5.2a-1 is actually version 0.5.1a.
(This is the sort of thing that makes Raspberry Pi such a joy to work with.
Yes, that's sarcasm.)
Okay. Let's try removing that bogus Raspbian package and getting it from
apt-get remove python-rpi.gpio
pip install --upgrade RPi.GPIO
Then I tried the same test as before. Success!
And now I was able to set the LED to half brightness:
I was able to brighten and dim the LED at will:
I played with it a little while longer, then cleaned up:
If you're experimenting with RPi.GPIO's PWM, you'll want to check
out this useful 2-part tutorial:
What about motors?
So PWM works great for LEDs. But would it drive my little robotic car?
I unplugged my LED and wired up one of the
motor drivers circuits I'd wired up for the Arduino. And it worked
just as well! I was able to control the motor speed using ChangeDutyCycle().
I'll write that up separately, but I do have one caveat:
GPIO.cleanup(), for some reason, sets the pin output to HIGH.
So if you have your car plugged in and sitting on the ground when you
run cleanup(), it will take off at full speed.
I recommend testing with the car on a stand and the wheels off the ground.
Update: the motor post is up now, at
two DC motors with a Raspberry Pi.
[ 20:00 May 04, 2013
More hardware |
permalink to this entry |
Sat, 16 Mar 2013
I'm at PyCon, and I spent a lot of the afternoon in the Raspberry Pi lab.
Raspberry Pis are big at PyCon this year -- because everybody at
the conference got a free RPi! To encourage everyone to play, they
have a lab set up, well equipped with monitors, keyboards, power
and ethernet cables, plus a collection of breadboards, wires, LEDs,
switches and sensors.
I'm primarily interested in the RPi as a robotics controller,
one powerful enough to run a camera and do some minimal image processing
(which an Arduino can't do).
And on Thursday, I attended a PyCon tutorial on the Python image processing
It's a wrapper for OpenCV that makes it easy to access parts of images,
do basic transforms like greyscale, monochrome, blur, flip and rotate,
do edge and line detection, and even detect faces and other objects.
Sounded like just the ticket, if I could get it to work on a Raspberry Pi.
SimpleCV can be a bit tricky to install on Mac and Windows, apparently.
But the README on the SimpleCV
git repository gives an easy 2-line install for Ubuntu. It doesn't
run on Debian Squeeze (though it installs), because apparently it
depends on a recent version of pygame and Squeeze's is too old;
but Ubuntu Pangolin handled it just fine.
The question was, would it work on Raspbian Wheezy? Seemed like a
perfect project to try out in the PyCon RPi lab. Once my RPi was
set up and I'd run an
apt-get update, I used
used netsurf (the most modern of the lightweight browsers available
on the RPi) to browse to the
The first line,
sudo apt-get install ipython python-opencv python-scipy python-numpy python-pygame python-setuptools python-pip
was no problem. All those packages are available in the Raspbian repositories.
But the second line,
sudo pip install https://github.com/ingenuitas/SimpleCV/zipball/master
failed miserably. Seems that pip likes to put its large downloaded
files in /tmp; and on Raspbian, running off an SD card, /tmp quite
reasonably is a tmpfs, running in RAM. But that means it's quite small,
and programs that expect to be able to use it to store large files
are doomed to failure.
I tried a couple of simple Linux patches, with no success.
You can't rename /tmp to replace it with a symlink to a directory on the
SD card, because /tmp is always in use. And pip makes a new temp directory
name each time it's run, so you can't just symlink the pip location to
a place on the SD card.
I thought about rebooting after editing the tmpfs out of /etc/fstab,
but it turns out it's not set up there, and it wasn't obvious how to
disable the tmpfs. Searching later from home, the size is
set in /etc/default/tmpfs. As for disabling the tmpfs and using the
SD card instead, it's not clear. There's a block of code in
/etc/init.d/mountkernfs.sh that makes that decision; it looks like
symlinking /tmp to somewhere else might do it, or else commenting out
the code that sets RAMTMP="yes". But I haven't tested that.
Instead of rebooting, I downloaded the file to the SD card:
But it turned out it's not so easy to pip install from a local file.
After much fussing around I came up with this, which worked:
pip install http:///home/pi/master --download-cache /home/pi/tmp
That worked, and the resulting SimpleCV install worked nicely!
I typed some simple tests into the simplecv shell, playing around
with their built-in test image "lenna":
img = Image('lenna')
And, for something a little harder, some face feature detection:
let's find her eyes and outline them in yellow.
SimpleCV is lots of fun! And the edge detection was quite fast on the RPi --
this may well be usable by a robot, once I get the motors going.
[ 20:43 Mar 16, 2013
More linux/install |
permalink to this entry |
Sun, 06 Jan 2013
For a recent Raspberry Pi project, I decided to use the
Adafruit Pi Cobbler
to give me easy access to the RPi's GPIO pins.
My Cobbler arrived shortly before I had to leave for a short trip.
I was planning to take my RPi with me -- but not my soldering iron.
So the night before I left,
I hastily soldered together the Cobbler along with a few other parts I
wanted to play with. No problem -- it's an easy solder project, lots of
pins but no delicate parts or complicated circuitry.
Later, far from home, I opened up my hardware hack box, set up a breadboard and
started plugging in wires, following one of the tutorials mentioned below.
Except -- wait, the pins didn't seem to be in the place I expected them.
I quickly realized I'd soldered the ribbon cable connector on backward.
There's no way I could unsolder 26 pins all at once, even at home;
but away from home, without even a soldering iron, how could I possibly
(image courtesy of
The ribbon cable connector is basically symmetrical, two rows of 13 pins.
The connector on the cable is keyed -- it has a dingus sticking out of
it that's supposed to fit into the slot in the connector's plastic box.
If I could, say, cut another slot on the opposite side of the plastic
box, something big enough for the ribbon cable's sticky-out dingus
(sorry for the highly technical language!),
I could salvage this project and play with my RPi.
I was just about to dig in with the diagonal cutter when someone on IRC
suggested that I try to slide the plastic box (it turns out this is
called a "box header") up off the pins, turn it around and slide it back
on. They suggested that using a heat gun to soften the plastic might help.
I didn't have a heat gun where I was staying, but I did have a hairdryer.
I slipped a jeweler's screwdriver under the bottom of one side of the box,
levered against the circuit board to apply pressure upward, and hit it
with the hairdryer. It slid a few millimeters immediately.
I switched to the other side of the box and
repeated; that side obligingly slid too. About ten minutes of
alternating sides and occasional blasts from the hairdryer, and
the box was off! Sliding it back on was even easier. Project rescued!
(Incidentally, you may be thinking that the Cobbler is really just a
way to connect the Pi's header pins to a breadboard. I could have used
the backwards-soldered Cobbler and just kept track of which pins should
map to which other pins. True!
But all the pin numbers would have been mislabeled, and I know myself
well enough to know that eventually, I would have gotten the pin mapping
wrong and plugged something in to the wrong place. Having
destroyed an Adafruit Wave Shield earlier that day by doing just that,
connecting 5V to an I/O pin that it turned out wasn't expecting it
(who knew the SD reader chip was so sensitive?),
I didn't want to take the same risk with my only Raspberry Pi.)
[ 15:29 Jan 06, 2013
More hardware |
permalink to this entry |
Fri, 09 Nov 2012
I've been using my
Pi mostly headless -- I'm interested in using it to control hardware.
Most of my experimenting is at home, where I can plug the Pi's built-in
ethernet directly into the wired net.
But what about when I venture away from home, perhaps to a group
hacking session, or to give a talk? There's no wired net at most of
these places, and although you can buy USB wi-fi dongles, wi-fi is so
notoriously flaky that I'd never want to rely on it, especially as my
only way of talking to the Pi.
Once or twice I've carried a router along, so I could set up my own
subnet -- but that means an extra device, ten times as big as the Pi,
and needing its own power supply in a place where power plugs may be scarce.
The real solution is a crossover ethernet cable.
(My understanding is that you can't use a normal ethernet cable
between two computers; the data send and receive lines will end up crossed.
Though I may be wrong about that -- one person on #raspberrypi reported
using a normal ethernet cable without trouble.)
Buying a crossover cable at Fry's was entertaining. After several minutes
of staring at the dozens of bins of regular ethernet cables, I finally
found the one marked crossover, and grabbed it. Immediately, a Fry's
employee who had apparently been lurking in the wings rushed over to
warn me that this wasn't a normal cable, this wasn't what I wanted,
it was a weird special cable. I thanked him and assured him that was
exactly what I'd come to buy.
Once home, with my laptop connected to wi-fi, I plugged one end into
the Pi and the other end into my laptop ... and now what? How do I
configure the network so I can talk to the Pi from the laptop, and
the Pi can gateway through the laptop to the internet?
The answer is IP masquerading. Originally I'd hoped to give the
Pi a network address on the same networking (192.168.1) as the laptop.
When I use the Pi at home, it picks a network address on 192.168.1,
and it would be nice not to have to change that when I travel elsewhere.
But if that's possible, I couldn't find a way to do it.
Okay, plan B: the laptop is on 192.168.1 (or whatever network the wi-fi
happens to assign), while the Pi is on a diffferent network, 192.168.0.
That was relatively easy, with some help from the
Once I got it working, I wrote a script, since there are quite a few
lines to type and I knew I wouldn't remember them all.
Of course, the script has to be run as root.
Here's the script, on github:
I had to change one thing from the howto: at the end, when it sets
up security, this line is supposed to enable incoming
connections on all interfaces except wlan0:
iptables -A INPUT -m state --state NEW -i ! wlan0 -j ACCEPT
But that gave me an error,
Bad argument `wlan0'.
What worked instead was
iptables -A INPUT -m state --state NEW ! -i wlan0 -j ACCEPT
Only a tiny change: swap the order of -i and !. (I sent a correction
to the howto authors but haven't heard back yet.)
All set! It's a nice compact way to talk to your Pi anywhere.
Of course, don't forget to label your crossover cable, so you don't
accidentally try to use it as a regular ethernet cable.
Now please excuse me while I go label mine.
Update: Ed Davies has a great followup,
and Red Tape, that talks about how to set up a
subnet if you don't need the full masquerading setup, why
non-crossover cables might sometimes work, and a good convention for
labeling crossover cables: use red tape. I'm going to adopt that
convention too -- thanks, Ed!
[ 15:57 Nov 09, 2012
More hardware |
permalink to this entry |
Tue, 31 Jul 2012
Raspberry Pi, the tiny, cheap,
low-power Linux computer, dropped their order restrictions a few weeks
ago, and it finally became possible for anyone to order one. I
immediately (well, a day later, since the two sites that sell them
were slashdotted with people trying to order) put in an order with
Newark/element14. They said they were backordered six weeks, but
I wasn't in a hurry -- I just wanted to get in the queue.
Imagine my surprise when half a week later I got a notice that my
Pi had shipped! I got it yesterday. Thanks, Element14!
The Pi comes with no OS preloaded -- it boots off the SD card.
a download page where you can get an image of Debian Wheezy
their recommendation), Arch, or several other Linux distros.
I downloaded their latest Wheezy image and unzipped it.
But instructions on what to do from there are scanty, and tend to be
heavy on "click on this, then drag to here" directives that
make no sense if you're not using whatever desktop they assume you have.
So here's what ended up working.
Writing the SD card with dd
First, make sure you downloaded the image correctly:
sha1sum 2012-07-15-wheezy-raspbian.zip and compare the
sum it prints out with the one on the download page.
Then get an appropriate SD card. The image is sized for a 2G card, so
that's what I used, but you can use a larger card if needed ...
you'll only get 2G initially but you can resize the partition later.
Plug the SD card into a reader on your regular Linux desktop/laptop
machine, and figure out which device it is:
Then, assuming the SD card is in /dev/sdb (make sure of this! you don't
want to destroy your system disk by writing the wrong place!)
dd bs=1M if=2012-07-15-wheezy-raspbian.img of=/dev/sdb
Wait a while, make sure all the lights are off in your SD drive,
then remove the SD card from the reader. (Yes, even if you're about
to mount it to change something.)
Headless Raspberry Pi
Now you have an SD card that will probably boot your Pi.
If you want to run X on it and see a desktop, you'll need a USB keyboard
and mouse, some sort of monitor, and the appropriate cable.
That stopped me.
The Pi needs either an HDMI to DVI cable -- which I don't have, though
I will buy one as soon as I get a chance -- or an RCA composite video cable.
I think our old CRT TV can take composite video, but what I see
on the net suggests this is a poor solution for the Pi since
the resolution and image quality aren't really adequate.
But in any case, one of my main intended uses for the Pi involves using
it headless, as a robotics controller, in connection with an
Arduino or other
hardware for analog device control.
So the Pi needs to be able to boot without a monitor, taking commands
via its built-in ethernet interface, probably using ssh.
That means making some changes to the SD card.
Reinsert the card. (Why not just leave it in place? Because the image
you just wrote changed the partition table, and your computer won't
see the change unless you remove and reinsert the card.)
The card now has two partitions on it -- you can check that via
/proc/partitions. The first is the /boot partition,
where you shouldn't need to change anything. The second is the root
filesystem. Mount the second partition if your system didn't do that
mount /dev/sdb2 /mnt
Now specify a static IP address, so you'll always know how to
get to your Pi. Edit /mnt/etc/network/interfaces and change the
iface eth0 inet dhcp line to something like this,
using numbers that will work for your local network:
iface eth0 inet static
Now, if you google for other people who want to ssh in to their
Raspberry Pis or run them headless, you will find approximately
1,532,776 pages telling you that to enable sshd you'll need to
rename a file named boot_enable_ssh.rc somewhere on the /boot partition
Disregard this. There is no such file on the current
official wheezy pi images, and you will go crazy looking for it.
Happily, it turns out that the current images have the ssh server
enabled by default. You can verify that by looking at /mnt/etc/init.d/ssh
and seeing that it starts sshd. So after setting a static IP, you're
You're done! Remove the card, stick it in the Raspberry Pi,
plug in an ethernet cable, then power it with a micro USB cable.
Wait a minute or two (it's not the world's fastest booter,
and you should be able to ssh email@example.com or whatever
address you gave it. Log in with the password specified on the
Downloads page where you got the OS image ... and you're good to go.
Fun! Now I'm off to find an HDMI-DVI cable.
[ 20:26 Jul 31, 2012
More hardware |
permalink to this entry |