Hacking G-35 GE Christmas Lights

Introduction

In 2010, I found an article about hacking the Color Effects GE G-35 string set 50 LED lights on the web.  I don’t recall if it was on LifeHacker.com or maybe even hackaday.com. Regardless, most of the hacking information was found by deepdarc.

These articles intrigued me enough to go out and buy a couple of light sets and an Arduino to control them.  (Several friends had been experimenting with the Arduino board — now, my turn!)  By the time I read the articles and was motivated, the lights were out of the stored (2010).  Now, 2011, lights are in, I bought a couple of strings, and have been working on programming them (from the advice and information found online).

My purpose in blogging this is to share my experiences, and hopefully help a fellow science enthusiast or two “realize the dream!”

Hack Information Sources

References for hacking G-35 lights include:

There are other references online.  Just google something like “hack costco GE christmas lights” and you will find lights flashing to music and scrolling marque signs made from these lights.

Special thanks to “Michael D.” for his post on Scott Harris’ blog referencing the delay_x.h delay library that can be found here:  http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=665&item_type=project (registration required)  And thanks to Hans-Juergen Heinrichs for writing the library!

Hardware

I bought two strings of lights, “Color Effects, G-35 string set 50 LED lights” from Costco around early September 2011.

I bought the Arduino Uno board from adafruit.com.  I got some extras with the board — a few LEDs, a 9v power supply, some transistors, and more.  (I plan to do a little more experimentation after Christmas!)

In addtion to the lights and Arduino, I bought miscellaneous wire, connectors, switches, and a box to mount the whole mess in.  Orvac Electronics.  :)

The key to the GE lights protocol can be found on the deep darc blog here.  I won’t go into the details except to note that the ground wire on the GE lights has a tiny rib on the insulation, making it easier to to find the ground wire.  Note that deep darc’s blog has a picture identifying the positive/ground/control lines here.

In brief, the light string comes with a 5v power supply (wall wart), and an inline controller.  The inline controller can be replaced with your controller of choice in order to make the light string do your bidding.  I’ve chosen the Arduino Uno.

The5v power supply plugs into 120v AC and outputs 5v DC.  The 5v DC goes into a little green box (inline with the GE lights).  Out of that little green box comes three lines — a ground line, a signal line (“line level” — but I’m not a h/w guy), and a 5v DC line.  The 3 lines “daisy chain” down to each bulb in the string.

Here’s a picture of the box I mounted it in.  I used Molex connectors on the light strings so that I could plug in the original controllers if I wish.

Clockwise from the upper left, note: power switch, green controller that came with light string, 5v DC power supply, lower right, second power supply for second light string, second green controller, lower left note the USB cable plugged into the Arduino (can be removed when I “deploy” this outside with lights), lower left corner has the Molex connector mounted that plugs into one light string, left is the Arduino board with two ground wires (one from each light string), and two control lines (one going to each light string), and back to upper left, the power cord.  Note in the very center, in the bottom of the pile, a 9 VDC transformer for the Arduino.  The yellow electrical “wing nuts” tie in the 120 VAC of the 3 transformers and connect to the power switch.  The dowel traversing bisecting the box simply keeps the transformers and controllers from sagging down into the Arduino when mounted vertically.

Wiring

To wire in the Arduino, you need to:

  • disconnect the GE lights control line from the light string
  • connect the ground from the light string to the Arduino ground
  • connect an Arduino output pin to the control line going to the light string (e.g., pin 2 or pin 4)
  • keep a 5v power source going to the light string (both positive and negative lines)

I didn’t use any pullup resistors, transistors, etc. in my wiring.

Here is my cheesy hand-drawn quickie wiring diagram.

If you look at the photo of my box above, the two coils of wire are the wires between the “connectors” in my hand drawn diagram.  I added these connector/plugs so that I could easily bypass my wiring and use the controller that came with the lights.  Also, looking closely at the photo, you can see two ground wires (one from each of my 2 light strings) connected to the ground on the Arduino, and I think you can see two control lines (yellow) connected to pins 2 and 4.

Another thing I found in my research was that if you control multiple strings of lights, and you have to run a signal line from an Arduino for a long ways, there may be some signal attenuation and some kind of signal boosting may be required.  Read up on the http://doityourselfchristmas.com/ site for details on this.

Software

My goal in writing software for the GE lights was to get a fun set of pleasing light sequences for the GE lights hanging on my house during Christmas.

You are welcome to reuse and modify any of the code I post as long as you leave my name in the “credits”.  Find a link to the code in the references section at the top of this blog post.

