Reading through the recent comments on my ColorNode project, it is clear that I wasn’t clear enough with how I used the hardware from a software perspective.  Most of the software is based on the RF12 examples from JeeLabs.  I took the RF12 Demo example and used/modified that for serial console control on both the controller and the string nodes.  It implemented a nice menu system and I expanded that to send the different ColorNode commands as defined by my command packet structure.   During development, I used that with a JeeNode attached to my laptop via a serial-to-USB converter as the controller and running the controller software.  This also allowed me to print different debug info to the serial console so I knew if different nodes were receiving my commands or not.  I eventually implemented an automatic pattern/sequence loop on the controller to cycle through different effects, as can be seen in the video.  Other users may want to keep the controller connected to a PC and send it serial commands to sequence according to some other software sequencers, which could enable synchronizing the lights to music.  I didn’t get there this year but maybe next year.

As far as libraries and the Arduino IDE is concerned, I slightly modified both the G35 library and the RF12 library and did all my development with Arduino version 22.  When you are ready to download, select one of the ’328 boards @ 16MHz such as the Arduino Pro. For the G35 library, I used the digitalWriteFast.h macro to enable microsecond-accurate delays for the string protocol.  Unfortunately, I couldn’t figure out how to make that work without hard-coding the ColorNode output pin into the G35 code, so it isn’t very universal for compatibility with other Arduino (or Arduino-compatible) boards unless you always use digital pin 19 or change it to match your configuration.  The plus side is that, with the accurate delays, I get absolutely zero glitches – no stuck/flickering bulbs or wrong colors or random bulbs lighting.  For the RF12 library, I have been using the rf12_easySend() function since it auto-retries.  It is intended to be used with ACKs so it knows to re-send the packet until it receives an ACK from the destination or gives up after 8 retries.  My nodes are programmed to not ACK when they are commanded via a broadcast message (node ID 255 – see examples below) so I hacked the timeouts and retries to be 10ms and 10, respectively, to very quickly re-send the packets and stop after 10 times.  Originally, this was 1000ms and 8, but I found that the radio could be used much faster and if one or more strings didn’t receive the packet the first time, they all would after 10 retries over 100ms.  This meant that all strings were synchronized to 1/10 of a second at worst case. If you are addressing one node at a time, the destination node will send an ACK when the command packet is received. The controller code will only retry 10 times if it never gets an ACK, otherwise it will stop once the ACK is received.

Here are some serial command examples:

If you are connected to a node via serial and enter “3,0,12,15,0,0,204,0,10 l” into the serial monitor (without the “”) this equates to Fade,start at bulb zero, end at bulb 12, red value 15 (max), green value zero, blue value zero, go to max intensity (0xCC in hex or 204 in decimal),use option 0 – fade in, step up the intensity once every 10ms. So, in other words, bulbs 0 through 12 would fade in from black to bright red in about 2 seconds.  The l at the end basically indicates that it is the light command, versus entering just an o which turns off everything. No other parameters are necessary for the off command.

If you are connected to a node/JeeNode programmed as a controller and enter “4,25,49,15,15,15,100,1,100,255 l” this equates to Chase, use bulbs 25, through 49, red max, green max, blue max (results in white), half-intensity, use option 1 – chase down, step through the bulbs every 100ms, send the command to all bulbs (255 = broadcast). So, in other words, the lights will be a dim white and chase down from bulb 49 to bulb 25 in 100ms steps (total time would be about 2.5 seconds) and all nodes listening to the controller would run this command. The l and o commands are the same as in the node software, except you can choose which node (or all) to turn off using the o command – “255 o” would turn all strings off, “5 o” would only turn off string 5. If you want to address one node in particular, you would replace 255 with your node #.  I don’t have a way right now to command anything other than all nodes or only one node.  However, the commands are sent so fast that if the code was written to send a command to one node and then immediately after send it to another node, they would only be off by max 200ms (assuming it took 10 retries for node 1 and another 10 retries for node 2).  If node one ACKed after the first packet and the second node did the same, then they would be synchronous within ~20ms.

One last note about the command structure – since I force retries when addressing the broadcast node (255 = all listening nodes), I have it setup to ignore any subsequent command packet that is exactly the same as the previous.  I did this since the strings would sometimes get glitchy if the same light command was issued over an over again which would be the case if one node successfully heard all 10 retries.  The downside of this is if you want to run the same white chase down command over and over again, it would only work the first time.  The nodes would see that the new packet is the same as before and assume that it is due to retries and ignore it.  In this case, you would want to issue an off command at the end of the sequence before sending the same command.  This limitation only exists when sending commands wirelessly via the controller.  If you program the same chase down sequence into the node software and have it loop, you can send the command to choose that particular Program (mode 1) number, then it can chase over and over again.  I like using the pre-programmed sequences on the nodes better since you have much more control over individual bulb timings which allows you to make much more complex patterns than what can be accomplished via the command modes (Fade, Chase, Random, etc.). You are just kinda stuck with the programs on the nodes once they are programmed, sealed up in the box, and the strings hung up.

