ColorNode is a wireless Arduino-compatible microcontroller board designed to replace the stock controller board on GE Color Effects light strings.
ColorNode was inspired by the original controller protocol reverse-engineering effort featured here: Hacking Christmas Lights. That work enabled simple control of each individual bulb of these light strings using just one pin on a microcontroller. The stock controller works nice and the patterns are good, however being able to have full control of the color and brightness of each bulb unlocks the potential for awesome holiday light displays. Hacking these lights is also relatively inexpensive, compared to using other addressable strings or light sequencers on the market.
As I mentioned on my posting for the GE Color Effects Arduino Library, I have been working towards using these programmable strings for my holiday decorations. One issue I had when I was planning out how to install these lights was being able to control and synchronize multiple strings. Each string only needed to be driven with one pin on a microcontroller so technically I could run all of my strings off one board. However, I didn’t like the idea of running a bunch of extra wires to each string from a controller. One nice thing about the stock GE controller is that it has a wireless receiver that works with the supplied remote to cycle the lights between the pre-programmed patterns. Since I would be replacing that controller and supplying my own control signals, I would be loosing the wireless aspect. That’s when it came to me: create a cheap wireless microcontroller board to replace the stock controller and make it fit in the existing little electronics box.
Unfortunately, that last sentence imposes a lot of design challenges, because there are usually trade-offs between cheap and wireless and microcontroller and small. As I was looking for solutions to this design, I knew that the wireless part would be the most expensive part. I didn’t want to re-use the existing module because there wasn’t much documentation about it and I wanted better control over the wireless link. I looked at XBee and Nordic transmitters and others that can be found at SparkFun. Most were either too big or too expensive. There is one, however, that fits both criteria: the RFM12B module from HopeRF. Not only was this wireless module small (16mm x 16mm) and inexpensive (~$6 from SparkFun or ~$3 if you order straight from the OEM), but it is also easy to solder. It gets even better – the stock controller uses a simple receiver paired with a transmitter in the remote. The RFM12B radio is a transceiver, so data can be received and sent from the controller board. Sweet!
Having found a great solution for the wireless radio, the next step was to figure out how to use it. XBee radios are nice because they can just look like a wireless serial port link and there is very little setup necessary. The RFM12B, however, requires more low-level control and configuration to get up and running. It uses a SPI interface for communication along with an interrupt pin to signal receipt of new wireless packets. Being more of a systems guy and less of a software guy, I looked around for existing implementations of this radio.
Eventually I stumbled upon the work of Jean-Claude Wippler who has an awesome design blog and store over at JeeLabs.org and JeeLabs.com. His main electronics design project is called the JeeNode. It is a low-cost, low-power Arduino-compatible board with an RFM12B wireless module interface. He has also developed many smaller sensor and I/O boards that interface directly with the ports on the JeeNode. The greatest thing, from my perspective, is the RF12 software library created for the JeeNode. This wealth of code removes all the complexity from using the RFM12B in the Arduino environment.
It made no sense to reinvent the wheel, so I set out to use the RFM12B radio with the RF12 JeeLabs code in hand. Next step: PCB. I admit I blatantly copied and modified the JeeNode PCB design in Eagle. That’s the whole point of Open Source Hardware anyway, right? 🙂 I wanted to use all through-hole components (besides the radio) so that it could be easily built by anyone or supplied as a kit. Unfortunately the ATmega328 in a 28-pin DIP package is pretty large (I had originally though about using a lower pin-count ATtiny85, but ultimately stayed with the ATmega so I could stay with the supplied libraries and Arduino IDE). I removed all the interface headers and moved components around and managed to fit everything on a board sized for the little plastic enclosure on the light strings. I liked that box because it was nice and small and already had environmental seals to keep out moisture. I run the antenna wire in a small loop around the box instead of coming out to avoid having additional areas I needed to seal.
As you can see from the PCB image and pictures below, the board shape replicates that of the stock controller, down to the holes for the plastic standoffs in the enclosure. You simply tear out (there is some extra epoxy in there for water sealing which makes it slightly more difficult to remove) the stock controller, cut off and strip back the wires going to the lights and the power brick, and solder them in the same positions on the PCB. Both the light strings (50, 36 count) and the yard sculptures (santa, tree, snowflake, etc.) share the same circuitry and electronics box, so it should work in most (if not all) of the Color Effects products. For the PCB manufacturing, I used the DorkbotPDX board service as I have for several other boards now (previously reviewed here) with good success.
This brings me to the name: ColorNode. Since this project is based so heavily on the JeeNode design and RF12 libraries, I decided to call it (with JCW’s permission) ColorNode. Leveraging the JeeLabs hardware and software designs enabled me to quickly design and prototype this project. It is really just a stripped-down clone of the JeeNode with the sole purpose of functioning as drop-in replacement for the stock Color Effects controller. As I said earlier, I wanted to take advantage of the existing enclosure and I didn’t want to run extra wires all over the place. Now I can just run my light strings as normal and not have to worry about any other connections.
Like the JeeNode, the ColorNode is based around the Arduino design but runs at 3.3V instead of 5V. The RFM12B module is only 3.3V tolerant so this was a necessary change. The ColorNode is programmed like the JeeNode or Arduino Pro-type boards where the USB-to-Serial converter is separate from the PCB and connects to a six-pin programming header. I use the USB BUB II from Modern Device (also a US distributor for the JeeNode) as my programming interface. This is similar to other FTDI-based USB-to-TTL adapters, except I like the way I can switch the supply and logic voltages with jumpers. I need to power and program the ColorNode at 3.3V instead of 5V to avoid damage to the RFM12B radio which shares the same power connections. I program the Atmel chips with the standard Arduino bootloader and download code to it using the Arduino IDE set to Pro or Duemilanove w/ATmega328. There are very few parts because I wanted the assembly cost to be as low as possible (~$10 in larger quantities). You can find the bill-of-materials here: BOM and the Eagle PCB design files here: ColorNodeV1. If you want to have the PCB manufactured, here are the Gerber files: ColorNodeV1.0 Gerbers. It is a two-layer board and the size is 1.82″ x 1.42″.
With the hardware designed and tested, I’ve moved on to the software. I have created two pieces of software for this project – code for the node itself and code for a controller board. I am using a JeeNode for a controller, which sends wireless commands to the string nodes to set patterns, colors, sequences, etc. I use my GE Color Effects Arduino library for the basic string control. The nodes each have a Node ID established so that the controller can either address an individual node or all at once using a broadcast message. Since the RFM12B radios are transceivers, I use ACK messages to signal back to the controller that a command has been successfully received. The controller will re-send several times if it does not receive an ACK. This method results in very reliable communications, more so than with just a simple transmitter/receiver pair. The code is still a work-in-progress, but I have the basic wireless communication done and mostly debugged. I just need to add some more light patterns to the node software and define light show sequences in the controller. Once I get the software to a stable state I will post it here.
Update: 26 November 2011
Here is the current code I am working with: ColorNode Code. I used the G35Arduino library which was created off of my GEColorEffects Arduino Library. It has some nice programs in the examples which mimic the stock controller. In order to not have to mess around with the timing of the delays, I modified the G35 library to use the DigitalWriteFast library. By hard-coding in the pin number for the LED string output, I was able to achieve the 2-cycle latency I wanted and then I could simply use the correct 10, 20, and 30 μs delays necessary. I am able to get reliable flicker/error free string lighting with this code. I think it has been updated since I grabbed it (November 20th) so it may have more/better features.
I also made a modification to the RF12 library to have the rf12_easySend function retry much faster (10ms versus 1s) and increased the retries up to 10. I found that, as long as the controller and nodes are within range (~50-100′ as implemented) the command will be received reliably using this method. Also, with the retries happening so fast, if one or more nodes doesn’t properly receive the command on the first try, it will on one of the subsequent retries and it will appear nearly simultaneous. It’s at least good enough for synchronizing multiple strings.
I don’t have a good interface yet for controlling the light programs/colors/etc. but it is all based on serial commands to the controller or the node PCB itself. It’s all spelled out in the Arduino code and a list of options/commands is displayed in the terminal window when connected. I’d like to connect the JeeNode I’m using right now to my home network (maybe with this?) and run a web server on it so I can control the lights from a web browser. That’s next on the To Do list…
The code is not perfect, but I had to baseline it so I could program the nodes and hang up my lights. I’ll be watching the development of that G35 library and I hope more people get involved and add features, like new cool light programs. After this season, I’ll re-visit the code and make any upgrades so the show is even better for next year.
Update: 1 November 2012
I am in the process of converting last year’s ColorNode software to the latest versions of the G35Arduino library and the JeeLib library. The new code will be compatible with Arduino 1.0+ and I plan to put it up on GitHub. For archival purposes, here is the code I ran last year for my light display: ColorNode Xmas 2011. Note that I used version 0022 of the Arduino IDE last year so you would need that version to use the 2011 code.
Update: 20 November 2012
Here is a new version of the ColorNode code which is compatible with the latest JeeLib library and Arduino 1.0.1: ColorNode2012 I was going to use the latest G35Arduino library or the G35-MEO-Programs one, but I decided to just hack it all with my old G35 library (also in the .zip). Most of the G35Arduino programs (StockPlus) and some of the MEO Programs (Rainbow, Sine Wave, Chasers) have been integrated. I couldn’t figure out a good way to leverage the patterns from both libraries so I just pulled them into the main node program code.
One other new thing is that I implemented a new node program (String Controller) which allows one node to transmit a sequence of commands/programs to other nodes while also setting its own lights to match synchronously. This should help for those who do not want to have a separate central controller. Like last year’s controller program, I have a sequence of commands that get sent/used every 30 seconds. I have it running through all the loaded patterns right now but I may remove some that don’t look so great (random colors/patterns are hard to synchronize…).
In the zip is also a tree sculpture node program if you have one of those. I created some basic patterns to make it look like a tree with lights/ornaments. Along with this I changed up how the broadcast messages are sent. I had it setup where all nodes respond to a command when the node ID is 255 (0xFF in hex). However, I realized that I may want to sometimes just have the tree (or a snowman or snowflake sculpture) doing a more static or custom pattern while the rest of the strings go through patterns. To do that, I have a sort of ID mask (like a netmask in a way) where the strings will respond to nodeIDs of 254 or 255 but the sculptures only respond to broadcasts with 255 (and obviously when directly addressed). This way I can set the sculpture up and sync the rest of the strings by sending messages with node ID 254 while the sculpture doesn’t change.
I still have some cleanup to do on all this but I need to get my lights on the house ASAP so I am calling this good enough. Also, I took a quick look at possible improvements to the hardware layout. My ColorNode GitHub repository contains a new layout with an LED added, additional pins broken out, as well as a different power supply capacitor footprint. I am hoping to have this stocked (PCB or PCB kit with components) in a shop like Modern Device in the future and this change helps leverage their existing component inventories if that were ever to happen.