12:28 am - The Geek, it Burns!
So this all started with a costuming project for someone. It’s sort of fallen by the wayside at present, but I might perhaps still have some use for it myself in the future. It involves addressable LEDs…that is, not just steadily-glowing eyes or whatnot, but things in motion…picture something like the animated light show of the Electric Giraffe, except you can wear it on your body.
I screwed around a bit with doing this with PIC microcontrollers a couple years back, and had a rough working model. Specialty chips for doing this same sort of thing were already available (for driving LED billboards and the like), but they weren’t particularly affordable, didn’t drive many simultaneous channels, and even those that did had all these weird external clocking requirements and stuff. So I did it in code, ostensibly for the aforementioned reasons, but in reality I suspect there was a healthy dose of just wanting to “wave my programmer dick around” and try to impress people, which it didn’t.

48 LEDs the Old Way™: 3 PICs, 48 resistors, etc.I sorta dropped it after that, but some of the blinkenlight displays at the
Maker Faire this year — many of them commercial things that could be bought — caught my eye. Against my better judgment, being kinda on the broke side of things, I did pick up a few of these gizmos to screw around with and see what they’re up to. And some of them, especially the
MaceTech ShiftBrite and
OctoBrite, were just the sort of thing I was after. They work pretty much the same as the thing I’d kludged up before: you string them end-to-end and feed it data essentially as a big shift register, a la SPI; clock, data and then latch to show the new values. Easy. The resulting display is double-buffered and every pixel stays in lock step, perfect for animation. The
ShiftBrite is a single RGB pixel (with 10-bit PWM per channel), while the
OctoBrite gangs up eight RGB LEDs in a line with a different controller chip that can do 12-bit PWM. It was the latter that interested me…there were certain things I needed to know, like realistic bandwidth needs, or dealing with interference or propagation delays when stringing these up…but I only had one OctoBrite to experiment with, and the things are $25 a pop. I really didn’t care about their LEDs — have a supply of those, and would want different physical arrangements anyway — just interested in the controller chip, a TI
TLC5947.
Being a cheap bastard, I requested samples from TI to make a little test rig, and was surprised that they actually sent a few. Things have moved along nicely since the last time I looked at these sorts of things. Still marginally more expensive than PICs, but for signage these do everything but wipe your butt. More channels, no more external clocking needed, and current control for all of the channels is set with a single external resistor (rather than needing a separate resistor, lovingly chosen to match both the LED and supply voltages, for every. single. LED. in. the. system.).

48 LEDs (16 x RGB) the New Way™: 2 chips, 2 resistors.This will happily ingest anything 3.4 volts or better with no change in brightness; current is limited in the chip. 4.5 volts from three alkaline cells, 4.8 from four NiMH cells, 12 volts from a gel cell, whatever…exactly the same output, only difference is the driver chip gets warmer (my power supply only goes up to 17V, but the chip’ll handle up to 35V). Too hot and it goes into a thermal shutdown mode to save itself…still passing along data and functioning as a shift register, just no output until things cool down. But I couldn’t even drive it to this point.
So to answer that propagation delay question…the devices are chained through Cat5 cable, because I already have a bunch of Ethernet cables of various lengths, and couplers to link them with. Went straight for the longest one I had — 100 feet — and it works with only a
very occasional glitch. Yeah. Something working at a more reasonable human scale shouldn’t pose a problem. Consider this One Problem Solved.
And here the story takes an abrupt left turn into something else…
So you see that “Arduino” bit in the photo above? If you’re not a geek (or if you’re a geek but have been living in a cave),
Arduino is a microcontroller reference platform. It’s not the fastest, or the strongest, or the best by, well, pretty much
any metric, but its creators have figured out the Secret Sauce for platform adoption. They’ve taken something that’s traditionally been the difficult and exclusive domain of only the most devoted geeks (the microcontroller), and essentially turned it into an appliance. An appliance for
tinkering. There’s no
single key thing that makes this happen, but host of little parts that all come together to create a cohesive whole. Common base hardware and pinout, free development tools, a lot of useful code libraries, cross-platform support, concise documentation…
One (well okay, two) of the winning, appliance-like things about Arduino is that it’s cheap and self-contained. Most microcontrollers, you need to start with a special external programmer device (often at considerable expense) just to get your code onto the chip. Arduino solved this with two things: firstly, a
bootloader, which is a little stub of a program pre-loaded on the chip that talks to the host computer and helps load your own code into the remaining program space (the part not occupied by the bootloader itself), and secondly, a USB-to-serial conversion chip on the board that handles all the ugly heavy lifting that USB requires, so the bootloader can be infinitely simpler and talk as if it were on a vintage serial port. You connect the Arduino directly via USB, download your code, and — no dongles or clusterfucks — everyone’s happy. What’s more, your own code on the Arduino can also communicate almost trivially over this serial port, passing data to or from a host computer through USB, which is eventually what I’m getting at here…
Sort of reversing that design decision, some models of Arduino now put the USB-to-serial chip on a separate board. Those chips cost a few dollars, and if one’s Arduino project is being put to some standalone use and doesn’t need the communication capability, why spend good money on a chip and USB plug that’ll be used once to transfer some code and then never again? So with these you
do need a little programming dongle…not terribly expensive or anything, certainly cheaper than most dedicated microcontroller programmers…and you can use it over and over again, and save a few bucks on the cost of each Arduino that’s permanently stuck in something.