While deep darc shows a lot of information about the hardware and timing of the lights, I didn’t find any software on his site to be useful for me.  My best s/w example came from Scott’s blog here.  While this was a good place to start, I often found an occasional bulb to not be addressed correctly.  A comment there by “Michael D.” led me to a delay_x.h library that provided more accurate timing.

Here’s a picture of my test setup.  I mounted the bulbs on a small sheet of plywood to more easily visualize the bulb sequences.

Low Level

It turns out that when you use the Arduino delayMicroseconds(num_us); function, you won’t get a consistent delay.  Interrupts are enabled during this call, and the Arduino does indeed interrupt.  I believe this lead to my inconsistencies in writing to the bulbs.  I switched over to the delay_x.h library.  Those calls don’t enable/disable interrupts.  So, I was able to disable interrupts, write a bit stream to the lights, then re-enable interrupts, resulting in consistent data and timing going to the controller.

One other thing that I attempted was to have the controller write to two strings of lights simultaneously.  That would reduce the overall time to update all of the strings of lights.  I was unable to accomplish this without timing problems.  It seems there was some kind of problem when I would write to two Arduino pins at the same time.  There may be remnants of these functions in the code if anyone wishes to try this.  I figured it was only decorative lighting — I didn’t have to sweat the details if it took slightly longer to refresh two light strings.

Medium Level

Once I got the timing down, I concentrated on core functions for writing the string of lights to the controller (based on Scott’s code).  I created structures representing the light string hardware (a list of bulbs, each bulb with an address, intensity, and red/green/blue value).  I wrote functions that would take those structures and write then to the controller.

Additionally, I created a model whereby my main Arduino loop() method would come back to the same place for delays.  This makes it much easier to do any kind of switch polling or other task during times when the light strings are not being updated.

High Level

On top of the “medium level” software representing the hardware (light string), I created an abstraction whereby I could write fairly high level functions to set light information, without having to deal with the details of forward/reverse addressing and multiple strings.  I was able to boil this thing down to where I could write a new light sequence in only a few lines of code.

I adopted a model whereby a particular light sequence is like a measure in a song.  However I never really got to the point of creating multiple lists of measures, with the exception of a “demo” list (shorter sequence, to show my friends), and an “operational” list for when I put my lights on my house.

Software Configuration

I’ve written my software in such a way that it will support one or more strings of lights.  The number of bulbs is configurable.  Those lights can be configured to be addressed/written either forward or in reverse.  The Arduino pin number is configurable.  There are also hooks in for debugging.  This includes writing to the serial port, and flashing the onboard LED to ensure the Arduino is still “pulsing” through the light software.

My “namespace” is simply to prefix my functions and global variables with “xm_” (For Xmas.)

In xm_lights.h, you can set the number of light strings, bulbs per string, Arduino output pins, and light string direction.

// The number of strings of lights used in the project.
#define XM_NUM_LIGHT_STRINGS 2

EXTERN uint8_t xm_light_string_pin[] // Arduino output pins for all strings.
#ifdef DEFINE_GLOBALS
= {2, 4}
#endif
;

EXTERN uint8_t xm_light_string_direction[] // Light string bulb address direction.
#ifdef DEFINE_GLOBALS
= {XM_REVERSE_DIRECTION, XM_FORWARD_DIRECTION}
#endif
;

You can configure which light sequences are displayed by modifying xm_measures.h.

EXTERN xm_measure_t measure_list_demo[] // Measures (of light sequences).
#ifdef DEFINE_GLOBALS
= {
{xm_measure_fill_to_blue, 2000},
{xm_measure_rgb, 2000},
{xm_measure_random, 150},
{xm_measure_shift_rt_fill_white, 100},
{xm_measure_random_fade, 25},
{xm_measure_fade_to_color, 200},
{xm_measure_fill_slide_loop, 25},
{xm_measure_fade_slide_loop, 25},
{xm_measure_red_green_alt, 500}
}
#endif
;

You can add “measures” (light sequences) by adding them to xm_measures.c.

Summary

Well, mostly I wanted to blab a little, and post my code in hopes of helping anyone else interested in a fun “light” hardware/software combined project.  Go ahead and post any questions and I’ll do my best to respond.  I didn’t have time to completely discuss the s/w but sometimes you just have to call it “done”.

(Leave me a note below!)

Posted in Uncategorized | 67 Comments

Blob Purpose

The purpose of this blog is to describe my adventures hacking the GE G-35 string set of 50 LED lights, commonly available at Costco at Christmas time.

I found information on hacking these lights at the end of 2010.  However, the lights were all sold out of the stores.  So here we are in 2011, I’ve got my lights, and I’ve programmed them to do my bidding.

Let the description begin!

Posted in Uncategorized | Leave a comment