USB status light(s)

Intro

The request was for a device that can be used to indicate the status of a few different builds and could be controlled easily from python. "Status" immediately implies RGB LEDs, what else? "Easily-controllable" immediately means no custom drivers and no custom HID classes, and no libusb. What does that lead us to? USB-serial. True, there exist chips that do this (FTDI), but then this becomes a 2-chip solution since FTDI chips cannot produce 9 PWM signals. Meh. That is too many chips. A better one-chip solution can be made. As for software, the idea was to make it simple to control. The format I chose is as follows. Each command is a set of eight characters. The first is the RGB cluster to control (0,1, or 2). Next 6 is the color to set it to (in hexadecimal, RRGGBB format, like HTML colors). The last byte is a newline or a carriage return character. This allows one to even use a commandline and "echo" to control the device.

 

Hardware

The one-chip solution is to use an ATtiny461 with a software bit-banged USB stack (the one I used for this particulat project is vusb). The schematic I used is on the right. The diodes drop USB's 5V to about 3.6V, which is a good enough voltage to run the ATtiny and is the signalling voltage that USB expects. We do need higher voltage to drive the RGB LEDs. So the LEDs use USB's 5V directly. A good EE person would be horrified by this schematic, and for good reasons. In theory this is wrong on a large number of levels. In practice it works. LEDs drop enough voltage that the Attiny does not get over 3.6 on any I/O pins. ATtiny's pins also cannot sink over 20mA and, luckily, that is about what we want for LED current. So, overall, this will work fine. I put this circuit together on a piece of perforated board and stuck it into a plastic project enclosure - simple.

Software

The software was easy. At first I expected to find the documentation on how USB-RS232 converters talk, but then I decided to try googling it. Turns out that soneone has already done this. I found a somewhat-working version at www.recursion.jp/avrcdc. I say somewhat, because it mostly worked. I had to make some changes to get it to work fully. The final version of the source code that worked can be found here: [LINK]. I changed it to be more compliant with the spec (8-byte write buffers) and removed a fake RS232 code, since I only needed the data. In theory the device can send data to the PC too, but my current code does not. In linux the device shows up under /dev/ttyACM0. On windows, as a COM port.

© 2012-2024