Different Arduino models; fully self-contained, or with a separate programming header.
Even the programmers come in different shapes. One conceals the USB-to-serial chip inside the USB plug itself!So here’s what’s going on: I’m originally using the Arduino itself to generate the animation sequences being fed to the driver chips. Which is fine and all, and in an actual costume project I’d want something small like that (though maybe something beefier like a PIC32). But this isn’t a costume yet, doesn’t need to be small…and frankly, as much as they’ve tried to make their development tools all nice and stuff, this doesn’t necessarily mean the entire process is a joy. Resource constraints, cross-compiling, downloading the code after each change…I’ve got a perfectly good laptop here, much more pleasant to program, if I could just animate the LEDs straight from
that…Which, in that second picture, is what’s going on. A simple program on the Arduino just shuttles data received from the serial port (from the laptop) out the chip’s SPI bus, feeding the LED drivers. So I can skip all that cross-compiling for the time being and focus on the results, programming and debugging quickly in a much more native tongue. I absolutely
detest corny blip-blip-blip canned animation…I want to work out some flowing, organic stuff, and having an FPU and a couple gigahertz should really ease the early development for such things. Joy and winningness. And everything is rainbows and gumdrops for, oh, maybe five minutes until I run into another problem…
My little test setup has only 16 RGB LEDs. Which is fine, it’s a test, and proved what needed proving. But in an actual project I might want dozens of these LEDs, possibly even hundreds. Thousands? Which is also fine, I just need to send more bits down the line. Even though I don't have the parts for a full setup, being as it’s all just a long shift register I can
simulate the required bandwidth by treating these two chips as the first in a long string of the same, but generate and transmit a full complement of data as if there were hundreds present…the excess bits just drip off the end into a wastebasket (okay, kidding about the wastebasket). And…scaling it up to an imaginary couple hundred LEDs…the frame rate drops to a pathetic chop-chop-chop, entirely inadequate for proper animation.
If the sequences were coming entirely from the Arduino, this wouldn’t be a problem…it can issue SPI data
very quickly, and could easily feed a couple
thousand LEDs at an acceptable frame rate. It’s the whole forwarding-data-from-the-serial-port thing. The fastest
reliable speed I can get through this port is 57,600 bps. Each LED requires 36 bits of data. A couple hundred LEDs, some overhead for all that start and parity bit stuff, and…do the math. Too many bits, not enough tube. Need bigger tube.
Normal people would probably accept the fact that this doesn’t scale well and go right back to writing the animation code to run directly on the Arduino, none of this passing-stuff-along nonsense. But I’m a curmudgeon, and a bastard, and I
really, really like native programming on the laptop. Cross-development makes me sad. So I go on a hunt, looking for something that can forward data from a USB port to an SPI bus…and just as importantly, do it on a Mac. One possibility looks to be using some of the microcontroller programmer devices that I already have (Microchip, Atmel) in a “bit-bang” mode. Which does, in fact work…and I waste a couple days getting code up and running to talk in these modes…only to find out that using them this way is even slower than the Arduino serial port thing.
This now has me looking at other options, like using a variety of PIC chip with USB support built in and using
that to do the forwarding. The speed is certainly there. But even when they provide you with a nice USB framework as a starting point, that doesn’t mean it’s
easy. This
sucks, sucks
hard, and most importantly,
it’s not what I want to be doing. I wanna be coding animation, not wasting a week or two pounding my knuckles with a ball peen hammer, which is sort of what USB is like. So instead I go looking for commercial options. Here’s one now:

