Hello everybody! Sorry it’s been so quiet over here … I’ve been preoccupied with unicorns.
The last three months have been rainy, indoorish months for me and Portland. Writing books is still my day job, but I’ve also be surprisingly, enjoyably, annoyingly busy with these smart lights. It’s been an educational odyssey: so far it’s required circuit-board fabrication, AVR programming in C and assembler, iPhone hacking, waterjet cutting, lamp design, bicycle maintainence, and lots and lots (lots!) of soldering. I’ve enjoyed it all, but what a time sink! (If only I could flip one of these AVR pins to source time instead of sinking it …)
Something about blinking, glowing light is still compelling to me, but I really do hope that the sun will come out soon and I’ll lose interest in this weak substitute. The goal I’ve set for myself is to have these lights mounted on my tallbike in time for Pedalpalooza, Portland’s three-week bicycling festival. I’ve always wanted ambulance lights on my tallbike, and these should provide the required traffic-shifting pep.
Before I describe what I’ve been up to with these smart lights, let me just announce that “smart lights” is a dumb name, one I’m no longer going to use for fear of it becoming the de facto Actual Name. It makes these lights sound like military ordinance. So I’ve decided to give them the less threatening name of “Unicorn Lamps.” Just like real unicorns, they are delicate, beautiful and slightly pointless. They consume time and emit rainbows. I, a microcontroller virgin, am drawn to their magic.
Having said that, here’s a quick overview of what the unicorns and I have been up to.
At a Dorkbot PDX meeting in January I was introduced to TouchOSC, a toolkit for building Star Trek TNG-style control interfaces on IOS devices, and decided I wanted to use it as my user interface to these lights. Once I design the screens on the mac and sync them to my phone, TouchOSC’s plethora of buttons, knobs and faders can turn my finger taps and slides into messages in the Open Sound Control protocol (aka OSC), which it can send to any host on the internet.
But what host? To make this work, I need an OSC receiver. It has to be a small, light and battery-powered computer with tcp/ip, wi-fi, a serial port and some decent development environment. Probably there is a way to do that with Arduinos, but I’m a Unix guy at heart and I have been saving my trusty iPhone OG for just such a situation.
It took four hacks to make this work. First (and easiest) I had to gain access to my own property, by jailbreaking my iPhone. Not hard. I then installed sshd and some basic unix commands, so I could log in and poke around the operating system.
Next, I had to mate the iPhone’s ttl-level serial port to the rs-485 bus on which the Unicorns frolic. Paul Stoffregen recommended the MAX487 chip for that job, and I designed a circuit around that, built it on perf-board and sealed it in a mint tin.
Since I was hooking to a 12v power source anyway, I added a portion of the MintyBoost circuit (really, just the charger-detection trick) so the iPhone can draw its power from the same source as the lights. The circuit connects to the iPhone through a standard iPhone connector. The one I bought from SparkFun was an incredibly delicate and fiddly little bastard, full of leads thinner than my hair. To protect against breakage, I filled the entire cavity of the connector with hot glue. I also keep the project box and the iPhone velcro’ed togther at all times. It’s kinda ugly, but it works. Any bits I send out /dev/tty.iap are dutifully repeated on the light bus. (BTW, this is also potentially a wireless DMX controller, if any of you DMX people are interested.)
Next I had to reconfigure launchd on the iPhone, so that a thing called “iapd” would quit freaking out about the presence of satanic non-Apple hardware on the serial port. Basically, “launchd” is the OS X equivalent to init, configured by a rat’s nest of XML files in “plist” format, some of which are compiled into binaries so they can’t ever be read by humans. One of those plist files tells the OS to run a daemon that runs another daemon that then speaks some kind of Apple-undocumented remote control protocol on the serial port. I deleted that file, and the port was mine. (In retrospect I could probably have accomplished the same thing with launchctl.)
Lastly I had to work out the complicated Makefile options to let me compile C programs on my Mac that will run on my phone. Most of that is voodoo to me, copied from other projects. The current Developer’s CD is a free download with all the compilers, libraries & headers one needs; it’s mostly just a matter of CFLAGS and LDFLAGS pointing to obscure locations under /Developer/Apple/iPhone/Apple/Developer/iPhone/Etcetera.
(The iPhone kernel as supplied by Apple would also require all my programs to be digitally signed with a developer’s key that Apple would charge me money for. Jailbreaking the phone freed me from that fascist bullshit, and good riddance too.)
With all that finally solved, the iPhone can now launch my custom middleware that uses liblo to receive network OSC messages, translate them into Unicorn and spit them out the serial port. In a pinch, it can also create its own wi-fi network, blink the lights in sync to audio on the built-in mic, text me its GPS coordinates in case of theft, and a million other things. A unix-based smartphone makes a great embedded server! And a bicycle without an embedded server is like a unicorn without a fish … or something.