Attached is a .zip file with the code I used this past December for the video.  It includes the Node software, Controller software, and modified libraries.  I am glad that so many people are using the ColorNode hardware/software platform to control the GE Color Effects lights.  Keep the comments and questions coming – I’ll try to address them as I can.  Please post links to project pages or any videos of the lights in action so others can see what cool things people are doing with these lights.  Thanks!

Code file: ColorNode Xmas 2011

Here is a video I recorded showing GE Color Effects lights installed on/around my house: ColorNode Demo on YouTube It illustrates how different light effects can be synchronized via a central wireless controller and using my ColorNode boards. I used mainly pre-programmed light patterns running independently on each node, with all the strings starting at the same time. The first several cycles use direct commands from the controller, where each change is another wireless payload. The light show isn’t particularly exciting, but it is neat to see everything synchronized so nicely!

I posted my current ColorNode code on the ColorNode project page. I admit it’s not great but it is working well and the lights look great on the house. I’ll have to take a video once the weather is better. I can’t really change anything at this point, so any improvements will have to wait until the lights come back down.

I am a big fan of the Arduino environment because of its simplicity, ease of use, and user community.  I like to use it for many of my projects so this means I must design around the Atmel ATmega MCUs to be compatible with the IDE. When you get a new commercial Arduino development board, a bootloader is already programmed on the chip.  This bootloader enables the IDE to download code over the serial port on the device rather than through the SPI interface. When you click the Download Code button on the IDE, the ATmega is briefly reset, and the bootloader code runs looking for indication that new code needs to be programmed.  The IDE then sends the new code to the UART on the ATmega from a serial port on the computer, usually via a USB-to-TTL converter.

If you are making your own Arduino-compatible hardware and you don’t purchase already-programmed chips, then you will need to program the chips with an Arduino serial bootloader first to be able to use the standard IDE.  There are various ways of doing so and they are well documented (for the most part).  The Arduino software installation comes with bootloader code ready to be programmed onto your target device.  The bootloader code has different flavors to match the different variants in ATmega chips, such as flash size and crystal frequencies.  I personally use the Arduino as ISP method to program the bootloader because I can use it with my existing Arduino board and not have to purchase a stand-alone AVR programmer.

I have an older Arduino Diecimila which I use as my programmer and I put the new chips on a breadboard which is on an Adafruit Proto Shield.  I have the necessary pins wired up from the shield headers to the breadboard and also included the necessary crystal and reset resistor (see here: burning the bootloader).  This setup works pretty well and lets me quickly and easily swap out the chip to be programmed.  It’s not as easy as this, but I already had all the necessary hardware.

I recently ran into a couple issues trying to use this Arduino as ISP method while programming the bootloader on chips for my ColorNode project. First, I kept getting a “not in sync” error when it tried to run the bootloader process. After digging around, I found this site which suggested installing ~ 110Ω worth of resistance between the programmer’s Reset line (Arduino board header closest to power jack) and +5V.  The method is also discussed and explained here. Basically, when the IDE connects to download the bootloader code via the Arduino board programmed as the AVR programmer, that board get’s reset due to the way the auto-reset circuitry works.  Pulling the Reset line to +5V with a much lower resistance prevents this from happening and screwing up the bootloader programming process.

Once I resolved that issue I was able to successfully program the bootloader onto some ATmega328P chips (I chose the regular Duemilanove /w ATmega 328 as the board). I had also purchased up some ATmega328 (non-P) chips because they were cheaper and readily available from DigiKey. The main difference is the process technology where the P indicates their PicoPower technology and is best suited for low-power applications. Since I’m not running off batteries in my application, it doesn’t really matter. The code is compatible with either device and the Arduino IDE doesn’t differentiate between the two when doing the serial programming.

When I attempted to use the above process to program the bootloader on the ATmega328 chips, I ran into my second issue. When I ran the bootloader process I got an “Expected signature for ATMEGA328P is 1E 95 0F” error. Although the two chips are nearly identical and, from the code space aspect are identical, they have different part identification signatures. These signatures need to match those setup in the ISP configuration, specifically the avrdude.conf file. Page 302 in the full datasheet shows that the ATmega328 has a device signature of 0x1E 0×95 0×14 while the signature for the ATmega328P is 0x1E 0×95 0x0F. I found this posting on the arduino forums that talks about it more. Once I changed that setting the bootloader programmed correctly and both the P and non-P versions were able to be serially programmed with the IDE using the standard process.

© 2012 DigitalMisery.com Suffusion WordPress theme by Sayontan Sinha