GE Color Effects Lights logic in Python

I’ve been playing with these holiday lights recently. They’re very neat: each bulb has RGB LEDs embedded in it and is individually addressable (albeit with only 4 bits of resolution per color channel). Some wonderfully talented folks have reverse-engineered the protocol that the light controller uses; others have written Arduino code making it possible to snip the light’s control line, connect it to an Arduino, and begin programming your own animations. Still others are doing various neat and unusual things with the result. Personally, I just want to have some interesting light displays for New Year’s.

These other folks’ work makes this possible, but not as convenient as it could be: developing new animation routines on the Arduino is a pain in the butt. To do so you write your code in the Arduino’s irritating development environment, then flash it to the chip and hope that everything worked right. There’s a small risk of damaging the lights, and a large chance of things going wrong.

So! I wrote some bridge code that moves the light control logic into Python, which can run and be manipulated on a regular ol’ computer. The state of the lights is then sent to the Arduino many times per second (though not as many as I’d like — still, only about 1FPS slower than the string’s theoretical max) and the Arduino dutifully updates the state of the lights. This should make development of animations easier, and make it simpler to trigger or modulate them in response to network events or other things that the computer can detect.

If you have any use for this code, you can find it here. For me, there are two challenges remaining: creating some interesting animations, and connecting a second string to the Arduino.

This latter issue is a bigger problem than you might think: the lights’ address space is only 6 bits — too small to simply connect the two strings together and retain the ability to control individual lights (bulbs can share addresses, but I’d rather not do that). So the two strings need to be treated as individual entities. That’s easy enough on the Arduino side. But the Arduino is going to live at one end of this double-string, not in the middle. That means that the signal to the far string will have to be transmitted along the length of the near string. This is too much distance for a fast serial connection to traverse without being spread out into illegibility.

The solution, I’m told, is to shift the serial signal to RS-422, a higher-speed and more ethernet-like standard, then back to serial at the light string (it will travel along a twisted pair of conductors that I’ll run along the already-too-heavy first string). I have the chips to do this, and it all *looks* pretty simple. Fingers crossed…

