Jay discovered this blog entry by a fellow Christmas hacker going by “Darco” the other day and pointed me to it. We both felt the potential for hacking this thing together with an Arduino and my Light Sequencer Program, EverSequence, was pretty cool, so we ran over to Costco and bought two strings each. (Unfortunately, one of Jay’s conked out shortly after he plugged it in and then they were sold out – oh well, he can probably get a new one for half the price next season :-)
Anyway, Darco has reversed engineered the protocol that drives these things and blogged about it. Another guy, Scott Harris, also ported his Atmel driver code to the Arduino and posted it here. Well, since I already have my now-much-improved Sequencer driving an Arduino to control the LED’s on my Christmas Light Suit, adding a little support for colors, dimming, and a plugin to control the G35 through an Arduino was not a huge leap.
First, I modified Scott’s code to accept a simple protocol that I will send via USB serial port from the plugin for my Sequencer. The protocol involves sending 5 bytes in a single command packet to set bulbs at address X to a given intensity:
“.” is ascii period character,
X is a byte representing the light number to address (between 1 and XMAS_LIGHT_COUNT),
I is a byte representing intensity (usually 0xCC), and
RGB are bytes representing red, green and blue intensity levels (between 0x00 and 0x0F)
So, “2E 00 CC 0F 0F 0F” would turn all bulbs assigned an address of 0x00 bright white. The Arduino code is here. As specified by the G35 protocol, at startup the bulbs must each be enumerated consecutively and assigned a bulb address. Normally, Darco and Scott’s code assigns addresseses 1-50, but in my case, I want many bulbs to be addressed by one Sequencer channel, so I modified the code a bit. I set XMAS_LIGHT_COUNT lower – to 5 in my case – which causes the init routine to use addresses 0x00 through 0x04 and assign the same address to every 5th bulb. This way I reduce the number of commands I have to generate, but can still easily produce chaser patterns or turn all bulbs to a given color level with only 5 packets. I also set the serial port to a high baud rate, 115200kbps, for lots of throughput.
This protocol is easily tested once you load the code into the Arduino by editing a file using a hex editor to put in a 5 byte packet, then using a terminal program like Hyperterminal to send the file to the Arduino. I cut the middle (data) line coming out of the controller on the G35 string and put a earphone jack inline. Then I connected an earphone plug to ground and Digital-Out-4 on the Ardiuno (which the protocol coverter software uses as the out pin). That way, I can plug the Arduino in and use it – or revert back to the out-of-the-box controller.
Next, I wanted to take advantage of the dimming abilities. To date, EverSequence only supported on/off, since it was only driving relay boards and simple on/off triacs on my light suit, cape and scepters.
Fortunately, I’ve kept the code design on this thing relatively clean (after a couple of refactorings), so enhancements like this are not too overwhelmingly difficult. After an evening or two, I had basic dimming support added, with the ability to set a color, and ramp-up and ramp-down rates settable via sliders. I wrote a new Sequencer driver plugin to talk to the Arduino running the protocol conversion code. This was quite easy, since I’d already written one to talk to the Arduino for the light suit setup.
The biggest enhancement to the code was ramping up or down (dimming). I did this using two .Net System.Timers that fire at (roughly) 25 millisecond intervals during the ramping periods, sending packets with the corresponding intensities. So, for example, a ramp-up that lasts .4 seconds results in 16 packets being sent, each 1 increment brighter. I had some initial trouble getting it to work, until I realized my stupid mistake – a cut and past error had me using no parity, instead of even. Also, I found that when I had controls on more than one channel firing, the bytes they each sent were getting jumbled up, resulting in completely wacky behavior. That was easily fixed by synchronizing the serial buffer send code, sendBuf(byte). Once that was done, it pretty much worked like a charm! It’s still a bit glitchy, as others have commented generally regarding the G35, but it works more than well enough to have a lot of fun with.
One more enhancement I want to make to the Sequencer is to support “fading down” to a
color other than black, permitting a cross-fade from one color to another. After that, I’ll post the latest program, as well as my plugin code. Here is video of EverSequence running a simple pattern and driving the string through an Arduino Uno.
Andy Coulson (aka AustinLightGuy)