Minion Christmas Lights


Christmas is fast approaching and we, like many of you, want to have a hacker style Christmas. We want to be able to have full control over our Christmas lights this year. GE lights are one of the best ways to do this because they have such huge capability. The out of the box the lights though only have a few sub par light functions programmed in.

We needed a way to hack into the lights and gain control. So we developed a small Arduino based unit that would fit in the original box of the GE light string, we call this little guy Minion. Minion is currently available on kickstarter until Nov 1st, check it out: (back this project now and get it in time for Christmas).

With Minion you can communicate with any bulb on any string and make it any color you want at anytime. This creates an easy method to make your house Christmas lights dance to music, spell sayings, make shapes and designs, etc.

Here’s a brief project overview and then a demonstration. More details are after the videos.

The First step was to open the GE light circuit box. They have a goofy triangle screw, you can use a small straight edge bit if you’re careful, others have ground hex keys down to fit. Once you get the box open you’ll have to pry the epoxy free form the housing.

 The next step is to do a little custom fabrication on the GE box. You’ll need to break off all the plastic pieces that stick out into the empty cavity of the box. This will allow Minion to fit nicely inside the box.

We used a small blow torch to heat up an X-Acto knife. This made the knife cut through the plastic like butter and gave us smoother edges inside the box.
 After that, you’ll need to take disconnect the original GE circuit board from the wires. We used a soldering iron and just re-flowed the solder.
 Now connect the Minion up to the power, the ground, and the signal line from the GE light string. Take note which signal line you connect it too. You’ll need to make sure that the power and ground get connected to the Minion from the wall wart as well. This will allow for the Minion and the lights to be powered from the wall wart.
Put a healthy coat of hot glue on the board to keep it safe from having the connections pulled while assembling. Hot Glue is a great insulator and has the benefit of holding the wires tight as well. We put a piece of cardboard under the wires and glued them all to it to hold them steady.
(We used our proto Minions that all had headers on them. So this was a proof of concept. Once we get our final Minions, which will not have headers already installed, I am going to just wire them straight into the board.)

Because we removed the inner plastic pieces as we showed above Minion fit in perfectly. We took the antenna and wrapped it around the board so that the entire Minion was completely contained in the controller box. Finally replace the box lid and screws. The end goal is to make it all watertight again.
Now to the code. We used the G35Arduino to control the lights and the RFM12 Library for controlling the radio.
The G35Arduino library is a great library for controlling the GE lights. It takes care of all the communication and timing. It lets us take control of all the lights. With it we can turn on a section of the light or just a single bulb. It lets you change the color and the brightness of each bulb. It also has examples light programs in it to help get you started.  The library is available at:

The 2 main ideas for using these are
             1: A predefined (recorded) light show: The Minions sync together and do their thing without receiving signals from a computer after being programmed. This is the final goal for us.
             2: Control the lights live from a computer: This is easier to set up and a first step to getting to the predefined show.

These instructions are for the live light show from a computer. It is the fastest way to get these lights up and working and later we will do the predefined (recorded) show.

For the Master Minion (the Minion sending the signal commands from the computer) we used the Minion Chat program. This is from our first test with the Minion, it is a simple way to send data straight from the terminal. The Chat program waits for you to send a byte through the COM port and then broadcasts it out to a specific Minion. We did this because we could just type on the keyboard and have it sent to the Light Minion. No Gui needed. (Code available below)

When the Light Strand Minion starts up it initializes all of the lights. This is taken care of by the library and gives all the lights a number. My strand here has 25 lights so it numbers them 0-24.

To make changing the lights quick and easy we had the Light Minion listen for characters sent over the radio. 0-9 set the color that we want the bulb to be.

2: RED

Because my strand has 25 lights I mapped the lights to  q=0 w=1 e=2 etc. (The layout of the letters on the keyboard. The first row of letters was 0-9, 2nd 10-18 and 3rd 19-24)

So by typing 2qwert into the terminal we could turn the lights 0-4 to red. 0qwert would then turn them to Black or Off.

If you have any questions about hacking GE lights with Minion or Minion at all please email leave them in the comments and I will get to you. Either by email or a reply in the comments.

Don’t forget to check out our kickstarter for these Minion circuits. It runs until Nov 1st, order them now to get them in time for Christmas.

All the code is below.

MinionLight Code