A commercial USB-to-SPI interface. This one’s a mere $250.$250?! And that’s at the
lower end as these things go! Just…no. Not gonna happen. I’ll just live with the cross-compiling stuff. Except for, y’know, the curmudgeon thing. So I keep Googling around and following link to link to link while looking for other options, and…
You have got to be kidding me.
You know the thing with Dorothy and the ruby slippers, and if Glinda had just
told her right up front about the clicking-the-heels thing, the story could’ve wrapped up in 20 minutes and avoid all the flying monkeys and crap? Did that kinda annoy you as a kid? It did me. But then, I’m a curmudgeon. But I digress. Point is…the answer had been under my nose the entire time…
That USB-to-serial chip…the one on every single Arduino programmer? Turns out it has a couple of alternate operating modes, one of which is a “bit-bang” mode, something that lets you twiddle all of the chips I/O lines independently and, as it turns out, with surprising speed.

Look familiar? Glinda, you bitch!There are eight bit-bangable lines on the chip, but most of the Arduino programmers only bring out four of them. Fortunately this is just enough lines to control the LED drivers. If you want to get fancy, there are more sophisticated breakout boards for this chip that bring out all the lines, and…I’ll get into that later. For now, check this shit out:

Dude, where’s my Arduino?Feeding the beast couldn’t be simpler. It’s like an 8-channel logic analyzer in reverse. 8 bit-bangable lines. 8 bits in a byte. Create and fill an array representing the state of all the lines over time, issue a write command using the provided library, and the stuff is politely buffered and issued at whatever baud rate is configured. I seem to be getting from 600 to 700Ksamples/second. Allowing that one of the lines needs to be used as the SPI clock for this, that means an actual throughput of about half that…so in practical terms, about 350Kbps-ish. If that’s not enough bandwidth, use one of the breakout boards with more lines, and drive two or more independent data lines with a common clock and latch. The LED drivers need a separate “enable” line as well, but that still leaves free up to five concurrent data lines, or 1.75 Mbps aggregate bandwidth. More than enough for as many LEDs as I could want, at ludicrous frame rates. If somehow this isn’t enough, they make a bigger brother to this chip…that one’s over 10 times as fast, and another story for another time.
So that’s Problem Two Solved.
But there’s another left turn…
As it turns out, those bit-bangable data lines can be
read from as well as written to. Which opens up another range of opportunities…
So yes, Arduino. Tinkering for mortals. Everyone’s doing it. The cat box that Twitters every time kitty takes a dump. The office chair that Twitters when someone farts. What a huge number of these sorts of Arduino projects have in common (aside from the scatological element) is that they’re simply polling some digital sensor and then — through the serial-to-USB connection — request that some process on the host system issue a message or whatever. But it dawns on me that an awful lot of those types of projects — ones involving a host system and not just a standalone Arduino — can do away with the Arduino entirely and
just use the cable! Cron job periodically polls the sensor, updates the web page, whatever. Certainly, yes, a majority of things will still need Arduino capabilities; analog-to-digital conversion, interrupt-on-change, stuff like that, but for a lot it’s simply overkill. I find this kind of hilarious in a way. Must use that for something.
Anyway, I mentioned not particularly enjoying the whole cross-development thing. Like you remember
that I2C hack? That’s the whole reason I did that. And I’ve had some of these other sensors and parts around that I’ve been meaning to fiddle around with, but never really got around to it because I didn’t feel like coding it up on the Arduino and then watching through a serial monitor, when really I just want to see a few numbers and get a feel for what’s coming out of these devices…and this little bitbang thing really makes that much more pleasant.
A few months ago one of the surplus junk places had a pile of these boxes with some kind of encoder knobs on them. They were cheap, and I was pretty sure these were some kind of nice optical encoders that might be good for something, so I bought several of the boxes ($3/ea., 2 knobs ber box). Turns out these were insanely high-end optical encoders, about $125 each new. Had been meaning to hook one up to a PIC or Arduino to see what comes out, but that whole “liver flavor” of cross-compiling and monitoring just sort of kept me away from it. Now it works like this:

