"Indictron" (You might guess that I like to come up with goofy code names for my projects) is a device I use to monitor the status of the continuous integration servers for some projects I've worked on. It's a USB powered grid of LEDs run by an Atmel ATmega88 processor. The device is controlled by a Windows application that queries the build servers for the status of various projects and then sends commands over USB to the AVR chip.
I should take a moment here to say that I am not at liberty to say for what "build projects" I actually used this, so some details or pictures may be altered/redacted.
I'm using Cruise Control .Net to monitor builds. I'm a giant fan of Continuous Integration, as is anyone who has ever worked with it. In a nutshell, Cruise Control orchestrates code builds or other long running processing that is subject to frequent changes by a lot of people. If anyone changes something that breaks the build, it's the job is the Continuous Integration server to find it and report it before the breakage affects everyone else.
Cruise Control comes with a tool that has a windows tray icon that will change to reflect build status, and give pop-up notices when the status of a build changes.
Motivation:
My original idea for came when I was doing some work maintaining some build servers running CC.net. I was aware that the CCTray app, as it is called, has some X10 device capabilities/plug-ins. I had discussed with another developer how cool it would be to have a large stop lights reflecting build status (there are several such projects out there on the web). I never really explored it much, it was more of one of those "wouldn't it be cool if.." type discussions. I also have a policy with my hobby electronics that I stay away from mains/AC power, or anything else with potential to kill me.
I got the idea one day that I could make a device that would be smaller in scale, but would be something I'd use every day, and something that would be much more noticeable than CCTray. I had also read about V-USB, and thought the idea of making something that interfaced to a PC was something I wanted to take a crack at.
Implementation:
My goals were:
- Cheap
- Easy to make, aesthetics were a low priority, I really wanted it to look geeky/homemade anyways.
- Quite limited in scope, I wanted it to be a project I could finish in a short amount of time. There were a million other features I could have added, but I'd probably still be working on it today.
- Use whatever tools and libraries I could to make it easier. On some projects, I like to try make the code and design 100% mine. Other times, I just want to 'get it done'.
The basics of design were:
- Four rows of LED's, one row to a project
- Each row had 4 LEDS to represent the status for that project, mirroring the color codes used by CCTray:
- Red - Last build failed
- Orange - Build in progress, last build broken
- Yellow - Build in progress, last build succeeded
- Green - Last build succeeded.
- Wooden frame for easy construction
- Use printed paper labels on the device to label projects on the device. (I really wanted to use an LCD display, but it would have doubled the complexity of making the thing, if I ever make a V2 it will have an LCD)
- powered by the USB port, using a couple of 914 diodes as poor man's regulators to run the whole thing ~ 3.5V.
- I just made up vendor and device ids for my device, its for my own machine, so I take my chances!
Here's a crummy shot I took with my cell phone camera, you can see one of the projects is broken, and another is building.
In this bad picture, Indictron in action. |
On the PC side, I used lib-usb-win32 to talk to the AVR, which I wrapped lightly with C++/CLI to make a .Net wrapper for it which was in turn used by the main application written in C#.
I use a .Net assembly directly out of CCTray to do the talking to the build servers. Just for fun, I mimic the LED status on the Windows side. I also use an USB connectivity indicator that was useful in testing my communications code, it glows red when the device is not connected.
In addition to just turning the LEDS on and off, the device can blink the lights in certain patterns to convey addition information. The windows app keeps track of how long a build takes, and uses that to estimate how long the build will take next time. I'm pretty sure this is how the CCTray application calculates ETA's, I couldn't find any statistical information in the exposed functions of the CCTray remoting lib. When a build is is estimated to have less than 5 minutes lest, I slowly blink the LED. My AVR code has timing and blink logic built in so, I didn't have to constantly send data over USB to blink a light. Also, Cruise Control allows someone to "Volunteer" to fix a broken build, and CCTray reflects that in the build status. I toggle the green LED off and on when my Windows app detects such a volunteer. Because I wired each row of LEDs in parallel to a single current limiting resistor, the lower forward bias of the green LED gives the effect that whatever other LED is on will shut off when the green is on.
I use a .Net assembly directly out of CCTray to do the talking to the build servers. Just for fun, I mimic the LED status on the Windows side. I also use an USB connectivity indicator that was useful in testing my communications code, it glows red when the device is not connected.
In addition to just turning the LEDS on and off, the device can blink the lights in certain patterns to convey addition information. The windows app keeps track of how long a build takes, and uses that to estimate how long the build will take next time. I'm pretty sure this is how the CCTray application calculates ETA's, I couldn't find any statistical information in the exposed functions of the CCTray remoting lib. When a build is is estimated to have less than 5 minutes lest, I slowly blink the LED. My AVR code has timing and blink logic built in so, I didn't have to constantly send data over USB to blink a light. Also, Cruise Control allows someone to "Volunteer" to fix a broken build, and CCTray reflects that in the build status. I toggle the green LED off and on when my Windows app detects such a volunteer. Because I wired each row of LEDs in parallel to a single current limiting resistor, the lower forward bias of the green LED gives the effect that whatever other LED is on will shut off when the green is on.
Below is a screen shot taken of the Windows App taken when the above picture was taken. I don't reflect the blinking status of the light on the Windows side. I was afraid it might needlessly steal CPU time from an app I run minimized 99% of the time anyways.
The Windows App UI, done in WPF. |
The general information flow of build status goes something like this, albeit bit simplified:
Build status information flow |
I also encapsulated a light manangment system into a .Net library, so the front end and other test programs really only make calls to "turn red light 01 on" or "blink green light for 0.3 seconds on and 0.25 seconds off". This will also come in handy if I find a cooler use for the device one day.
The way that the two sides communicate is just by sending small USB "HID" request with small payloads, of up to 8 bytes. The payload would contain parameters for the commands, for instance, if I want one of the lights to blink, I would send the "blink light" request with the on and off times as parameters.
Here's a shot of the back showing the awesome rats nest, and you can barely see it, but I use stacks of metal washers as stand offs for the board mount.
Solder, perf-board and hot glue, oh my! |
Also each row of LEDs share a current limiting resistor. I did this more to simplify the wiring than to save a few cents on extra resistors. Within a row, no two resistors are supposed to on at the same time. A side effect of this arrangement is that the brightness of the different colored LEDs varies somewhat, due to different LED colors having different forward bias voltages. The green ones are the brightest, and they are almost retina searing.
You can also see the 6 pin ISP/debug connector, I started physical construction when the code was about 75% "done", so this let me debug it and tweak it. I used just about all available I/O pins on the AVR, including the ones normally used for ISP. I had a #define to disable IO to the row of LED's that were shared with the ISP lines when I would do frequent updates.
You can also see the 6 pin ISP/debug connector, I started physical construction when the code was about 75% "done", so this let me debug it and tweak it. I used just about all available I/O pins on the AVR, including the ones normally used for ISP. I had a #define to disable IO to the row of LED's that were shared with the ISP lines when I would do frequent updates.
you made hack a day. post code! http://hackaday.com/2011/04/12/led-build-monitor-helps-keep-an-eye-on-your-servers/
ReplyDeleteSounds like something used by a judge, jury, or lawyer... Maybe you were going for "Indicatron"?
ReplyDeletehttp://en.wiktionary.org/wiki/indict
Still, it's a great idea and top-notch execution.
I'm curious, though... what is the function of the grid of brass "dots" (screws?) on the left side?
Heh, you're right. I only really used "Indictron" as a "code name" when I was developing it. I think it came from early in the project when I was staring at the "New Project" dialog in AVR Studio, and I had to think of something to call it.
ReplyDeleteThe brass dots are screws that hold the labels and "laminate" plastic in place. The picture where the lights are on shows labels (that I blurred out) being used.
Wow..i must try it.
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDelete