Shallow Thoughts : tags : hardware
Akkana's Musings on Open Source Computing, Science, and Nature.
Wed, 22 May 2013
For half a year now my Timex watch (yes, I'm one of those old fogeys
who actually wears a watch) hasn't had a light. And it doesn't beep
when I use the stopwatch. I don't care so much about the beep, but
the light was handy.
I replaced the battery at some point, and apparently got something
wrong when I put it back together. I've been meaning to go back in
and figure out what I got wrong, but life intervened, so I've been
putting up with it for way too long, until now.
I felt a bit better about having messed up when some web searching
showed that many, many people have this exact same problem.
Some of the web pages I found had succestions that got the beeper
working again; but the light still didn't work.
Curiously, it worked fine with the watch disassembled: the watch's
brains and battery are all in one self-contained module, and if you
push the tiny button in the front, the light comes on. It's just that
the big button in the front didn't push the tiny button on the watch
module.
Maybe there was some tiny piece that went sproinging off to
freedom the first time I opened the watch. No matter; if so, it's long
gone now.
But you know what? Several pieces of masking tape stacked up over
the inner button worked fine -- and now my Indiglo light works again.
A few other tips for Timex fixers, some of which aren't obvious from
the how-to sites:
-
The "scratches" on my crystal -- so bad I'd been thinking it was time
to buy a new watch -- were actually melamine (or some such material)
that had rubbed off from the artists' table I use as a desk.
It cleaned off nicely with alcohol.
- I used a needle to open the spring clip over the battery.
-
Rotating the back cover 180° was probably what fixed the beeper.
-
You may or may not need to reset the watch by shorting the two contacts
as suggested on the label inside the watch. If you see an error code
or the watch doesn't work right, try shorting the contacts.
Tags: hardware
[
14:56 May 22, 2013
More hardware |
permalink to this entry |
comments
]
Sat, 18 May 2013
In my post about
Controlling
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
5V
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
combat planes.
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.
Tags: hardware, raspberry pi, robots
[
16:50 May 18, 2013
More hardware |
permalink to this entry |
comments
]
Sun, 12 May 2013
In my previous article about
pulse-width
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
each motor.
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
SN754410
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.
Programming it
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
a signal.
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 set_speed(s)
and stop(). It's on GitHub at
pimotors.py.
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 GPIO.cleanup()
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
HobbyTronics
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
the second.
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
motor
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, libqt4-sql-sqlite,
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 ...
Tags: hardware, raspberry pi, robots
[
13:08 May 12, 2013
More hardware |
permalink to this entry |
comments
]
Sat, 04 May 2013
I've written about how to
drive
small DC motors with an Arduino, in order to
drive
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
SimpleCV.
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
RPi.GPIO,
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
RPi Low-level
peripherals for the official GPIO pin diagrams).
With the LED wired up, I
plugged
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.setmode(GPIO.BCM)
>>> 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
pypi instead:
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:
led.start(50)
I was able to brighten and dim the LED at will:
led.ChangeDutyCycle(90)
led.ChangeDutyCycle(25)
I played with it a little while longer, then cleaned up:
led.stop()
GPIO.cleanup()
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
SN754410
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
Driving
two DC motors with a Raspberry Pi.
Tags: raspberry pi, hardware, electronics, robots
[
20:00 May 04, 2013
More hardware |
permalink to this entry |
comments
]
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
library SimpleCV.
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
SimpleCV
installation instructions.
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:
wget https://github.com/ingenuitas/SimpleCV/master
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')
img.show()
img.binarize().show()
img.toGray().show()
img.edges().show()
img.invert().show()
And, for something a little harder, some face feature detection:
let's find her eyes and outline them in yellow.
img.listHaarFeatures()
img.findHaarFeatures('eye.xml').draw(color=Color.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.
Tags: raspberry pi, python, programming, hardware, linux
[
20:43 Mar 16, 2013
More linux/install |
permalink to this entry |
comments
]
Sun, 17 Feb 2013
I've done a few experiments with
playing
music on an Arduino over the years -- the Arduino library has a
tone() call that gives you a nice tinny monophonic
"chiptunes" style noise. But for playing anything more complex,
you need more processing power.
I had a silly little project in mind. I like some pink noise when I'm
sleeping (in summer, I usually have a fan running). You can buy
electronic devices called "sleep soothers" that have tracks of the
ocean, rain, trains etc. but they often have annoying misfeatures
(like foghorns or train whistles in the middle of a track). Wouldn't
it be more fun to make my own, with sound samples of my choice?
Pink noise samples
Of course, I needed some sound samples, and
I found a great resource: Laptop.org's list of
Free sound samples.
I downloaded a few sample collections that looked like they might have
some nice ambient pink-noise sounds -- rain, ocean and so forth.
Some of the samples were usable right away.
But others are only available at 44.1k, and the
Adafruit Wave Shield, the hardware I was targeting first, will only play
WAV audio at 16k. So they needed to be converted.
A simple shell loop did that:
for fil in *.wav ; do
avconv -i $fil -ar 16000 ../samples16/$fil
echo $fil
done
Arduino hardware
There are several Arduino shields for playing sound files.
The simplest (and probably cheapest) is the
Adafruit Wave Shield,
and that's what I started with. It comes as a kit that you solder
together (an easy soldering project) and it has its own volume control
and SD card reader. On the down side, it can only play .WAV files, not
other formats like .MP3 or .OGG. But for my sleep soother project that
was okay.
Getting basic sounds playing was easy, following Adafruit's tutorial
and sample code. But for my project, I also needed some external
buttons, to allow for jumping from one track to the next. I was a
little confused about which pins are used by the shield, and I ended
up wiring my button to one of the pins that the shield uses for
talking to the SD card reader. Things didn't work at all. And then
while I was fumbling with plugging/unplugging things, at some point
I installed the shield onto the Arduino wrong, with the pins off by one.
I'm not sure whether it was the miswired button or the off-by-one shield,
but something got fried in the wave shield and it was never able to
read an SD card again after that (yes, even after plugging it in properly).
I thought about ordering another Wave Shield. But I was leery -- if
it's so delicate that a stray 5v signal in the wrong place can fry it
permanently, how long did I expect a second one to last? Besides, I was
tired of soldering things, and I happened to be putting in an Amazon
order for some other things. So I ran a search and found that there was
an MP3 player shield available through them, made by Seeed Studio.
It even had buttons built in, so I wouldn't need any extra hardware.
It was a little more expensive than the Wave shield, but it claimed to
play MP3 and OGG as well as WAV, and it comes pre-assembled, no
soldering needed.
The hardware arrived and looked nice. Two simple buttons plus a
"multifunction" button you can press or rock left or right. I grabbed
a micro SD card, put some MP3s on it, and went to
Seeed's page
on the Music Shield.
Hacking the Seeed library
I was a little worried when I discovered that they have three
different demos there -- each of which comes with a different library,
and you have to remove one set of libraries before you can try a
different demo. Not a good sign.
And indeed, it wasn't. None of the demos worked at all. When I added
some debug Serial.printlns, I found that it wasn't opening
the SD card.
Much web searching found a couple of people saying they'd discovered that
the Seeed shield only works with 2G or smaller microSD cards. Good luck
finding one of those! The next day, I drove all over town looking for
one, without success, and was on the verge of giving up when Dave remembered a
little cheapie camera he'd bought a few years ago for taking airplane
movies. It came with a microSD card. Success! It was a 2G card.
Back to trying the various demos and their incompatible libraries again.
And this time, one of the demos, the first one (the one that comes with
the Music v1 14.zip library), worked. I could play tracks,
sequentially as they were loaded on the SD card.
Unfortunately, that wasn't what I wanted to do -- I wanted to play the
same track over and over, jumping to the next track when the user
presses a button. I tried the other demos. None of them worked at all.
Long story short, after struggling for the better part of a week and
reverse-engineering a fair amount of the Music v1 14 library, I finally
got my sketch working.
Sharing the changes
I come from the open-source world. I keep my
Arduino sketches on GitHub
(at least once they work well enough to be useful to anybody).
So of course I wanted to share the work I'd put into fixing this
library.
I had it all laid out and ready to commit, and was working on
some documentation on how to use it, when I noticed the readme.txt
in the library directory. It begins:
Copyright (c) 2010 Seedstudio. All right reserved.
Pffft! So after finally getting things working, I can't share my working
version of the library! What are they thinking? What on earth is the
point of distributing a library for your hardware, one that you know
doesn't work very well (or you wouldn't be distributing four different
incompatible versions of it), and then not letting anyone fix it for you?
I posted a query in one of the many
threads
discussing problems with the Music Shield, asking if Seeed would
consider releasing the library under a license that allowed redistribution.
It's been a few weeks now, and no answer yet.
Incidentally, even posting the query wasn't easy. Seeed doesn't let
you post in their forums unless you register -- and the registration
process requires full name, address, and phone number! Fortunately,
they have no way of knowing whether the info you give them is fake,
so that's what I did.
Since I don't have permission to share the code directly, I've checked
in a patch that updates their library so it can play arbitrary tracks,
not just sequential ones, and can re-play the same track. It's here:
Music Shield
library on GitHub, along with my sample app, called play-repeat.
Conclusions
So my app is working now. Well, mostly; sometimes the volume randomly
jumps in the middle of the night, which I think is a hardware glitch,
but since it only happens after several hours of play, it's hard to debug.
But if you're looking for an Arduino sound project, I can't recommend
either the Wave Shield or the Seeed Music Shield. The Wave Shield
seems too fragile and its formats are limited, though the
tutorials and support are great.
And I'll certainly never buy anything from Seeed again.
If I had it to do over again, I'd spend the big bucks and buy
the Sparkfun
MP3 Player Shield. It's more expensive ($40) and doesn't have nice
buttons like the Seeed shield, but it plays all the formats the Seeed
shield does, and they offer tons of documentation and examples,
including an open-source library and code contributed by users.
Tags: arduino, hardware, music
[
11:37 Feb 17, 2013
More hardware |
permalink to this entry |
comments
]
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.
Argh!
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
recover?
(image courtesy of
PANAMATIK
of Wikipedia)
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.)
Tags: hardware, raspberry pi, ribbon cable, box header
[
15:29 Jan 06, 2013
More hardware |
permalink to this entry |
comments
]
Fri, 09 Nov 2012
I've been using my
Raspberry
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
Masquerading
Simple Howto.
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:
masq.
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,
Crossover Cables
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!
Tags: raspberry pi, hardware, linux, networking
[
15:57 Nov 09, 2012
More hardware |
permalink to this entry |
comments
]
Thu, 09 Aug 2012
I have an old tool bag I bought at a surplus store a zillion years ago
to carry tools in the trunk of my Fiat X1/9, while I was
learning
to work on cars. It's reasonably compact, with two pockets, which
I designated as "wrenches" and "everything else", and it carried nearly
all my tools for over a decade.
But over that time, it's been getting progressively shabbier and
dirtier -- funny thing about something that gets tossed on roadsides
and parking lots. And I've been getting tired of the way, when I need
to find that 10mm wrench, I have to dump everything in the "wrenches"
pocket out on the garage floor and sort through them. Then the last
straw was the zipper breaking.
Lately, every time I have to find a tool, an idle thought flits through
the back of my mind, like ... wouldn't it be nice if I had some flat
thing that held all the tools in some sort of order, which then rolled
up into a compact bag?
It took an embarrassingly long time before it occurred to me that
if I was thinking this,
maybe someone else had had the same idea ... and to go to Amazon and
search for "tool roll". And discover that there were dozens of these
things, and they're not even expensive. Under $20 for a nice one.
So I ordered one.
When it arrived, I took all my tools out of the old bag, washed and
dried them, and sorted them. (What ever happened to my 14mm socket?
Or the short 3/8-inch extension?) Then I laid out the tool roll
and started choosing pockets.
I was glad I'd chosen the 25-pocket model instead of one of the
smaller ones. I didn't have any problem filling out the pockets,
and I'm still not sure what to do with my set of deep sockets.
Maybe I should get an even bigger roll!
But I'm very happy with my tool roll for now.
I'm jazzed about how organized the tools are now and how easy it'll
be to find things, and to pack up after a repair job. And it rolls up
much smaller than the old tool bag, so it'll be easy to store in the
Miata's trunk. Not that I expect to need to carry tools with the Miata,
like I sometimes needed for the Fiats ... but it never hurts to be
prepared. And having my tools in one compact place will also it easy
to toss them in the back of the Rav4 when we go on desert trips.
(And no, I don't know how the large Vice-Grips got so rusty. They
never got wet.)
Tags: hardware, cars
[
15:10 Aug 09, 2012
More hardware |
permalink to this entry |
comments
]
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:
I used cat /proc/partitions.
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
sync
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
automatically:
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
address 192.168.1.50
netmask 255.255.255.0
gateway 192.168.1.1
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
to boot.rc.
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
ready to umount /mnt
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 pi@192.168.1.50 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.
Tags: raspberry pi, hardware, linux
[
20:26 Jul 31, 2012
More hardware |
permalink to this entry |
comments
]
Mon, 25 Jun 2012
Some time ago, I wrote about my explorations into the options for
driving
motors from an Arduino.
Motor shields worked well -- but they cost around $50 each, more than
the Arduino itself. That's fine for a single one, but I'm teaching an
Arduino workshop (this Thursday!) for high school girls, and I needed
something I could buy more cheaply so I could get more of them.
(Incidentally, if any women in the Bay Area want to help with the
workshop this Thursday, June 28 2012,
I could definitely use a few more helpers! Please drop me an email.)
What I found on the web and on the Arduino IRC channel was immensely
confusing to someone who isn't an electronics expert -- most people
recommended things like building custom H-bridge circuits out of zener
diodes.
But it's not that complicated after all.
I got the help I needed from ITP Physical Computing's
DC Motor
Control Using an H-Bridge.
It turns out you can buy a chip called an SN754410 that implements an
H-bridge circuit -- including routing a power source to the motors
while keeping the Arduino's power supply isolated -- for under $2.
I ordered my
SN754410
chips from Jameco and they arrived the next day.
(Technically, the SN754410 is a "quad half-bridge" rather than an "dual
h-bridge". In practice I'm not sure of the difference. There's another
chip, the L298, which is a full h-bridge and is also cheap to buy --
but it's a bit harder to use because the pins are wonky and it doesn't
plug in directly to a breadboard unless you bend the pins around.
I decided to stick with the SN754410;
but the L298 might be better for high-powered motors.)
Now, the SN754410 isn't as simple to use as a motor shield. It has a
lot of wires -- for two motors, you'll need six Arduino output pins,
plus a 5v reference and ground, the four wires to the two motors,
and the two wires to the motor power supply. Here's the picture
of the wiring, made with Fritzing.
With all those wires, I didn't want to make the girls wire them up
themselves -- it's way too easy to make a mistake and connect the wrong
pin (as I found when doing my own testing). So I've wired up several of
them on mini-breadboards so they'll be more or less ready to use.
They look like little white mutant spiders with all the wires going
everywhere.
A simple library for half-bridge motor control
The programming for the SN754410 is a bit less simple than motor shields
as well. For each motor, you need an enable pin on the Arduino -- the
analog signal that controls the motor's speed, so it needs to be one
of the Arduino's PWM output pins, 9, 10 or 11 -- plus two logic pins,
which can be any of the digital output pins.
To spin the motor in one direction, set
the first logic pin high and the second low; to spin in the other
direction, reverse the pins, with the first one low and the second one high.
That's simple enough to program -- but I didn't look forward to trying
to explain it to a group of high school students with basically no
programming experience.
To make it simpler for them, I wrote a drop-in library that simplifies
the code quite a bit. It defines a Motor object that you can initialize
with the pins you'll be using -- the enable pin first, then the two logic pins.
Initialize them in setup() like this:
#include
Motor motors[2] = { Motor(9, 2, 3), Motor(10, 4, 5) };
void setup()
{
motors[0].init();
motors[1].init();
}
Then from your loop() function, you can make calls like this:
motors[0].setSpeed(128);
motors[1].setSpeed(-85);
Setting a negative speed will tell the library to reverse the logic pins
so the motor spins the opposite direction.
I hope this will make motors easier to deal with for the girls who
choose to try them. (We'll be giving them a choice of projects, so
some of them may prefer to make light shows with LEDs, or
music with piezo buzzers.)
You can get the code for the HalfBridge library, and a sample sketch
that uses it, at
my
Arduino github repository
Cheap and easy motor control -- and I have a fleet of toy cars to
connect to them. I hope this ends up being a fun workshop!
Tags: arduino, hardware, education, programming
[
21:32 Jun 25, 2012
More hardware |
permalink to this entry |
comments
]
Tue, 06 Mar 2012
I got a request from SVLUG to fill in at the last minute for a speaker
with a health emergency. Fortunately, I'd been slated to give them my
Arduino talk from SCALE in a few months, so I was happy to accept.
I'm always glad for a chance to show off Bruce, my
Arduino-
and Linux-controlled 6-foot flying robotic shark.
And if anyone
reading this happens to be in town for PyCon, Symantec isn't that
far from Santa Clara, roughly a 10-minute drive ... and I promise there
will be at least two interesting Python scripts presented.
It's free, of course, so come hear the talk!
Here are the SVLUG meeting
details and directions.
Tags: speaking, arduino, hardware, robots, radio control
[
18:25 Mar 06, 2012
More speaking |
permalink to this entry |
comments
]
Fri, 02 Mar 2012
Working on projects that might be fun for a proposed Arduino high school
workshop, I realized I hadn't done much with Arduinos and sound.
I'd made clicking noise for my
sonar
echolocation device, but nothing more than that.
But the Arduino library has a nice function to control a speaker:
tone(int pin,
int frequency, int length).
tone() works much better than trying to make your own
square wave, because it uses interrupts and doesn't glitch when
the processor gets busy doing other things. You can leave off the
length parameter and the tone will continue until you
tell it to stop or change frequency.
Random tones
So you can produce random tones like this (SPEAKER is the pin the
speaker is plugged into):
uint8_t SPEAKER = 8;
void setup()
{
pinMode(SPEAKER, OUTPUT);
// Seed the random number generator from floating analog pin 0:
randomSeed(analogRead(0));
}
void loop()
{
// Random frequency between 20 and 1400 (Hz).
unsigned long freq = random(20, 1400);
long duration = random(5, 50);
tone(SPEAKER, freq, duration);
delay(random(100, 300));
}
Light theremin
Purely random tones aren't very interesting to listen to, though, as
it turns out.
How about taking input from a photo-resistor, to make
a light theremin that wails as I move my hand up and down above the
sensor? The photoresistor I was using typically reads, on the Arduino,
between 110 (with my hand over the sensor) and 800. So I wanted
to map that range to audible frequencies the speaker could handle,
between about 20 Hz and 5000.
uint8_t LIGHTSENSOR = 0;
void loop()
{
// Set the frequency according to the light value read off analog pin 0.
#define MAX_SIGNAL 800
#define MAX_FREQ 5000
#define MIN_SIGNAL 380
#define MIN_FREQ 20
int lightsensor = analogRead(LIGHTSENSOR);
int freq = (lightsensor - MIN_SIGNAL)
* (float)(MAX_FREQ - MIN_FREQ)
/ (MAX_SIGNAL - MIN_SIGNAL)
+ MIN_FREQ;
tone(SPEAKER, freq);
}
Random music (chiptunes)
That was fun, but
I still wanted to try some random music that actually sounded ... musical.
So how about programming the standard scale, and choosing frequencies from
that list?
I looked up the frequency for Middle C, then used fractions to
calculate the rest of the
"just" diatonic
scale for C major:
float middle_c = 262.626;
float just[] = { 1., 9./8, 5./4, 4./3, 3./2, 5./3, 15./8 };
#define NUMNOTES (sizeof(just)/sizeof(*just))
float cur_octave = 1.;
Multiplying the frequency by 2 transposes a note up one octave;
dividing by two, down one octave. cur_octave will keep track
of that.
Now if whichnote is a number from 0 to 7,
cur_octave * just[whichnote] * middle_c
will give the next frequency to play.
Just choosing notes from this list wasn't all that interesting either.
So I adjusted the code to make it more likely to choose a note just one
step up or down from the current note, so you'd get more runs.
rand = random(0, 6);
if (rand == 0)
whichnote = (whichnote + 1) % NUMNOTES;
else if (rand == 1)
whichnote = (whichnote + 1) % NUMNOTES;
else
whichnote = random(0, NUMNOTES);
float freq = middle_c * just[whichnote];
// Change octave?
rand = random(0, 10);
if (rand == 1 && cur_octave <= 3) {
cur_octave *= 2.;
} else if (rand == 2 && cur_octave >= 1) {
cur_octave /= 2.;
}
freq *= cur_octave;
It's still not great music, but it's a fun experiment and I'm looking
forward to adding more rules and seeing how the music improves.
Bach
But this left me hungry for real music. What if I wanted to play
a real piece of music? Certainly I wouldn't want to type in an array
of frequency numbers, or even fractions. I'd like to be able to say
A, Ab (for A-flat), Cs (for C-sharp), etc.
So I defined the frequency for each of the notes in the scale:
#define NOTE_Ab 207.652
#define NOTE_A 220.000
#define NOTE_As 233.082
#define NOTE_Bb NOTE_As
#define NOTE_B 246.942
#define NOTE_C 261.626
#define NOTE_Cs 277.183
#define NOTE_Db NOTE_Cs
#define NOTE_D 293.665
#define NOTE_Ds 311.127
#define NOTE_Eb NOTE_Ds
#define NOTE_E 329.628
#define NOTE_F 349.228
#define NOTE_Fs 369.994
#define NOTE_Gb NOTE_Fs
#define NOTE_G 391.995
#define NOTE_Gs 415.305
#define NOTE_REST 0.0
#define NOTE_SUSTAIN -1.0
Then the first part of Bach's 2-part invention #4 in D minor
looks like this:
float composition[] = {
NOTE_D, NOTE_E, NOTE_F, NOTE_G, NOTE_A*2, NOTE_As*2,
NOTE_Db, NOTE_As*2, NOTE_A*2, NOTE_G, NOTE_F, NOTE_E,
NOTE_F, NOTE_REST, NOTE_A*2, NOTE_REST, NOTE_D*2, NOTE_REST,
NOTE_G, NOTE_REST, NOTE_Cs*2, NOTE_REST, NOTE_E*2, NOTE_REST,
NOTE_D*2, NOTE_E*2, NOTE_F*2, NOTE_G*2, NOTE_A*4, NOTE_As*4,
NOTE_Db*2, NOTE_As*4, NOTE_A*4, NOTE_G*2, NOTE_F*2, NOTE_E*2,
};
And the code to play it looks like:
unsigned long note = composition[i++];
if (note == NOTE_REST)
noTone(SPEAKER);
else if (note == NOTE_SUSTAIN)
; // Don't do anything, just let the current tone continue
else
tone(SPEAKER, note);
It's a bit tedious to type in the notes one by one like that, which
is why I stopped when I did. And as far as I know, the Arduino can
only emit one tone at once -- to play the real 2-part invention,
you either need a second Arduino, or extra hardware like a
wave shield.
Anyway, it was a fun series of experiments, even if none of it
produces great music. You can see the source at
github:
akkana/arduino/music.
Tags: arduino, hardware, music
[
18:54 Mar 02, 2012
More hardware |
permalink to this entry |
comments
]
Thu, 16 Feb 2012
I just got an Arduino
Nano. Cute little thing -- I'm looking forward to
using it in portable projects. But I had one problem when first plugging
it in. It was getting power just fine, and blinking its LED -- but it
wasn't showing up as a USB serial port in Linux. dmesg said things like:
usb 1-3.4: new full speed USB device number 7 using ehci_hcd
usb 1-3.4: device descriptor read/64, error -32
usb 1-3.4: device descriptor read/64, error -32
with several different device numbers each time, and an occasional
unable to enumerate USB device on port 4 thrown in.
A web search found a few other people seeing this problem on Linux
or Linux-based devices, with some people saying that pressing the RESET
button multiple times helps. It didn't for me. What solved the problem
for me was switching cables. The mini-USB cable I'd been using -- which
has worked fine for other purposes, including programming other Arduinos
through an FTDI Friend -- apparently was missing something the
Nano needs for downloading. With a different cable,
dmesg showed a much more civilized
usb 1-3.4: new full speed USB device number 20 using ehci_hcd
ftdi_sio 1-3.4:1.0: FTDI USB Serial Device converter detected
usb 1-3.4: Detected FT232RL
usb 1-3.4: Number of endpoints 2
usb 1-3.4: Endpoint 1 MaxPacketSize 64
usb 1-3.4: Endpoint 2 MaxPacketSize 64
usb 1-3.4: Setting MaxPacketSize 64
usb 1-3.4: FTDI USB Serial Device converter now attached to ttyUSB0
What was wrong with the cable? I did some testing with a multimeter versus a
pinout
diagram. Didn't get a definitive answer, but I did find that on the
cable that doesn't work for the Nano, it was hard to get a solid
connection on the D- (#2) pin inside the Type A connector. But since
that's the connector that goes to the computer end (in my case, a powered
hub), if it wasn't making good contact, I would expect it to show up
everywhere, not just with the Nano. Maybe the Nano is more sensitive to
a good solid D- connection than other devices.
I'm not really convinced. But Arduino's
Troubleshooting
Guide suggests:
"Try a different USB cable; sometimes they don't work."
So I guess they don't know what's special about some cables either.
So if your Arduino Nano doesn't initially connect properly, don't panic.
Try a few different cables (everybody has about a zillion mini-USB
cables lying around, right? If not, here, have five of mine).
The Nano is happily composing random chiptunes as I write this.
Tags: hardware, arduino, usb
[
15:24 Feb 16, 2012
More hardware |
permalink to this entry |
comments
]
Sat, 11 Feb 2012
This is the story of my adventures learning to drive a little toy truck
from an Arduino: specifically, how to drive the motors.
Motor control turned out to be trickier than I expected, and I don't
see a lot of "Arduino motor control for dummies" pages on the web,
so I'm writing one.
My truck is from a thrift shop. It has two brushed motors (about 280-350
size, in R/C plane parlance). It was originally radio controlled.
It has space for 4 AA batteries, nominal 6v, which I thought should be perfect
for the Arduino.
Connecting directly to the Arduino (don't)
First, you can drive a small motor directly by plugging one lead into
ground and the other into an Arduino digital or analog output line.
(Analog output isn't real analog output -- it uses PWM, pulse width modulation.)
Don't do this. You risk damaging your Arduino, either by putting
too much current through it (the Arduino maxes out at 40ma per pin, 200ma
total; a small motor can pull several amps), or from
back-EMF when
the motor stops.
Motor shields
Lots of Arduino-oriented shops sell "motor shields". I bought a
Freeduino
motor shield because I could get it from Amazon and it was cheap.
It's a kit you have to solder together, but it's a very easy soldering job.
The demo code is easy, too. I wired it up to the Arduino, loaded the demo
code, hooked up my Arduino to the truck's onboard batteries, and ...
nothing. Sometimes the motor would twitch a bit, or hum, but the truck
didn't move.
I wondered if maybe it was something about the batteries (though they
were brand new). I tried plugging the Arduino in to the universal AC
power supply I use for testing. No improvement.
At first I suspected that the motor shield was junk because its 1 amp
maximum wasn't enough. But I was wrong -- the problem was the batteries.
Neither the truck's 4xAA batteries nor the (supposedly) 1 amp AC adaptor could
put out enough current to drive motors.
When it finally occurred to me to try
a lithium-polymer model airplane battery (2 cells, 7.4 volts, 500 mAh),
the truck immediately zipped across the floor and smashed into a chair leg.
So motor shields work fine, and they're very easy to use -- but don't
underestimate the importance of your power supply. You need a battery
capable of supplying a fairly beefy current.
But why is that, when the truck was designed for 4xAA batteries?
Well, the 4xAAs can drive the motors, but they can't drive the motors,
the Arduino and the shield all at the same time. If I power the
Arduino separately off a 9v battery, the truck will move. It doesn't zip
across the room like with the li-po battery, but at least it moves.
Motor Driver
So I had a solution. Except I wanted something a little cheaper. A
$20-30 motor shield is fine for a one-time project, but I was also
shopping for parts to teach a summer camp class in robotics. We're on
a shoestring budget, and an additional $20 per team is a little too much.
On a recommendation from Eugene at
Linux Astronomy, who's been
teaching wonderful robotics classes for several years, I discovered
Pololu as a source of robotics
equipment. Poking around their site, I found the
TB6612FNG Dual
Motor Driver Carrier, which is under $8 in quantity. Sounded like
a much better deal, so I ordered one to try it out.
The TB6612FNG comes with headers not yet soldered. I substituted female
headers, so it would be easier to plug in jumper wires to the Arduino
and the male leads from the motors.
Writing an Arduino program for the TB6612FNG is a little more
complicated than for the motor shield. It has two direction pins for
each motor, plus a STDBY pin you have to keep high. So there
are a lot more pins to manage, and when you change motor direction
you have to toggle two pins, not just one.
That'll make it more confusing for the students (who are
beginning programmers), but I've written wrappers like
drive(int whichmotor, int direc, int speed) to make it simpler.
The motor driver has the same power supply issue as the motor shield did:
I can't power it, the Arduino and the motors all from the 4xAA batteries.
Like the shield, it works okay with the Arduino on 9v, and great with
one li-po powering everything.
Electronic Speed Controllers
I also tried using ESCs, the electronic speed controllers I've used
with radio controlled airplanes. You can talk to them using the Arduino
Servo library (there are lots of examples online). That works,
but there are two issues:
- ESCs all have wierd proprietary arming sequences,
so you have to figure out what they are (e.g. run the voltage up to maximum,
hold there for two seconds, then down to zero, then hold for two seconds,
then you're ready to drive) and write that into your code. If you switch
ESCs, you may have to rewrite the arming code.
- ESCs only go in one direction -- fine for driving a truck forward,
not so good if you need to drive a steering motor both ways.
I'm sure ESCs have the same battery issue as the other two options,
but I didn't even try running one off the AAs.
Anyone who has ESCs sitting around probably has beefy batteries too.
Custom H-bridges
All the cool robotics hipsters (cHipsters?) buy H-bridge chips
and build their own circuits around them, rather than using things like
motor shields or motor drivers.
This
H-bridge
circuit by Bob Blick is one popular example.
(Those double-transistor-in-a-circle things are Darlington transistors.)
But a web search like arduino h-bridge circuit turns
up other options.
For driving big motors, you definitely need your own H-bridge circuit
(or an ESC), since all the available motor shields and drivers are
limited to 2 amps or less. For small motors like my toy truck,
I'm not sure what the advantage is. Except being one of the cool cats.
Summary
- For any sort of motor, either use a beefy battery (lithium polymer
is idea, but you need a special charger and safety precautions for them),
or use separate batteries for the Arduino and the motors.
- Motor shields are the easiest and most turnkey option.
- A motor driver is cheaper and smaller, but slightly more hassle to use.
- Use an ESC for big motors that only need to go in one direction,
or if you're already a model airplane junkie and have some lying around.
- Use a custom H-bridge circuit if you're a cHipster or you have a
really big motor project.
Tags: arduino, hardware, robots
[
12:45 Feb 11, 2012
More hardware |
permalink to this entry |
comments
]
Tue, 07 Feb 2012
I've wanted an
Ardweeny
for a long time. It's just so cute -- it's an Arduino compatible
that's barely bigger than the Atmega 328 chip driving it. Plus, it's cheap:
$10 including the chip.
Like most small or low-cost Arduino clones, the Ardweeny doesn't have its
own USB connection; instead, you use an adaptor such as an
FTDI Friend,
which slides onto a 6-pin header on the Ardweeny.
I knew that ahead of time.
One thing I hadn't realized was that the Ardweeny gets its only power
from the USB adaptor. So if you want to use an Ardweeny by itself
with no computer connection, you need a regulated 5v power supply.
Those are easy enough to build (see the
Breadboard
Arduino), but don't forget to allow for that when designing projects.
The Ardweeny comes as a kit that needs soldering -- something that
isn't made clear in the sales literature, though for the price, it didn't
surprise me. I downloaded the Ardweeny
soldering steps (PDF) and got to work.
Easy initial build
The PDF estimates 15 minutes for the construction. The first part,
soldering the 10 components, was a snap, and took maybe 10 minutes.
At this point you can take the Ardweeny and nestle it down over the
Atmega chip, and test it to check your soldering work.
I plugged in my FTDI Friend and the LED immediately started blinking.
Success! (It's nice of them to pre-program the chip with blink code,
so it's easy to tell it's working.) Downloading my own version
of the blink sketch (use the Duemilanove w/Atmega 238 setting,
or atmega328 if you use my Makefile) also worked fine.
The last step: soldering the legs
Except that I wasn't done. The next step of the build is to solder all
28 legs of the Ardweeny directly to the Atmega chip's legs. Scary idea
-- won't all that heat kill the chip? But the instructions didn't have
any warnings about that. I took a deep breath and forged ahead.
This part put me way over the 15-minute estimate -- 28 pins is a lot
of pins, and I took it slowly, careful to be sparing with heat and solder.
When I was finally done, I plugged the FTDI Friend back in and
... nothing. Not a blink. And when I checked voltage on one of the V+
pins versus the ground pin, it measured around 1.5v, not the 5v I
expected to see.
So I'd messed something up. Somehow, even though it worked without
soldering the legs, that additional soldering had broken it.
I went through all the pins with a voltmeter checking for shorts,
and tested everything I could. Nothing obviously wrong.
It might have been nice to inspect my solder joints on the Ardweeny --
but once the Ardweeny is soldered to the chip, the solder is all inside
and you can't see it. But anyway, I'd tested it and it had worked fine.
Detaching the backpack from the chip
So I figured I must have destroyed the chip with heat or static during that
soldering process. My Ardweeny was a brick. Nothing salvageable at all.
Unless -- if I could somehow de-solder the legs and pull the two apart,
I could use the Ardweeny with another chip.
But how do you de-solder 28 legs? I tried a solder sucker (a
pen-shaped vacuum pump) and de-soldering braid, but neither one
broke the bond between the two sets of legs.
I tried sliding an X-acto knife in between the Ardweeny's legs and the
chip's while heating the leg with solder; no luck, the knife blade was
too good a heat sink and the solder never melted.
Dave finally found a solution. With my assurance that the chip was
probably dead anyway, he rolled the Ardweeny on its back, and used
the tip of the heated soldering iron to bend each chip leg inward away
from the Ardweeny leg. When he was done, the chip looked bent and sad,
like a squashed millipede -- but the pieces were separated.
Testing to find the problem
And now I could take the Ardweeny and stick it on an Atmega 328 I
pulled out of another Arduino. Plugged in the FTDI Friend and -- nothing.
Wait, it was the backpack that was bad? But I tested it before doing that
last soldering phase!
I took the sad squashed-millipede Atmega and carefully bent all the pins
back into shape, or at least close enough that I could plug it into a socket
in my Diecimila. And, amazingly -- that poor abused overheated
squashed bent 328 still worked just fine.
Okay, so the problem is definitely in the Ardweeny backpack.
Now that the solder joints were exposed again, I examined them all
and found two that looked questionable. I re-soldered them -- and
everything worked.
Lessons for the Ardweeny
I still don't know why my board worked the first time, then failed after
the step of soldering the legs. But it makes me nervous about repeating
that leg-soldering step. What if something else, something that's
working now, stops working?
For now, I'll probably solder just a few pins -- maybe the
four outermost ones -- and rely on pressure for the other contacts.
Of course, in a real environment where the Ardweeny might be subject
to vibration and temperature changes, that might not be good enough.
But until then, it seems the safest option.
Tags: arduino, hardware
[
16:26 Feb 07, 2012
More hardware |
permalink to this entry |
comments
]
Fri, 27 Jan 2012
When SCALE approved my talk proposal,
Fun
with Linux and Devices, I had a challenge: I needed some good,
visual Arduino demos that would work in front of an audience.
In particular, I wanted something that moved. A little toy truck?
A moving penguin? A rotating sunflower? I fiddled with this and that,
not fully satisfied with anything. And then suddenly I realized what I needed.
Something cool. Something BIG.
Something I'd been wanting an excuse to buy anyway.
An Air Swimmers Shark.
I'd seen these things on video, but never in person. They're available
all over, even on Amazon, so I put in an order there and got a shark
in a few days.
These things are ridiculous and cool. It's huge, about 5 feet long,
and filled with helium. It takes maybe half an hour to assemble.
It has a small motor to beat the tail, an infrared transmitter,
and a weighted receiver that moves back and forth on a track to tilt
the fish up or down as it swims.
Once it's assembled, you can get it filled with helium at a party
store (which costs $3 to $6 depending on where you go).
Once the shark is filled, you add clay as ballast until the shark is
neutrally buoyant, neither rising nor sinking. It's quite sensitive:
you'll find yourself needing to add or remove pea-sized chunks of clay
as the temperature in the room changes, but being a little over- or
under-ballasted doesn't hurt it much.
With its tail beating, the shark really does look like it's swimming
through the air.
My shark is named Bruce, after the mechanical shark used for the movie
"Jaws". My Bruce, I'm happy to say, has been much more tractable than
his famously intemperate namesake.
Okay, now how do we turn this ridiculous-but-cool thing into an Arduino
project?
Hacking the transmitter
There were two possible approaches. First, mount an Arduino directly
on the shark, and let it be totally self-directed. Second, patch the
Arduino into the shark's transmitter and control it from Linux.
I chose the second option, for several reasons. First, I was fairly
sure it would be easier, and less invasive (the shark would still be
usable with manual control). I also liked the idea of keeping the
transmitter as a manual override, in case my control program didn't
work right. Finally, I liked the idea of keeping a Linux machine in the
loop -- the shark would actually be controlled by Linux, not just by
the Arduino.
So the first thing I did was take the transmitter apart (4 Philips screws).
Inside are 4 pushbuttons, for right, left, up, and down, and the circuit
board is nice and simple. Whew -- this might be doable!
Four more screws and I had access to the back of the board, which was
equally simple. Now I could get my voltmeter on the contacts while I
pushed buttons.
It turned out the contacts (indicated with arrows on the photo) on the
downstream side of each switch were normally high (4.5 volts -- the transmitter
uses 3 AAA batteries). When I pushed the button, the contact went to ground.
Okay, so what I needed was some way for the Arduino to ground those
contacts at will.
First I needed to solder some wires to the contacts.
(How do you tell which side of the pushbutton is the one you need to solder?
Well, one side changes voltage when you press the button, and the other
side stays constant. The one that changes is the one you need to connect
to the Arduino, so the Arduino can change it too.)
I figured I needed 6 wires: ground, power, and one for each switch.
(It turned out I didn't need the power wire, but I figured it didn't
hurt to include it just in case.)
I wanted to have a nice small connector on the side of the transmitter,
but I couldn't find any 6-pin connectors that didn't look big and bulky,
so I gave up and decided I'd just let my ribbon cable dangle from the
transmitter. If I got a nice multi-colored one, maybe it would look festive.
I couldn't find any 6-conductor ribbon cable, so I got a
wider one and separated 6 wires from the rest. Then I soldered the
six wires to the appropriate places (marked by arrows in the photo).
On the other end, I tinned the six wires with solder so I could plug
the stranded wires into my breadboard.
Simulating button presses
I've done enough reading to know of three ways to simulate a button press.
You can put a relay between the two contacts of the switch; you can do
the same thing, but with an optocoupler (opto-isolator) instead of a relay;
or you can do some magic with a transistor. I was fuzzy on the
transistor magic bit, so a relay sounded easiest.
I played around with a relay and a spare switch and convinced myself I
knew how to wire them up. Then it was off to my local parts store to
buy four matched relays small enough to fit on my little mini breadboard.
There followed a several-day fiasco wherein I bought lots of relays
that turned out not to be suitable, and got increasingly frustrated at
how large and clunky all the available relays were.
There are smaller ones, but I couldn't get them to work.
And I learned that relays mostly come without documentation on which
pin does which, so there's a lot of experimenting with each new type.
Frustrated, I tried some optocouplers I'd bought on a whim last year.
No dice ... couldn't get them to work either.
Desperate, I turned to IRC, #arduino on Freenode. The folks there are
mostly electronics wizards, and I'm sure my questions must have seemed
very dumb, but they were patient with me, and pointed me toward
a very simple circuit,
LED4dummies,
that was just what I needed. (They also suggested
Wikipedia's Open
collector article, but I found that less clear.)
It took me some
experimenting with a transistor, an LED and a couple of resistors
(I blew out a couple of transistors before I realized I had the R2 resistor
in the wrong place) but eventually I got it working, and felt confident
enough to try it with the real shark transmitter. The key was to simplify
the circuit so it had no extra parts, then once it was working, add more
parts to build it up to what I needed.
At left, the circuit I ended up with. For each button, I have one
transistor and one resistor (I don't need the second resistor from the
LED4dummies circuit, since that was just to keep the LED from burning out).
At right is the circuit assembled on a mini-breadboard on top of the
proto-shield.
Note that the ends of the ribbon cable are plugged in to a spare header I had
lying around; a header makes a passable connector, so I can plug it in
fairly easily right before a talk. The green and blue wires in the back
are going to Arduino digital output pins 3 through 6 (leaving 0 and 1
for serial I/O). The red wires go from the transistors back to the
ribbon cable wires that go to the shark's transmitter buttons.
The software side
Now I could make the shark think I'd pressed a button on its transmitter.
How do I control that from Linux?
On the Arduino side, I wrote a simple program that reads and parses
commands coming over the USB cable. So from the computer, I might send
a line like L 300, and the Arduino would "press" the Left
button for 300 milliseconds. I had already written something like this
for a couple of other Arduino programs. That program is
shark.pde.
On the Linux side, first I needed something that established a serial
connection and sent commands to the Arduino. I wrote a Python class
for that,
shark.py.
That let me send commands from the Python console to test the shark.
Then I needed something more visual, something I could show during a talk.
In particular, the shark doesn't swim unless someone's pressing left,
right, left, right buttons over and over. Of course I wanted the computer
to handle that part.
So I wrote a little Python-GTK application that keeps the shark swimming,
and lets me drag a mouse around to adjust its left/right up/down direction:
sharkwindow.
Purely by coincidence, the week before SCALE, Scott Adams introduced a
roboshark character:
Dilbert, Jan 11 2012.
Nice timing for the debut of my own roboshark!
Sadly, I don't have any photos or video of the shark in action.
But if you're a LWN subscriber, there's an article on my talk
with a couple of great pictures:
Robots rampage (in a
friendly way) at SCALE 10X.
And you can see my slides and notes at
Arduino notes.
Tags: arduino, hardware, robots, radio control
[
13:02 Jan 27, 2012
More hardware |
permalink to this entry |
comments
]
Sat, 12 Nov 2011
Yesterday Dave and I attended a "Robot Hackathon" in Redwood City,
part of a "nerd new year" 11/11/11 celebration.
What a fun event! O'Reilly/Make
generously sponsored hardware, so everybody got an Arduino Uno
as well as a Grid Kit, a couple of sheets of cardboard pre-scored
in a grid to encourage cutting and bending into various robot shapes,
and a couple of motors. Tools were provided -- there were big bins
of wire, soldering irons, glue guns, box cutters and other odds and ends.
People of all ages were there having fun -- lots of kids there with
their parents, as well as adults of all ages and experience levels.
The adults were mostly fiddling with the Arduinos; the younger kids
mostly eschewed the electronics and concentrated on building cool
monsters and vehicles with the cardboard kits. I saw some great models
-- penguins, squid, tanks, cherrypickers, many-legged bugs.
Wish I'd thought to take a camera along.
No instructions were provided, but I didn't see many people looking
lost; there were enough people there with experience in Arduino,
soldering and the other tools who were happy to help others.
I was able to help some folks with their Arduino projects
while I worked on copying a grid penguin model from a nearby table.
There were lots of friendly volunteers (I think they were from Robotics
for Fun) wandering around offering advice, in between building a
cardboard city out of GridKits.
There was even pizza, from host Pizza & Pipes.
I had to leave before finishing my penguin, but it does have me
inspired to do more with Arduinos and motors. I had a blast, both
fiddling with my own projects and helping other people get started
with Arduinos, and I'm pretty sure everybody else in the room was
having an equally good time.
Thanks, sponsors O'Reilly/Make,
Robotics for Fun,
The Grid Kit,
Mozilla,
MS and
Andreessen Horowitz!
Controlling motors from an Arduino
One point of confusion: everybody got their Arduino LEDs blinking quickly,
but then how do you control a motor? I wasn't sure about that either,
but one of the volunteers found a printout of sample code, and it
turned out to be simplicity itself: just plug in to one of the digital
outputs, and set it to HIGH when you want the motor to spin.
There was much discussion at my table over how to reverse a motor.
I suggested you could plug the two motor leads into two digital pins,
then set one HIGH and the other LOW; then to reverse the motor, just
swap the HIGH and LOW pin. Nobody believed me, and there were a lot
of fervent assertions that there was some magic difference between
a pin being LOW and a real ground. I should have coded it up then
to demonstrate ... I wish I had, rather than spending so much time
hot-gluing penguin parts.
Now that I'm home and it's too late, here's an example of how to
reverse a motor by plugging in to two digital outputs.
// Arduino basic motor control
#define DELAYTIME 1000 // milliseconds
int motorPins[2] = { 5, 6 }; // plug the motor leads into these pins
int direction = 0; // toggle between 0 and 1
void setup()
{
pinMode(motorPins[0], OUTPUT);
digitalWrite(motorPins[0], LOW);
pinMode(motorPins[1], OUTPUT);
digitalWrite(motorPins[1], LOW);
}
// Alternate between two directions and motionless.
// Assume we start with both pins low, motor motionless.
void loop()
{
delay(DELAYTIME);
digitalWrite(motorPins[direction], HIGH);
delay(DELAYTIME);
digitalWrite(motorPins[direction], LOW);
direction = !direction;
}
Incidentally, powering robot motors directly from an Arduino is
generally a bad idea. It's okay for testing or for small servos, but
if you're going to be driving a truck with the motors or otherwise
pulling a lot of current, it's better to use a
separate power
supply for the motors rather than trying to power them from the Arduino.
The easy way is to buy something like this
Motor/Stepper/Servo Shield
that plugs in to the top of your Arduino and has its own power supply.
Arduino Uno on the command line
As I've written before, I prefer to do my
Arduino
hacking from the command line ... but I didn't know the settings
needed for an Uno, and avrdude is quite particular about settings
and can't auto-configure anything.
So I ended up using the standard Arduino IDE while I was at the event ...
there was theoretically wifi at the site, but it wasn't working for me
so I had to wait 'til I got home to search for solutions.
Now I've uploaded a new, more flexible version of my Arduino Makefile
with presets for the Uno, Duemilanove and Diecimila models:
Makefile-0022-v3.
Tags: hardware, arduino, robots
[
14:01 Nov 12, 2011
More hardware |
permalink to this entry |
comments
]
Sun, 16 Oct 2011
Debugging Arduino sensors can sometimes be tricky.
While working on my Arduino sonar
project, I found myself wanting to know what values
the Arduino was reading from its analog port.
It's easy enough to print from the Arduino to its USB-serial line.
First add some code like this in setup():
Serial.begin(9600);
Then in loop(), if you just read the value "val":
Serial.println(val);
Serial output from Python
That's all straightforward --
but then you need something that reads it on the PC side.
When you're using the Arduino Java development environment, you can
set it up to display serial output in a few lines at the bottom of
the window. But it's not terrifically easy to read there, and I
don't want to be tied to the Java IDE -- I'm much happier doing my
Arduino
development from the command line. But then how do you read serial
output when you're debugging?
In general, you can use the screen program to talk to serial
ports -- it's the tool of choice to log in to plug computers.
For the Arduino, you can do something like this:
screen /dev/ttyUSB0 9600
But I found that a bit fiddly for various reasons. And I discovered
that it's easy to write something like this in Python, using
the serial module.
You can start with something as simple as this:
import serial
ser = serial.Serial("/dev/ttyUSB0", 9600)
while True:
print ser.readline()
Serial input as well as output
That worked great for debugging purposes.
But I had another project (which I will write up separately)
where I needed to be able to send commands to the Arduino as well
as reading output it printed. How do you do both at once?
With the select module, you can monitor several file descriptors
at once. If the user has typed something, send it over the serial line
to the Arduino; if the Arduino has printed something, read it and
display it for the user to see.
That loop looks like this:
while True :
# Check whether the user has typed anything (timeout of .2 sec):
inp, outp, err = select.select([sys.stdin, self.ser], [], [], .2)
# If the user has typed anything, send it to the Arduino:
if sys.stdin in inp :
line = sys.stdin.readline()
self.ser.write(line)
# If the Arduino has printed anything, display it:
if self.ser in inp :
line = self.ser.readline().strip()
print "Arduino:", line
Add in a loop to find the right serial port (the Arduino doesn't always
show up on /dev/ttyUSB0) and a little error and exception handling,
and I had a useful script that met all my Arduino communication needs:
ardmonitor.
Tags: arduino, hardware, programming, python
[
19:27 Oct 16, 2011
More hardware |
permalink to this entry |
comments
]
Sun, 02 Oct 2011
A recent Jon Carroll column
got me thinking about Making and Fixing.
This was the passage that got me started:
... I took it to Dave up at the repair place. "You need a new
battery," he said. Looked like a fine battery to me, but what do I
know? I had a second opinion from the guy who wanted to sell me a
battery. What could go wrong?
I brooded about this on the way. I realized how much we are at the
mercy of the repair people in our lives, and how much we do not know
about, well, most things.
At their mercy
That took me back. I grew up with the idea that mechanical things
like cars were a little scary, something one doesn't really muck with.
This despite the many happy afternons I spent building little
balsa-wood gliders with my father. Later, I learned a little
electronics, and built little things like a switchbox so my mom could
switch between cable and VCR without unplugging anything.
But knowing I could handle an X-Acto knife and soldering iron somehow
didn't translate to the notion that I could work on anything as
scarily mechanical as a car or a home appliance.
When I was just getting out on my own, my car -- a 200SX turbo, my
pride and joy -- developed a terrible ticking sound. When I got on the
gas hard, it would make this loud tick tick tick tickticktick.
I took it to the mechanic. He listened to the noise and said "Lady,
it's your turbo." He said it needed replacement.
I was pretty sure that wasn't right. I had read the turbo spun at something
like 100,000 RPM. This sound was more like -- I don't know, a few
ticks a second, maybe a few hundred RPM? Shouldn't something spinning
at a hundred thousand RPM (let's see, that's ... divide by 60 ... 1667 Hz),
shouldn't that make a sort of a whine, not ticks?
I asked the mechanic that. He shook his head. "Lady, it's your turbo.
You have to replace it."
I was pretty sure I was being lied to. But what could I do?
As Jon Carroll says, "we are at the mercy of the repair people in our lives."
I arranged for a replacement. The warranty covered part of it; I still had
to pay quite a bit.
And when it was over, the tick-tick-ticking noise was still there.
I'd been right -- the noise wasn't coming from the turbo.
Somehow that didn't make me feel better.
Becoming Kaylee
I saw a movie some time around then -- some awful movie involving
motorcycles, I forget the details -- that had a character I liked.
You've probably seen the archetype -- she's been in other movies.
You know, the girl-mechanic with the grease smudge on one cheek and the
bright eyes. Think Kaylee from Firefly, only this was long before Firefly.
I wanted to be that girl -- the one who never had to put up with
mechanics lying to her, the one who'd never get stuck somewhere.
She had control over her life. She understood the machines.
But how do you even get started learning something like that?
All the guys I knew who knew how to work on cars had grown up in a
culture where they learned it from their father or brothers.
I set a goal: I'd do my own oil change. I found instructions somewhere.
I bought a crescent wrench -- one of those adjustable things --
and an oil pan to catch the oil, and a new filter.
I lay down in the dirt and slid under the car and got the wrench on the
bolt and ... it kept sliding off. I couldn't get the bolt loose,
and I was rounding off the corners so maybe no one could ever get
it loose. Oh no! The instructions didn't say what to do if that happened.
I got in the car, drove to the local mechanics' shop (not the same one
that had lied to me about the turbo) and threw myself on their mercy.
I said I'd be happy to pay whatever an oil change cost, but I didn't
want them to do it -- just please show me how to get the bolt loose.
They were super nice about it. They broke it loose (they said whoever
did it last way over-tightened it). They took a look at my crescent
wrench and told me never to use it again -- that I should stop at Napa
on the way home and buy a 14mm box-end wrench. I don't think they even
charged me anything.
Back at home, armed with my new 14mm wrench, I got the drain plug off,
and the rest of the oil change went smoothly. I changed the filter and
put the new oil in and closed up. My hands were shaking as I drove off --
surely all the oil was going to fall out right away, trashing my
engine forever. But it didn't.
When I got back, one of my housemates was home. He said "You look adorable."
Apparently I had that grease smudge on my cheek -- you know, just like
the girl mechanic in the movie. Maybe there was hope!
And you know what? Once I knew how to do an oil change, I found it took less
time to do it myself than it did to drive to the shop, drop off the
car, arrange a ride home, and all the other hassle associated with
having someone else do it.
Beyond oil changes
Doing my own oil change boosted my confidence incredibly. But I wanted
to learn more. I wanted to be able to fix things when they broke down.
It was around this time that I took up autocross racing. Of course,
a lot of the guys at the autocrosses were great mechanics. I started
asking them questions, picking their brains.
My car still made that tick-tick-tick sound -- I'd pretty much learned
to live with it since it seemed to be this mysterious thing no one
knew how to fix. I asked one of my autocrosser friends.
He said "Yeah, I've noticed you have an exhaust leak. You
should fix that" He said it like, duh, doesn't everybody recognize the
sound of an exhaust leak when they hear it?
What's an exhaust leak? How would I fix it? Turns out it means the gasket
between the exhaust manifold and the head is bad. You have to unbolt
the manifold and pull it back so you can slip a new gasket in. (He showed
me what all those things were so I'd know what he was talking about.)
Normally that would be pretty easy, but on a turbo car it meant
disconnecting all the turbo plumbing and moving the turbo out of the
way. Eesh!
Another autocrosser, an expert mechanic, offered to help.
We did the job. It turned out to be harder than expected.
Seems that previous mechanics, probably the nim-nuts who replaced the
turbo, had messed up the threads in the aluminum head -- and instead
of fixing it right, they'd just taken a stud with different threads
and jammed it in. I learned all about taps, and Heli-coils, and
other techniques that weren't part of the original plan.
And the noise went away. We fixed it right. Not like the shop
that was only interested in screwing another ignorant customer out of
whatever they could get.
Books
I still wanted to learn more, and not be so dependent on helpful guys.
I looked around for books.
Shop manuals and Haynes and Chilton and Clymer manuals all assume you're
already pretty comfortable working on cars. I needed something that
explained things.
I'd been kicking around the idea of getting a car just for autocross --
some older, simpler car that would be easy to learn on. One option
I was considering was a Scirocco, and that put me on to Poor
Richard's Rabbit Book: How to Keep Your VW Rabbit/Scirocco Alive.
It was fabulous. It explained everything from the beginning -- what the
various parts do, how to find them in a Rabbit/Scirocco -- but it was
clear enough that it worked for any car, not just a VW. I inhaled that
book. It was my bible for years, even after I gave up on the Scirocco
idea. I chose a Fiat X1/9 instead.
Colibri
Everyone knows Fiat's reputation. The joke is that it stands for "Fix
It Again, Tony" (though I always preferred "Fix It Alla Time").
A Fiat would surely force me to learn, fast.
My new baby, Colibri (Italian for "hummingbird") was a mess of a car.
It had been in several accidents. Just about everything needed some
amount of work. It was perfect. I loved it.
My first big job was a brake job in the parking lot of a San Diego Pep Boys,
Poor Richard's and the Haynes manual in hand, the store handy
so I could go in and buy tools I discovered I needed, a pay phone
nearby so I could make long-distance calls to my boyfriend when I hit snags.
(We were in the process of moving, but the brake job couldn't wait
until he was there in person -- and besides, I wanted to learn how to
do things myself!)
I was there for hours, and used the pay phone several times. But I emerged
triumphant -- covered in grime, but with brakes that worked great.
Over the next few years of driving and racing Fiats, I learned how to
re-jet a carburetor (and how to do it really fast when a bit of
fluff from your sketchy aftermarket performance air filter clogs a
carburetor jet when you're stuck in traffic on 101 and the car
suddenly isn't getting any power from the primary). I got good at
replacing the alternator,
doing alignments,
working on suspension; I replaced the exhaust system a few times,
and eventually the head.
We don't have to be at the mercy of the repair people in our lives.
Fixing and Making
And that brings me to the Maker movement -- because fixing things,
very often, is making,
and that's something I hadn't realized at first.
I remember watching my master mechanic boyfriend (the one who'd helped
me with the 200SX) faced with
the problem of a pop-up headlight that rattled. The link that held the
light in place was worn from so many years of rattling along potholed
roads. The part was available -- but look at it, he said. This will
just wear out again in a couple of years. There's no lubrication, no
adjustment, no compensation for how the angle changes as the headlight
goes up and down.
He redesigned it using a
rod end --
a lovely piece of hardware that has a threaded rod (adjustable!) at
one end and a nylon-encased ball bearing at the other. It came out
far more solid and adjustable than the original ever was. No more bouncing!
Later, when I got more confidence in my own automotive ability, I
could do some of that myself. My proudest accomplishment was a set of
adjustable spring perches made out of a toilet part from the hardware
store. They cost about a tenth as much as the custom spring perches
the top-flight autocrossers were using, and worked almost as well. I only
wish I'd been prescient enough to have taken photos for a future website.
When you take your car to a mediocre mechanic, like the one who lied
to me about my turbo because he was too inept to recognize the real
problem, you get the wrong idea.
You come away thinking that fixing things is all about
replacing one part after another until the customer stops coming back.
But real fixers aren't like that. They look at a design
and ponder how to make it better. They fiddle with things, and try out
new ideas. If they're not sure what's wrong, they set up experiments,
just like a programmer does chasing a bug, or a scientist testing a new theory.
In today's world,
being a Maker is hot now,
while being a mere fixer isn't held in such high regard. But it should be.
People who fix old stuff -- who can figure out how to take
something broken and make it better than it was to begin with -- not only
are creative Makers, they're also environmental heroes. They're our
best hope to keep us from drowning in a sea of discarded junk.
I'm still not that good at it. I try to fix my computer stuff when it
breaks. I've learned a little
woodworking,
painting, plumbing and other home-maintenance skills from my husband,
who grew up in a culture where most people worked on things like that.
(That definitely wasn't true where I grew up.)
I don't work on the car nearly as often as I used to in the Fiat days --
I have more money and less energy and free time -- but I try to do
enough that I know what does and doesn't need fixing. When I don't
know something (which is still most of the time), I google for help,
and fiddle with things, and invent solutions, and sometimes I succeed,
sometimes not. When I do go to a repair person, I can ask the right
questions, and I can tell if I'm being lied to.
Jon Carroll is right, of course. There's so "much we do not know about,
well, most things." None of us has time to know everything about
everything we own. But that isn't going to stop me from trying. Fixing
is just as cool as making ... and maybe they're the same thing, really.
And I still want to be Kaylee. Maybe I'm making progress.
Tags: hardware, cars, autocross
[
20:34 Oct 02, 2011
More hardware |
permalink to this entry |
comments
]
Sun, 18 Sep 2011
The first time I saw a
Maxbotix Ultrasonic
Rangefinder, I knew I had to have one. My mind filled with thoughts
of bats and dolphins, echolocating. I'm the kind of geek-slash-animal-lover
who, as a kid, used to swim underwater making noises trying to
echolocate like a dolphin.
(I probably shouldn't admit to that. And anyway, it never worked.)
Only in the last few years have I learned that some blind people
actually do echolocate, though not underwater.
But it takes a long time to learn, and not everyone can do it.
Wouldn't it be great (especially if you were blind)
if you could build something you attach to a
hat or glasses? You could walk around hearing pings indicating whether
you're about to walk into anything, or get walked into. How cool is that?
I already had a sonar rangefinder, which I used for a simple
proximity
webcam demo in a talk on plug computing.
With the demo over and the device known to work, I could finally try
making a sonar device.
Clicks in earbuds
I wanted to use earbuds -- no reason everyone else should need to hear
your sonar as you walk around. But how do you do that?
The obvious way works, as it turns out. Connect one earbud wire to
one of the Arduino's digital outputs (via a resistor, to reduce the volume),
the other to ground. Of course
you can connect both earbuds to the same output, or to different outputs
if you want to send different signals to each ear.
Then program the Arduino to set the line high, pause a short time, then
set it low again, like this:
#define EARBUD 1 /* pin number */
#define clicklen 10 /* milliseconds */
#define timeout 2000 /* milliseconds */
void loop()
{
while (1) {
digitalWrite(EARBUD, 1);
delay(clicklen);
digitalWrite(EARBUD, 0);
delay(timeout);
}
}
This gives a short click ever 2 seconds. Once the rangefinder is
hooked up, I'll make timeout a variable and adjust it according
to the rangefinder signal.
I used cheap earbuds: the digital output is sending a square wave and
probably isn't good for earbuds, so don't risk a set you care about.
I had to experiment to find a good resistor value to keep
the volume audible but quiet enough not to be annoying. 10k was about
right for my dollar-store earbuds.
Of course, if you were actually building this device you'd want
to use a potentiometer so you'll be able to adjust the volume as you walk,
or use earbuds that come with one.
One sound-on-arduino page I found put a capacitor inline with the resistor
... to smooth out the waveform?
I tried a 47 uF capacitor, but it didn't make any difference I could hear.
Adding the rangefinder
The rangefinder plugs in just like in my
proximity
webcam project: Power on the rangefinder to 5v on the Arduino,
Gnd to ground, and AN (analog signal) to the Arduino's analog pin 1.
Then I just need to read the rangefinder output and map it to an
appropriate delay between clicks. That took some tuning. Initially
I just made the equation linear, for simplicity, and I experimented
to see when I wanted to hear the clicks getting closer together.
Something like this, added at the beginning of loop():
#define FACTOR 15
#define MINRANGE 20
float range = analogRead(RANGEFINDER);
int timeout = FACTOR * (range-MINRANGE);
Pretty cool -- now I could hear the clicks get really close together
as I put my hand in front of the sensor.
But when I took the device outside, I found sometimes it would stop
making noise for a long time, or even forever.
Some of that was due to an earlier equation I used, where the values
could sometimes be negative. (With the equation I showed above, they
probably won't be -- I've never seen the rangefinder return single
digits.) So I added a minimum:
#define MIN_TIMEOUT 5
if (timeout < MIN_TIMEOUT) timeout = MIN_TIMEOUT;
That got rid of the "stops clicking and never starts again" problem.
But I still had delays that were too long: if you face an open area,
you might have a timeout of 6 seconds, and you could easily turn and
walk into a tree before those 6 seconds are up. So I made a maximum
timeout of 2 seconds: it will never go longer than that between checks.
#define MAX_TIMEOUT 2000
if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT;
Much better! Now I could walk around and -- usually -- get warned before
I got too close to obstacles.
You can grab the source and a Makefile for my test program program at
sonarduino.
It's not perfect. Sometimes it gets a spurious reading from the
rangefinder, and waits too long before warning you. It would really
be better if it continued to check during those long timeouts.
And the rangefinder really doesn't give very reliable results much
beyond a meter and a half. There are other models of rangefinder,
and you'd probably want to experiment with several models before
trying to use one of these gizmos to walk around at normal speed.
You might even want to have two different types of
So this is just a start. I'm not going to give dolphins or bats any
competition yet, and it's certainly not good enough that a blind person
could use it to walk around at full speed.
But it's a fun project, very easy to build, and I'm looking forward
to playing with it further.
Tags: arduino, hardware, sonar, echolocation
[
15:54 Sep 18, 2011
More hardware |
permalink to this entry |
comments
]
Sat, 11 Jun 2011
Every now and then I think it might be handy to have some sort of
display on the Arduino ... something a little more detailed than
an LED that either blinks or doesn't.
Adafruit's 2-line LCD text display comes with a great
Character LCD
tutorial, but it's quite heavy, and includes a backlight I
don't need. I wanted something more minimal.
The local surplus store always has
lots of cheap LCDs, but they unfortunately tend to be unlabeled, so
you can't tell which pin is which.
But the other day I spied a very lightweight little display for $2.95
that actually had a label on it, so I grabbed it, figuring I'd be able
to get the pinout from google. It said:
DENSITRON 2
617ASNG0441
0201 TAIWAN
Alas, googling produced no useful information for any of those numbers.
Foiled again! It might as well have been unlabeled!
Wait -- let's not give up quite so quickly.
Adafruit's LCD
Shield tutorial says most parallel displays have either 14 or 16 pins,
while this one has 15. That's close, at least ... but comparing the
two Ada tutorials, I could see that the pin assignments for the two
displays were completely different even though both were 16-pin.
I wasn't going to get pin assignments there.
Searching for just densitron 15-pin lcd found
lots of displays that clearly weren't this one. But apparently a lot of
them were similar to a display called an LM50. Perhaps mine used that
pinout too.
So I tried it, and it worked with only a little experimentation.
Here's the pinout:
| LCD pin | Function | Arduino pin
|
| 1 | Gnd | Gnd
|
| 2 | +5 V | +5 V
|
| 3 | Contrast | pot
|
| 4 | RS | 7
|
| 5 | EN | 8
|
| 6 | RW | Gnd
|
| 7 | D0 |
|
| 8 | D1 |
|
| 9 | D2 |
|
| 10 | D3 |
|
| 11 | D4 | 9
|
| 12 | D5 | 10
|
| 13 | D6 | 11
|
| 14 | D7 | 12
|
| 15 | (nonexistent backlight)
|
Or I can use the nice cable with the 8x2 connector that came with the
display, which maps to these functions:
| 1 = Gnd | Contrast | RW | D0 | D2 | D4 | D6 |
|
| +5V | RS | EN | D1 | D3 | D5 | D7 |
|
The Arduino LiquidCrystal library works just fine with it, using
this initialization:
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
in the
Liquid Crystal
Arduino sketch.
Works great! I went back and grabbed another $3 display.
So the moral is, even a complete hardware klutz shouldn't give up too easily:
with the right web search terms and a little fiddling, you might just
get it to work after all.
Tags: arduino, hardware, electronics
[
19:25 Jun 11, 2011
More hardware |
permalink to this entry |
comments
]
Mon, 30 May 2011
I've been doing more Arduino development lately.
But I don't use the Arduino Java development environment -- programming
is so much easier when you have a real editor, like emacs or vim, and
key bindings to speed everything up.
I've found very little documentation on how to do command-line Arduino
development, and most of the Makefiles out there are old and no longer
work. So I've written up a tutorial. It ended up too long for a blog
post, so I've made it a separate article:
Command-line Arduino development.
Tags: hardware, arduino, cmdline, programming
[
13:45 May 30, 2011
More programming |
permalink to this entry |
comments
]
Mon, 11 Apr 2011
In the last article, I wrote about how to get a very
simple
webcam demo running on a plug computer, also known as a Sheevaplug.
Okay, a webcam is sorta cool, but it's still a pretty easy thing to do
from any laptop. I wanted to demonstrate some lower-level hardware control.
As I mentioned in the previous article, trying to run hardware directly from a plug
computer is an exercise in frustration.
So what do you do when you want to drive low-level hardware?
Use an Arduino, of course!
Add the Arduino
Happily, the sheeva.with-linux
kernels include the FTDI driver you need to talk to an Arduino.
So you can plug the Arduino to the plug computer, then let the Arduino
read the sensor and write its value to the serial port, which you
can read on the plug.
First I tried a simple light
sensor from Adafruit, using the circuit from the
LadyAda photocell
tutorial.
I wrote a very simple Arduino sketch to read the analog output:
lightsensor.pde.
I'm allergic to Java IDEs, so I compiled the sketch from
the commandline using this
lightsensor
Arduino Makefile. Edit the Makefile to point to wherever you've
installed the Arduino software.
Now, on the plug, I needed a Python script to read the numbers coming in on
the serial line. I ran apt-get install python-serial, then wrote
this script:
readsensor.py.
The script loops, reading the sensor and writing the output to an
HTML file called arduino.html. Visit that in a browser from
your desktop or laptop, and watch it reload and change the number as
you wave your hand or a flashlight over the photocell.
Ultrasonic rangefinder for proximity detection
Pretty cool ... if you're extremely geeky and have no life. Otherwise,
it's maybe a bit limited. But can we use this Arduino technique to
do something useful in combination with the webcam exercise?
How about an
ultrasonic
sonar rangefinder?
The rangefinder comes with a little PC board, and you have to solder
wires to it. I wanted to be able to plug and unplug -- the rangefinger
also has digital outputs and I may want to experiment with those some day.
So I soldered an 8-pin header to the board. (The rangefinder board only
has 7 holes, so I had to cut off the 8th pin on the header.)
I ran power and ground wires to 5v and Gnd on the Arduino, and a wire from
the rangefinder's analog out to the Arduino's Analog In 2. A little
heatshrink keeps the three wires together.
Then I rubber-banded the rangefinder to the front of the webcam,
and I was ready to test.
Use a sketch almost identical to the one for the light sensor:
rangefinder.pde, and its
rangefinder Arduino Makefile.
I used pin 2 so I could leave the light sensor plugged in on Pin 1.
Now I ran that same readsensor.py script, paying attention to the
numbers being printed out. I found that they generally read around 35-40
when I was sitting right in front of it (camera mounted on my laptop
screen), and more like 150-250 when I got out of the way and pointed
it across the room.
So I wrote a script,
proximity.py,
that basically does this:
if data < 45 :
if verbose :
print "Snapping photo!"
os.system("fswebcam --device /dev/video0 -S 1 output.jpg")
It also rewrites the HTML file to display the value it read from the
rangefinder, though that part isn't so important.
Put it all together, and the proximity-sensitive camera
snaps a photo any time something is right in front of it;
otherwise, it keeps displaying the last photo and doesn't snap a
new one. Sample uses: find out who's using your
computer when you're away at lunch, or run a security camera at home,
or set up a camera to snap shots of the exotic wildlife that's
visiting your feeder or research station.
You could substitute an infra-red motion sensor and use it as a
motion-operated security camera or bird feeder camera. I ordered one,
but got bogged down trying to reverse-engineer the sensor (I should
have just ordered one from Adafruit or Sparkfun).
I'm happy to say this all worked pretty well as a demo. But mostly,
it's fun to know that I can plug in virtually any sensor and collect
any sort of data I want. Adding the Arduino makes the plug computer
much more fun and useful.
Tags: hardware, arduino, plug, programming
[
20:23 Apr 11, 2011
More tech |
permalink to this entry |
comments
]
Sun, 10 Apr 2011
I was asked to give a talk on plug computers ("sheevaplugs") at a local LUG.
I thought at first I didn't have much to say about them, but after
writing down an outline I realized that wouldn't be a problem.
But plugs aren't that interesting unless you have something fun to
demonstrate. Sure, plugs can run a web server or a file server, but
that doesn't make for a very fun demo -- "woo, look, I'm loading a
web page!" What's more fun? Hardware.
The first step to running any hardware off a plug computer is to get
an upgraded kernel. The kernels that come with these things can't
drive any useful external gizmos.
I've often lamented how the folks who build plug computers
seem oblivious to the fact that a large part of their potential customer
base wants to drive hardware -- temperature and light sensors,
weather stations, garage door openers, servos, whatever.
By not including drivers for GPIO, 1-wire, video and so forth,
they're shutting out anyone who doesn't feel up to building a kernel.
And make no mistake: building a kernel for a sheevaplug is quite a bit
harder than building one for your laptop or workstation. Some of the
hardware isn't supported by fully open source drivers, and most Linux
distros don't offer a cross-compiler that can do the job.
I covered some of the issues in my LinuxPlanet article on
Cross-compiling
Custom Kernels for Plug Computers.
Fortunately, the sheeva.with-linux
kernels include a webcam driver. That seemed like a good start for a demo.
A simple webcam demo
My demo plug is running Debian Squeeze, which has a wealth of webcam
software available. Although there are lots of packages to stream live
video to a web server, they all have a lot of requirements, so
I settled for a simple snapshot program, fswebcam.
The command I needed to snap a photo is:
fswebcam --device /dev/video0 -S 1 output.jpeg
The
-S 1 skips a frame to account for the fact that my
cheap and crappy webcam (a
Gearhead
Sound FX) tends to return wildly striped green and purple images otherwise.
So I run that in a loop, something like:
while /bin/true; do
fswebcam --device /dev/video0 -S 1 output.jpeg
sleep 2
done
Now that I have a continuously updating image,
I need to run some sort of web server on the plug.
Plugs are perfectly capable of running apache or lighttpd or whatever
server you favor. But for this simple demo, I used
a tiny Python server script:
simpleserver.py.
Then all I have to do is a simple web page that includes <img
src="output.jpg"> and point my computer at http://192.168.1.102:8080
to see the image. Either refresh the page to see the image update, or
add something like
<meta http-equiv="Refresh" content='2'>
to make it refresh
The next parts of the demo added an Arduino to the mix. But this is
already getting long and I'm out of time ... so the second part of
this demo will follow in a day or two.
Tags: hardware, plug, programming
[
21:18 Apr 10, 2011
More tech |
permalink to this entry |
comments
]
Mon, 27 Oct 2008
I wrote in my OSCON report a few months back that I came home from the
conference with an
Arduino
microcontroller kit and just enough knowledge and software to make
LEDs blink. And so it sat, for a month or two, while I tried to come
up with some reason I desperately needed a programmable LED blinker
(and time to play with it).
But it turned out I actually did have a practical need for a
customizable programmable gizmo. One of the problems with
R/C combat
flying is that you're so focused on keeping track of which plane
is yours that it's tough to keep track of how long you've gone on
the current battery. You don't want to fly a lithium-polymer battery
until it gets so weak you notice the drop in power -- that's really
bad for the battery. So you need a timer.
My transmitter (a JR 6102) has a built-in timer, but it's hard to use.
As long as you remember to reset it when you turn on the
transmitter, it displays minutes and seconds since reset.
Great -- so all I need is somebody standing next to me who can
read it to me. Looking away from the sky long enough
to read the timer is likely to result in flying into a tree, or worse.
(The new uber-fancy transmitters have programmable beeping
timers. Much more sensible. Maybe some day.)
I could buy a kitchen timer that dings after a set interval, but
what's the fun of that? Besides, I could use some extra smarts
that kitchen timers don't have.
Like audible codes for how long I've flown, so I can make my own
decision when to land based on how much throttle I've been using.
Enter the Arduino. Those digital outputs that can make an LED
blink work just dandy for powering a little piezo beeper, and it turns
out the Atmel ATmega168 has a built-in clock, which you can read
by calling millis().
So I wired up the beeper to pin 8 (keeping an LED on pin 13 for
debugging) and typed up a trivial timer program,
battimer.pde.
It gives a couple of short beeps when you turn it on (that's so you
know it's on if you can't see it), then gives a short beep at 9
minutes, a long one at 10, shorter one at 11, and thereafter gives
(minutes MOD 10) beeps, i.e. two for 12, three for 13 and so forth.
Fun and easy, and it works fine at the field once I worked out a way
to carry it (it's in a camera bag hanging on my belt, with the beeper
outside the bag so I can hear it).
Fun! It could use better codes, and a pause switch (for when I land,
fiddle with something then go back up on the same battery).
Of course, in the long run I don't actually want to devote my only
Arduino kit to being a glorified stopwatch forever. I have further
plans to address that, but that's for a later posting ...
Tags: hardware, arduino, electronics
[
12:10 Oct 27, 2008
More tech/hardware |
permalink to this entry |
comments
]
Sat, 13 Sep 2008
I turned on my printer to print out a form I needed to mail and it
emitted a nasty high-pitched noise ... not quite a squeal, but almost.
And it refused to feed paper more than about an inch at a time.
Pressing the paper feed button made it roll the paper about an inch
farther down, stop, and squee again. Another press, another inch,
stop and squee. Each time it seemed to advance the paper quite
smoothly -- it wasn't slipping, jamming or feeding at an angle.
How do you google for a weird high pitched noise? I tried a few
phrases in combination with epson c86 OR c84 OR c88
and hit several promising-looking URLs with domain names like
fixyourownprinter.com ... but every hit turned out either to be
someone describing a problem, then the discussion morphing into
a discussion of unclogging ink cartridges, or someone describing
a paper feed problem like mine and someone answering with
unhelpful advice like "you could fix the mechanism if you could
get the back panel off, but that's hard if you're not a printer
repair shop and printer repair shops charge more than the printer
is worth, so throw it away and buy a new printer."
I try to be green -- I recycle, turn off lights, try to use low
power PC and monitor, and I'll be damned if I'm going to throw out
a great big hunk of mostly nonrecycleable plastic every couple years
without at least trying to fix it.
Giving up on web searching, I unplugged the printer and started
pushing and poking at it to see what I could disassemble.
The back cover clearly was tucked into the two side covers ...
it clearly wasn't going anywhere until those side covers came off.
The side covers had several holes to the plastic piece underneath, with
arrows near them seeming to invite "push and slide". But there
didn't seem to be much consistency to whether I was supposed to push
the outer cover, or the inner tab, in the direction of the arrow.
I finally just ignored the arrows and used screwdrivers and pliers
to poke and compress and wedge and slide until I got the left side
cover (left as seen from the front of the printer) off.
The right side cover was more challenging -- I had all the tabs
loose, but the cover seemed to stick at a point near the front, near
the "Dura-Brite" oval. After twenty minutes of attempted finesse, I
switched to trying to force it (since the alternatives were to throw
the printer in the garbage or pay a repair shop more than the price
of a new printer). I heard two sharp CRACKs as of
plastic tabs breaking ... and the stuck front side popped loose.
Curiously, I couldn't find any obviously broken plastic inside; forcing
it was apparently the right and only way to get that side cover off.
Inside ... everything in the paper path looked fine. I pulled out an
errant paper shard that's been floating in there for about a year (I
knew right away when I fed that sheet of business cards with some of
the cards already removed that it had been a bad idea) but it hadn't been
touching any of the mechanism.
What's this on the left side, though? There was a tiny ink-smudged
piece of paper between one of the pulleys and its toothed belt.
Hmm. Doesn't look like it ought to be related, but it clearly
doesn't belong ... so I pulled it out.
I poked and prodded and shone flashlights for a while longer, but
couldn't find anything else. Darn! Well, just for the heck of it, I
plugged the printer back in and switched it on. No squee tone!
Hmm ... I fed it a piece of scratch paper and pushed the paper feed
key ... and the paper went straight through, no noise, no fuss.
Whee! I hooked it up to the computer and tried a nozzle
test (escputil -r /dev/usblp0 -mC86 -u -n) and it seems
fine! The printer is back in its normal place now ... sans side
covers, of course. I figure putting them back on so soon is just
an invitation for the problem to come back. I'll put them back on
eventually ...
The moral of the story is: don't let ignorance stop you from trying
to fix things.
Maybe the problem was that little piece of paper wedged in the wheel after all.
Or maybe, as I often suspect, sometimes hardware just gets lonely and wants
some attention ... and if you're willing to spend an hour dinking with it,
it doesn't matter how little you know about what's actually wrong.
All it really wanted was your attention.
Tags: hardware, printing
[
13:12 Sep 13, 2008
More tech |
permalink to this entry |
comments
]
Mon, 04 Aug 2008
No postings for a while -- I was too tied up with getting ready for
OSCON, and now that it's over, too tied up with catching up with
stuff that gotten behind.
A few notes about OSCON:
It was a good conference -- lots of good speakers, interesting topics
and interesting people. Best talks: anything by Paul Fenwick,
anything by Damian Conway.
The Arduino
tutorial was fun too. It's a little embedded processor with a
breadboard and sockets to control arbitrary electronic devices,
all programmed over a USB plug using a Java app.
I'm not a hardware person at all (what do
those resistor color codes mean again?) but even I, even after coming
in late, managed to catch up and build the basic circuits they
demonstrated, including programming them with my laptop. Very cool!
I'm looking forward to playing more with the Arduino when I get a
spare few moments.
The conference's wi-fi network was slow and sometimes flaky (what else is new?)
but they had a nice touch I haven't seen at any other conference:
Wired connections, lots of them, on tables and sofas scattered
around the lounge area (and more in rooms like the speakers' lounge).
The wired net was very fast and very reliable. I'm always surprised
I don't see more wired connections at hotels and conferences, and
it sure came in handy at OSCON.
The AV staff was great, very professional and helpful. I was speaking
first thing Monday morning (ulp!) so I wanted to check the room Sunday
night and make sure my laptop could talk to the projector and so
forth. Everything worked fine.
Portland is a nice place to hold a convention -- the light rail is
great, the convention center is very accessible, and street parking
isn't bad either if you have a car there.
Dave went with me, so it made more sense for us to drive.
The drive was interesting because the central valley was so thick
with smoke from all the fires (including the terrible Paradise fire
that burned for so long, plus a new one that had just started up near
Yosemite) that we couldn't see Mt Shasta when driving right by it.
It didn't get any better until just outside of Sacramento. It must
have been tough for Sacramento valley residents, living in that for
weeks! I hope they've gotten cleared out now.
I finally saw that Redding Sundial bridge I've been hearing so much
about. We got there just before sunset, so we didn't get to check the
sundial, but we did get an impressive deep red smoky sun vanishing
into the gloom.
Photos here.
End of my little blog-break, and time to get back to
scrambling to get caught up on writing and prep for the
GetSET Javascript class for high
school girls. Every year we try to make it more relevant and
less boring, with more thinking and playing and less rote typing.
I think we're making progress, but we'll see how it goes next week.
Tags: oscon08, conferences, linux, travel, portland, hardware
[
22:00 Aug 04, 2008
More conferences |
permalink to this entry |
comments
]
Sat, 29 Mar 2008
Dave and I were helping out with replacing the keyboard on a friend's
computer. Isn't it funny how keyboards never come with cables that
are quite long enough to go from the front of a desk to the back,
down and around to the computer that sits underneath?
This particular desk has a backboard that makes the cable take a
more circuitous path than most, and when we unplugged the old
keyboard, we discovered that it was plugged in using an extension
cord.
And what an extension cord! It's a PS/2 to 5-pin AT plug
adaptor ... connected to an AT to AT extension cable ... connected
to an AT to PS/2 cable on the other end. Each of the three pieces
is yellowed with age, but to three different colors.
Unfortunately the mass spectrometer is on the fritz again so we
weren't able to establish accurate Carbon-14 dates for each of
the three pieces.
Tags: humor, hardware
[
12:09 Mar 29, 2008
More misc |
permalink to this entry |
comments
]