#include         //Radio Library
#define myNodeID 30 //node ID of Rx (range 0-30)
#define network 210 //network group (can be in the range 1-250).
#define freq RF12_915MHZ //Freq of RF12B can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. Match freq to module
typedef struct { byte c1 ;} Payload; // create structure - a neat way of packaging data for RF comms
Payload rxPacket;
const int Rx_NodeID=10; //emonTx node ID

#define LIGHT_COUNT (25)
#define G35_PIN (4)
G35String lights(G35_PIN, LIGHT_COUNT);
//EO G35

void setup() {
lights.fill_color(0, LIGHT_COUNT, G35::MAX_INTENSITY, COLOR_WHITE);
rf12_initialize(myNodeID,freq,network); //Initialize RFM12 with settings defined above

int Color=0;
int BulbNum=0;

void loop() {
if (rf12_recvDone())
if (rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0)
int node_id = (rf12_hdr & 0x1F); //extract nodeID from payload
if (node_id == Rx_NodeID)
{ //check data is coming from node with the corrct ID
rxPacket=*(Payload*) rf12_data; // Extract the data from the payload
char temp=(char)rxPacket.c1;

if(temp=='q') BulbNum=0;
if(temp=='w') BulbNum=1;
if(temp=='e') BulbNum=2;
if(temp=='r') BulbNum=3;
if(temp=='t') BulbNum=4;
if(temp=='y') BulbNum=5;
if(temp=='u') BulbNum=6;
if(temp=='i') BulbNum=7;
if(temp=='o') BulbNum=8;
if(temp=='p') BulbNum=9;
if(temp=='a') BulbNum=10;
if(temp=='s') BulbNum=11;
if(temp=='d') BulbNum=12;
if(temp=='f') BulbNum=13;
if(temp=='g') BulbNum=14;
if(temp=='h') BulbNum=15;
if(temp=='j') BulbNum=16;
if(temp=='k') BulbNum=17;
if(temp=='l') BulbNum=18;
if(temp=='z') BulbNum=19;
if(temp=='x') BulbNum=20;
if(temp=='c') BulbNum=21;
if(temp=='v') BulbNum=22;
if(temp=='b') BulbNum=23;
if(temp=='n') BulbNum=24;

if(temp=='0') Color=0;
if(temp=='1') Color=1;
if(temp=='2') Color=2;
if(temp=='3') Color=3;
if(temp=='4') Color=4;
if(temp=='5') Color=5;
if(temp=='6') Color=6;
if(temp=='7') Color=7;
if(temp=='8') Color=8;
if(temp=='9') Color=9;

if(temp>='a' && temp<='z')
case 0: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_BLACK); break;
case 1: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_WHITE); break;
case 2: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_RED); break;
case 3: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_BLUE); break;
case 4: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_GREEN); break;
case 5: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_CYAN); break;
case 6: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_MAGENTA); break;
case 7: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_YELLOW); break;
case 8: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_PURPLE); break;
case 9: lights.fill_color(BulbNum, 1, G35::MAX_INTENSITY, COLOR_ORANGE); break;
default: break;
//If you have the USB connected you can watch the commands come in for debugging
Serial.print("Color: ");
Serial.print("Bulb: ");
Serial.print("char: ");


}//end of void LOOP()

Minion Chat Program Code (Minion Master attached to the computer)


#define myNodeID 10 //node ID of Rx (range 0-30)
#define network 210 //network group (can be in the range 1-250).
#define freq RF12_915MHZ //Freq of RF12B can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. Match freq to module

typedef struct { byte c1 ; } Payload; // create structure - a neat way of packaging data for RF comms
Payload txPacket;

const int Rx_NodeID=0; //emonTx node ID

void setup() {

 while (!Serial);
 rf12_initialize(myNodeID,freq,network); //Initialize RFM12 with settings defined above

void loop() {

   int i=0;
   while(!rf12_canSend() && i<10)
   rf12_sendStart(0,&txPacket,sizeof txPacket);

}//end of void LOOP()

3 Responses to Minion Christmas Lights

  1. Brett Kappenman says:

    How realistic is it that you’ll be selling these within the next week?

    • Nate says:

      I’m sorry to say we wont be selling them until all of the kickstarter backers get theirs. They are looking to go on sale sometime middle of dec to early january.

      • Brett Kappenman says:

        I was hoping to have a spinning tree this year. :-(

        I’m sure you’re busting your backside trying to get them out the door.

        Anxious to see the final product.

        Guess I’ll have to hack something together with my Arduino.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>