Could read two of these with the cable, or four with the full breakout board.That’s all there is. Zero microcontroller coding. Just a few minutes host-side programming and I’m reading a stupidly insanely precise relative position encoder. This could have applications for some kind of X/Y table, or use two of them to create like a monster trackball as a novel interface for an installation of some sort, or who knows what else. Makers and Burners would be saying, “Ooh, IDEAS!” right now.
And then…do you remember the
Rar Box video, where I’d used a glove with small switches on the fingertips and in the feet to trigger sound effects for a dragon costume? That was just sort of a demo/test, but in reality the switches weren’t that practical. They trigger way too easily…clapping, high-fives and so forth. Not good for actual deployment. A couple of folks have been asking for something similar for their own costumes, so one possibility I was looking at is
Hall effect sensors, which are triggered by magnetic fields:

Innit cute?My thought is that these might be used in the fingertips, with a strong magnet in the thumb. But I had some doubts…will these fire off willy-nilly if a magnet gets even vaguely near them? Or the opposite — is the necessary trigger distance too close for thick, fur-covered fingers? What if I want to use two sensors in each finger, one on the nail side and one on the pad of each finger…will both trigger? Are they too close? Yadda yadda what-if what-if. Theory vs. practice. I had to put together a test case…
Now, in actual use these
would be used with an Arduino (that’s what’s producing the dragon noises), and eventually I’d have to interface them there anyway. But at this early stage I just needed to see if I was wasting my time with these things, if they triggered way too easily, or not at all, or whatever. I throw together something on a breadboard, four sensors back-to-back and side-by-side, sort of how they might be arranged on adjacent fingers…