6 Responses to “GE Color Effects Lights logic in Python”

  1. Curtis Owens says:

    I would love to do the same sort of thing, but my knowlege in scripting is limited, and I know nothing about python. I am very new to the hacking world, but I had the same sort of ideas, that it would be nice to just use the arduino as a relay for the hard work done on a networked computer.
    I would love to know all the steps nessessary to reproduce your amazing work. I am decent at understanding code, but I get lost when it comes to separate elements. I have 3 sets of GE-35 50 strands, 1 arduino duemilanove, plenty of computers, 1 network shield with SD card storage. any tips or a walk through? So far your work has been the closest to my dream of making this work due to the memory and computational limits of the arduino. Thanks! I am trying to figure this out before christmas and possibly before a class reunion. Eventually I would love to get it wireless if possible.

  2. Tom says:

    Curtis, I think this is a great starter project. The best place to begin is with the sample libraries and code that I link to in my various blog posts. You should begin by just trying to control one string of lights.

    Unfortunately it looks like the link to the Scott Harris library is now dead. There is software linked from the end of the deepdarc blog post, though (you can ignore the details of that blog post as you get started — it just explains how he reverse-engineered the protocol). This might also be a useful library (I haven’t tried it).

    In either case, your basic steps will be:

    1. Look at the Arduino code and figure out which pin it’s planning to use for output.

    2. Connect that pin to the middle conductor of the Color Effects wiring (make sure to break the connection on this conductor that goes to the stock controller box — otherwise the lights will be getting contradictory signals).

    3. Connect the Arduino’s ground connector to the Color Effects ground connector. You need to *NOT* sever the connection of this wire to the control box (or if you do sever it, reconnect it later). You will probably need a multimeter to determine which of the outside conductors is the positive line and which is ground. The voltages are now high enough for you to shock yourself, but do avoid cutting into active lines (if you connect the positive to ground through an x-acto blade or something you could short out the power supply).

    With those connections made you should be able to control the string through the Arduino. This is a great first step. Experiment, understand what the library is doing, perhaps start reading that deepdarc post to grok the protocol. It’s actually all pretty basic stuff, though it may seem intimidating at first.

    Controlling multiple lights is more complex. For someone starting out, I wouldn’t necessarily recommend the approach I took. Having a separate Arduino for each light is probably the simplest solution.

  3. Curtis Owens says:

    I have actually been aware of deepdarc’s post for about 2 years now. I have wanted to do something like this for about 3 years. So I have uploaded stuff to the Arduino, I have tweeked one or 2 codes, but I don’t have the understanding of how to make the computer control the lights through the Arduino. Like I have said in my first message, I have run into codes that use too much memory, and frankly I don’t have enough coding experience to limit the amount of memory it takes to get something done. I can do math, I understand variables and types, but I am horrible with pointers and don’t have enough experience with interfacing.
    I have already gained control of the GE lights. I know enough engineering wise to know how to be safe with the electrical and how to control it. I have run other scripts through my arduino to control the lights successfully. But, I like your ideas much more, that is the primary reason I have contacted you. I like the way you have a computer controlling the arduino. I don’t know how you are interfacing with the Arduino, but I like it so far. Eventually I hope to see someone control the arduino over a network/wireless connection to control these lights.

    Thank you for all your help. I am shocked that you were able to get back to me so quickly! Keep on tinkering, you seem good at it. I like how some people are using optical relays to separate the electrical sources. Right now I have the transformer powering the arduino+ the lights, I don’t remember which script I have installed right now, but it can make some fancy patters, and my somewhat older arduino doesn’t have enough memory to run anything more complicated. That is exactly what I would like to run. I would like to eventually control multiple strands, but I will keep them electrically separate. especially since each transformer has slightly different properties, I don’t want to risk damaging one by connecting 2 together. I have no clue how some people are able to interface 8+ strands to 1 arduino. I do not know how to deal with sending one stream of data to one port and another stream to another port. It’s all confusing to me. Those are the places in which I am stuck.
    deepdarc’s post has been 100% correct in telling which lines are which. He has done amazing work!

  4. Tom says:

    Ah! Then you’re much further along than I expected. You’re welcome to all of my code, which you can find here:

    https://github.com/sbma44/cheerlights-arduino-python

    As I’ve mentioned in videos about this (in other posts connected to this one) the refresh rate is limited, making direct on-Arduino logic a better choice for some applications. But this code should demonstrate how to have a Python script control the state of the lights, sending refresh signals via serial to an Arduino sketch that then updates the string.

    There’s also a simple web interface that lets you flip between animations on an iphone or other device. You can find this in web_ui.py, which is probably the most complicated/confusing of the scripts in that it forks a separate Tornado webserver process and sends messages back and forth from it. random_colors.py shows a bare-bones approach to the code. As I mention briefly in the README, you’re going to need to edit the contents of settings.py to reflect the number of strings (which should be 1 in your case — my code assumes they’ve been daisychained with some more exotic protocol extender ICs) and the serial port’s ID. If you had 3 Arduinos there’s no reason you couldn’t run three copies of the script at once though, from different locations (or, better, adapt the code to send messages to the three different serial ports).

  5. Curtis Owens says:

    indeed the refresh rate will never be ideal. I am hoping someone can eventually make it so these arduinos can have this type of code sent to them over a wifi,lan connection rather than direct serial connection to a computer.

    Is that maximum refresh rate caused by the GE-light’s hardware? What is it caused by? I guess I will have to read back to Deepdarc’s page.

  6. Tom says:

    Yeah, it’s a timing limitation. Deepdarc has details. The system I wrote introduces some overhead but not much.

    Wifi should be possible, but getting embedded systems working wirelessly tends to be a pain in the butt. Most Arduino wifi shields are expensive and can’t handle DNS, for instance. You might want to look at a BeagleBone or similar to drive the string. Or, more simply, just an old netbook from ebay. The price will be similar, and it’s not like you’ll be running the lights off of a battery anyway (right?) so an embedded low-power system presumably isn’t a requirement.

Leave a Reply