Cough up a few lines of code, and in all of maybe two minutes I have my answer: not just yes, but
hell yes! Better than expected. And yes, I also tested with various combinations of layers of fur, fingers-wedged-between, etc. These should make a couple of
rarsuiters very happy.
So basically, I was playing around with shiny things, and got distracted by
other shiny things.
Way more complex than the simple stuff I've built, i.e., simple PWM setups. :3
Why do I suddenly feel like I am wasting my time? >.>
If it makes you feel better though, maybe the Giraffe needs to Twitter every time Lindz farts or something. Or would that require upgrading everything to faster chips?
BTW on the topic of Lindz' various emissions, did he tell you about when we stopped for lunch on the way back? Or did he not need to tell you, did you feel the shock wave?
Yeah, we need to talk :)
And thanks for pointing out the TLC5947. You may have just solved a problem of mine.
"use the library" ?
You mention that two write the array of bytes to the ft232l chip you just "use the provide library". What library is that? i.e. where can I get the code?
I plan to implement this in Processing....
Re: "use the library" ?
The "D2XX" driver and library can be downloaded from FTDI's web site, or alternately you can use the open source libftdi (similar functionality, but the API is different so it's not just a drop-in replacement).
In either case, you need to disable the Virtual COM Port drivers (the thing that makes the FTDI chip appear as a serial port) if it's been previously installed (e.g. if you're using Arduino, or most USB-to-serial adapters).
Re: "use the library" ?
http://www.ftdichip.com/Projects/CodeEx
This should allow me to use them with processing.
Also since you used the shiftbrites in your demo I was wondering if you could share the simple code you used for controlling them (i.e. the array of bytes you were writing to them etc.)
I am fairly new to this so it would help me to see some examples.
thanks!
Re: "use the library" ?
Regarding pinouts, I'm using the TX pin for latch, RX for blank, CTS for data and then for the clock I toggle both the DTR and RTS lines together. The reason for doing both at once is so this can work with either the FTDI breakout cable or the SparkFun FTDI Basic Breakout (the latter uses a different signal pin in order to auto-reset an Arduino after programming). This particular mapping of FTDI to Shiftbrite pins was chosen as it makes the wiring very straightforward (if using one of the aforementioned adapters). If you're using a different breakout board then it's not necessary to have two clock lines, and you can free one up for something else.
My C code is a sloppy mess at present, so I'll just post a few relevant bits. Here's the pin definitions:
And the number of LEDs in the chain:
#define N_LEDS 5
I'm just using a kludgey fixed-length buffer to hold the output data. Because the data is represented 'sideways' in the buffer (that is, as a bitmap of the state of the output pins over time, not 'packed' in any manner), and allowing for an alternating clock signal, each Shiftbrite requires 64 bytes, and then there's a latch toggle (requiring two bytes) at the end:
unsigned char data[N_LEDS * 64 + 2];
Opening the device should be obvious and isn't reproduced here. Setting the bit mode should likewise be straightforward, but for posterity:
FT_SetBitMode(handle,BIT_CLOCK | BIT_DATA | BIT_LATCH | BIT_BLANK,1);
This sets the port to asynchronous bit-bang mode with five output lines (because BIT_CLOCK is actually two lines as previously described).
Once configured, you might want to set the BIT_BLANK line to disable LED output at the earliest opportunity (to minimize any startup flash). I'm bypassing that step here for the sake of brevity.
Later on, when actually issuing data to the Shiftbrites:
And then, in a loop for each 'frame' of animation, something like:
n = 0; cmd = 0; /* Shiftbrite command to set color */ for(i=0;i<N_LEDS;i++) { r = DO MATH HERE FOR YOUR OWN DESIRED EFFECT g = EACH COMPONENT SHOULD BE A 10-BIT VALUE b = (0 = OFF, 1023 = FULL BRIGHTNESS) /* CCBBBBBB BBBBRRRR RRRRRRGG GGGGGGGG */ val = (cmd << 30) | (b << 20) | (r << 10) | g; for(bit = 0x80000000;bit;bit >>= 1) { if(val & bit) { data[n++] = BIT_DATA; data[n++] = BIT_DATA | BIT_CLOCK; } else { data[n++] = 0; data[n++] = BIT_CLOCK; } } } data[n++] = BIT_LATCH | BIT_BLANK; data[n++] = 0; if((FT_OK == FT_Write(handle,data,n,&out)) && (n == out)) { /* Success */ } else { /* Error */ }Note that I'm setting both the latch and blank bits at the end of the data, and not just the latch. This avoids some unsightly flicker that otherwise happens.
Re: "use the library" ?
Re: "use the library" ?
It's one of Macetech's 12" Shiftbrite jumpers that's been slightly modified to connect directly to an FTDI cable (or SparkFun FTDI breakout) and 9V battery. Okay not quite directly, it still requires a straight 6-pin header to join the two female ends.
On the end that plugs into an FTDI cable: using a jeweler's screwdriver, pry up the clip holding the red wire in place and slide that wire/connector out of the housing. Now do the same for the yellow wire, but re-insert it where the red wire used to be. Likewise shift the green and blue wires down one spot. The order of the wires in the housing should now be: black, white, none (empty socket), blue, green, yellow (the red wire should be left dangling at this point).
On the end that connects to the input of first Shiftbrite in the line: cut the red wire (leaving just a short length), strip and connect to the positive lead of a 9V battery clip. Strip away a small section of insulation on the black wire and attach the negative lead of the 9V clip here (creating a 'Y' connection). Insulate connections.
Not sure how many Shiftbrites can be driven from a single 9V battery (probably not many). But the same general layout would still be used with a beefier power source. Don't try powering from the FTDI cable itself though, the available current is too limited.
Re: "use the library" ?
Re: "use the library" ?
Also in your code in the above example you labelled one pin as "blank", is that what corresponds to the "CE" (enable pin)?
Re: "use the library" ?