Introduction: Arduino Christmas Lights
Let me add this to the beginning of this... I made some very large safety mistakes in this... please if you do anything with this understand the electricity, how it should be used, and how to NOT do it like I did. There are some things are are fine... great even... and there are some things that should NOT be done. (the biggest ones I can think of are putting the relay on the neutral, instead of the hot, and using low voltage wire instead of 120v wire).
That being said everything here works, and was very educational for me. With a few minor changes you can amke this functional AND safe. Thank you.
I am very new to Arduino, but am having a lot of fun with it!!! After finishing the animatronics for my office Christmas float I decided to make some automated Christmas lights.
I know this has been done many times online, but I think this shows the best, easiest, and cheapest of some of the different ways I have found.
Most of this deals with the electrical box. I didn't take pictures of the cable build, so it is all in one step, but there is a lot there.
Also the software and a MP3 is at the end.
Let me know if you have any questions.
I will also say that I got the hot/neutral backwards. You don't want to be switching the neutral on and off and constantly pushing electrons down the other lines (the hot). Any leak, insulation damage, or whatever else will results in leaking electrons... and this is never good. So make sure the lines that are being switched are the hot lines, not the neutral.
I have keep this the same (wrong) way so as not to cause more confusion with the colors. If you are doing this I am going to assume you can make this switch without too much problem. Just make sure you are switching the hot, not the neutral.
Attachments
Step 1: Intro
Here is everything you will need for this project. From left to right:
Arduino. I used the Arduino Mega 2560 and Ada Fruit Wave Shield. I went with the Mega because I wanted to be able to control more lights. With the mega I effectively can control as many as I want (not hundred, but dozens). If you want to go this way make sure you check out the differences in building the Wave Shield for the Mega as opposed for the Uno. Basically pins 10-13 need to be redirected to 50-53 ("CCS" to 53, 11 to 51, 12 to 50, 13 to 52). I'm not going to go into all of the changes for that, the AdaFruit forums are much better than I could do.
If you haven't used electrical scissors get them, I love them. Same with wire strippers. These are both things I have been reluctant to use for years, preferring to stick with a knife. Go for the succors and stripper.
In-sure wire connectors are not needed, but they sure make the connections easier.
Be sure to get jumper wires that are male on one end, and female on the other. There aren't many like that, so look for them, the ones from AdaFruit are good.
cheap electrical outlets.
Cheap plug from Home Depot
4-Gang Old Work Outlet Box. This makes a pretty good project box. I still need to get a 4 place faceplate to finish it off, and get another outlet box to house the arduino and relays. Currently it is functional, but not pretty.
Romex wire. It may be easer and better to just use some speaker wire or something like that, but I had the romex and so I used it.
SainSmart 8-Channel Relay Module. This makes this easy, and is likely cheaper than any you would roll yourself. The only downside is you have to make sure you program them backwards from what I am used to... low is on, high is off. Strange, maybe that is how they do it in China.
Laptop for programing the Arduino. Make sure you switch the board from the Uno to the Mega... that one took me a while to figure out why it was not compiling right!!!
Step 2: The Outlets
The first thing you want to do is modify the outlets so that each outlet can control two channels.
I will be passing the neutral through the relay. You can use hot, but it is not as safe, and not the standard. I would just stick with neutral. A few ways to know the difference is neutral has the wider outlet, the neutral is on the left of the receptacle (assuming ground is down), the neutral is often aluminum color and the hot is copper, the neutral line is ribbed, and usually the writing is on the hot line. A line tester will only light on hot side. These are only guidelines, so check and make sure you know which line you are working with.
There is a little tab between the screws on the outlet that is the only thing that connects the top and bottom receptacle in an outlet. If you want to have two different circuits in a outlet you can easily break this off. In our project ONLY BREAK OFF THE HOT SIDE (the side with the large plug). (I have 4 extra receptacles with both the hot and neutral tabs broken off if you need them). You can do it with both tabs broken off, but is is much easier if you don't.
In these pictures you can see the tab, see it half broken off, and see if off.
Step 3: Wire the Hot
The hot side are all wired together. Use short 2-3" jumpers to connect all 4 outlets. They are different colors because I made them from both wires from one length of romex. Measure them against the box. The end will be connected to the long wire from the outlet after everything is put together.
At this point go ahead and make the wall plug in. Cut a romex piece 2-3 foot long. Make sure the neutral is attached to the wide plug. Twisting the two lines together keep things much better organized.
Step 4:
You can see the 4 outlets ganged together by their hot sides.
Also you can see the plug put together, and the lines twisted.
Also there are 8 pieces of romex cut about 10-12 inches long. I will take these apart, using the hot and neutral insulated wires, but keep the ground wire is not used, and kept for recycling.
Step 5:
You can see after the romex is taken apart the ends are made ready. They are both stripped 1/2" on one end, and 1/4"- 1/8" on the other. The hot lines (black) are kept strait, but the white (neutral) lines are curved on the 1/2" end.
The short 1/4-1/8 inch end is for connecting to the relay.
Step 6:
The neutral lines are all ganged together. I used the In-sure connectors to connect all of the hot lines; this just makes it easier.
Step 7:
Here you can see all of the leads connected to the neutral side of the plug. Note that you are going to have a wire connected to both screws on the neutral side, where as the hot side is all ganged together.
Step 8: Label the Wires
Make sure you label the wires coming from the plugs. When you put them through the box it is easy to loose track of which one was for which outlet. I started to use a tape flag, but it didn't go through the junction box very well, so I used a sharpie instead.
I used a line for 1, and a block for 5. In the picture you can clearly see a 7 and 8 in the middle, and a 1 is blurry on the right.
Step 9:
Stick all of the wires through the holes in the outlet box. This includes sticking the outlet plug wires into the box.
The hot wire goes directly to the hot screw on the closest outlet. The electricity will be spread to all of the plugs through the jumpers that gang all of the plugs together.
All of the other wires you see down in the box (most of them) are neutral. It would have been better to have another color, but I didn't... so the dark color is the neutral that is all ganged together with the In-sure connectors, and going out to the relays, and the white is the neutral coming back from the relay, and will only be neutral when the relay is closed.
Step 10:
Here you can see the outlets in place.
The power is coming in from the top right. The hot is going to the first outlet, and a jumper wire is used to gang together all 4 outlets.
The neutral line is then ganged tougher with the In-sure connectors and going out of the box as the dark wires. The white wires will be coming back from the relay. If you look you can see the numbering system I put on the wires with brown sharpie.
Step 11:
Here you can see I am holding the plug on the left, but it is going in on the top right.
The 8 dark lines are all ganged together neutral, and are connected to the common (C) relay contact.
The whites are attached to the normal open (NO) contact. You can see that I have now numbered the outlet, and the wire.
Step 12:
I currently have my Arduino Mega, with the attached WaveShield, relay, and plug ins in a plastic tub. I next plan on getting a 4 gang plug cover the plugins, and may put the relay and Mega in another 4 gang junction box. The Arduno fits perfectly in the bottom, but the relay doesn't fit as well.
Step 13:
I am sorry I did not take pictures of how I made the extension cord for this. While you can simply use a bunch of extension cords, making your own is much easier to work with, and not so unsightly.
First, two things. First I have made a few changes because of the education someone else took the time to help me with. The hot and neutral do matter. You don't want to be constantly sending elections down the wire unless you want to do something with them. Sure they will do nothing as long as there is no where to go, but just one little knick and you will have trouble. The common should be neutral for a reason. I think I have made all of theses changes, but if you find an area that does not agree with the rest sorry... I may have missed one.
Second... use your brain. Just because someone did it one way... just because you can do something one way... does not mean you should. Using things differently than they were designed should always be cause for concern. Fuses, gauge size, insulation, GFCI outlets, and just good ole common sense all should come into play when doing anything like this, especially when working with 110v AC.
What you need:
7 strand sprinkler cable
6 male and 6 female plugs
two stranded wire (lamp cord)
black electrical tape... quite a bit of it.
I used 7 circuit sprinkler cable. It has 7 solid copper strands, each with their own color. You can see most of the colors where I have the male plug ends. The neutral is not seen in this version. I made two of them, and I liked the way I did this one better.
Strip about 1-2 feet of the outer black sheath exposing the 7 wires. Pick which color you want to be neutral, I chose white.
Strip most of the insulation off the white (or whatever color you want to be neutral). Leave about 1" near the base so you can make sure the insulation is totally covered.
Take 3 strands of the two stranded wire about the same length as your stripped wire (about 1-1.5 feet). Split these two wires from each other so you have 6 wires. Strip 1/2" from one end, and 1-2" from the other.
Twist all 6 of these around the base of the stripped (white) wire (this is where you will appreciate the 1-2 inches you stripped from the wire!!). Then take long bare copper wire and wrap it around the bundle of wire you now have. This will not only ensure you have a bullet proof connection, and will more importantly make sure you don't have one wire come loose from the rest. You then coat this with a generous covering of electrical tape.
You will then put the male plugs together using one wire from the sprinkler cable, and one from the neutral wire you have all ganged together with the white wire.
Now you decide how far down the line you want each connector. As I wanted my line to be fairly generic I spaced them all evenly apart.. about 18 foot (really 3 fully stretched arms, and the last two just split half way to the end, and then the end).
Very carefully split the black outer sheath only. You don't want to nick the insulation of any of the inner wires. You then pick which line you want to use first. I usually try and follow rainbow orders of colors, so I always know which one is next (Roy G Biv anyone?) So my first female plug was red, then yellow, green, blue, brown, and finally black. Make sure you label each female plug as you will not know what color they are once you are done.
Once you have your hot wire (red for the first one) and neutral (white) isolated from the rest (they will always be at the bottom of the bundle, it is a rule of projects, one of Murphy's) you can take the insulation off. The hot (red) wire can be cut if you aren't going to be using it further down the line, but as I may want to put a line somewhere else down the line I kept all the lines intact. Make sure you keep the white (neutral) line intact, or if you cut it reconnect the ends together. You will for sure need it to be intact all the way to the end.
Use the two stranded wire to attach to the wires you have now exposed. A generous amount of electrical tape will keep everything in place, and hopefully watertight. I made the tail from the female plug about 1.5 feet long, but you can make it as long as you like.
Continue connecting each hot (colored) strand until all of the colors are used it. In my wire it was 6, as I had a 7 strand wire. There are also 5 strand wires.
I am still not sure if I should make the white (common) wire as the hot or the neutral, but as long as you are consistent it should be fine. I am sure there is some EE groaning right now... so please educate me.
*********************** Someone did educate me!!! (Thank you very much). The HOT is the one what should be switched. This way you only have electrons being pushed down the line when the lights should be one. Otherwise electrons are always trying to be pushed down the line. Sure, it will work either way, but it is a fairly big safety thing).
I am also trying to decide if the electrical tape is good enough to be left outside. I have several layers, all wrapped very tight, but it still makes me a little nervous.
Step 14: Software
I will say I got my start of this timing from some other webpage. I can't find where I got it, and had to make a lot of changes anyway, so I am loading it here. Once you have this it is very easy to create a program for any song.... but if you are like me you are better at the technical wiring and programing than you are matching dancing lights to music... so having a starting point is a great help.
So here is the code. Again it is the code for the Joy to the World file. The version I uploaded is MP3, but if you use the wave shield it will need to be converted to WAV.
Also, I got tired of dealing with the very long code for the lights in the loop, so I made it a function, called "joy()".
Here is the Arduino code:
// By: Tre' Landrum
#include
#include
#include
#include "WaveUtil.h"
#include "WaveHC.h"
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the filesystem on the card
FatReader f; // This holds the information for the file we're play
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
#define DEBOUNCE 5 // button debouncer
//This is for the dancing lights durring joy to the world
// if you are using the Uno instead of the Mega you will need to change these pins. If you use the WaveShield you will only have a few pins avaialbe... 6-9 from the top of my head.
int light1 = 22;
int light2 = 24;
int light3 = 26;
int light4 = 28;
int light5 = 30;
int light6 = 32;
int light7 = 34;
int light8 = 36;
int s = 150;
int ds = 225;
int e = 300;
int de = 450;
int q = 600; //600
int dq = 900;
int h = 0; //1200
int dh = 1800;
int start;
int end;
int time;
int now;
// Variables will change:
// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {14, 15, 16, 17, 18, 19};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
extern int __bss_end;
extern int *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}
void sdErrorCheck(void)
{
if (!card.errorCode()) return;
putstring("\n\rSD I/O error: ");
Serial.print(card.errorCode(), HEX);
putstring(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
void setup() {
byte i;
// set up serial port
Serial.begin(9600);
putstring_nl("WaveHC with ");
Serial.print(NUMBUTTONS, DEC);
putstring_nl("buttons");
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble!
// Set the output pins for the DAC control. This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
// pin13 LED
pinMode(13, OUTPUT);
// Make input & enable pull-up resistors on switch pins
for (i=0; i< NUMBUTTONS; i++) {
pinMode(buttons[i], INPUT);
digitalWrite(buttons[i], HIGH);
}
// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
if (!card.init()) { //play with 8 MHz spi (default faster!)
putstring_nl("Card init. failed!"); // Something went wrong, lets print out why
sdErrorCheck();
while(1); // then 'halt' - do nothing!
}
// enable optimize read - some cards may timeout. Disable if you're having problems
card.partialBlockRead(true);
// Now we will look for a FAT partition!
uint8_t part;
for (part = 0; part < 5; part++) { // we have up to 5 slots to look in
if (vol.init(card, part))
break; // we found one, lets bail
}
if (part == 5) { // if we ended up not finding one :(
putstring_nl("No valid FAT partition!");
sdErrorCheck(); // Something went wrong, lets print out why
while(1); // then 'halt' - do nothing!
}
// Lets tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?
// Try to open the root directory
if (!root.openRoot(vol)) {
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1); // then 'halt' - do nothing!
}
// Whew! We got past the tough parts.
putstring_nl("Ready!");
TCCR2A = 0;
TCCR2B = 1<
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<
pinMode(light1, OUTPUT);
pinMode(light2, OUTPUT);
pinMode(light3, OUTPUT);
pinMode(light4, OUTPUT);
pinMode(light5, OUTPUT);
pinMode(light6, OUTPUT);
pinMode(light7, OUTPUT);
pinMode(light8, OUTPUT);
//the SainSmart Relay's are off high
digitalWrite(light1,HIGH);
digitalWrite(light2,HIGH);
digitalWrite(light3,HIGH);
digitalWrite(light4,HIGH);
digitalWrite(light5,HIGH);
digitalWrite(light6,HIGH);
digitalWrite(light7,HIGH);
digitalWrite(light8,HIGH);
Serial.begin(9600);
} //void setup()
SIGNAL(TIMER2_OVF_vect) {
check_switches();
}
void check_switches()
{
static byte previousstate[NUMBUTTONS];
static byte currentstate[NUMBUTTONS];
byte index;
for (index = 0; index < NUMBUTTONS; index++) {
currentstate[index] = digitalRead(buttons[index]); // read the button
/*
Serial.print(index, DEC);
Serial.print(": cstate=");
Serial.print(currentstate[index], DEC);
Serial.print(", pstate=");
Serial.print(previousstate[index], DEC);
Serial.print(", press=");
*/
if (currentstate[index] == previousstate[index]) {
if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
// just pressed
justpressed[index] = 1;
}
else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
// just released
justreleased[index] = 1;
}
pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed
}
//Serial.println(pressed[index], DEC);
previousstate[index] = currentstate[index]; // keep a running tally of the buttons
}
}
//**********************************************************************************************************
//**********************************************************************************************************
void loop() {
byte i;
//Make sure you change the name of the file to what you want
playfile("JOY.WAV");
joy(); // This is the function that plays joy to the world
}//void loop() {
//**********************************************************************************************************
//**********************************************************************************************************
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
// call our helper to find and play this name
playfile(name);
while (wave.isplaying) {
// do nothing while its playing
}
// now its done playing
}
void playfile(char *name) {
// see if the wave object is currently doing something
if (wave.isplaying) {// already playing something, so stop it!
wave.stop(); // stop it
}
// look in the root directory and open the file
if (!f.open(root, name)) {
putstring("Couldn't open file "); Serial.print(name); return;
}
// OK read the file and turn it into a wave object
if (!wave.create(f)) {
putstring_nl("Not a valid WAV"); return;
}
// ok time to play! start playback
wave.play();
}
// Function for making the diffrent strands light diffrent
void joy() {
putstring_nl("Start of Joy to the World");
start = millis();
digitalWrite(light1, LOW);
digitalWrite(light8, LOW);
delay(q);
digitalWrite(light1, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(de);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(s);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
delay(1050);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light8, LOW);
delay(s);
digitalWrite(light1, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(q);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(q);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
delay(dq);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
digitalWrite(light7, LOW);
delay(dq);
digitalWrite(light2, HIGH);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
digitalWrite(light6, LOW);
delay(dq);
digitalWrite(light3, HIGH);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light2, LOW);
digitalWrite(light3, LOW);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
digitalWrite(light6, LOW);
digitalWrite(light7, LOW);
digitalWrite(light8, LOW);
delay(dq);
digitalWrite(light1, HIGH);
digitalWrite(light2, HIGH);
digitalWrite(light3, HIGH);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light8, HIGH);
//8100
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light8, HIGH);
digitalWrite(light1, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light7, LOW);
delay(e);
digitalWrite(light7, HIGH);
digitalWrite(light2, LOW);
delay(e);
digitalWrite(light2, HIGH);
digitalWrite(light6, LOW);
delay(e);
digitalWrite(light6, HIGH);
digitalWrite(light3, LOW);
delay(de);
digitalWrite(light3, HIGH);
digitalWrite(light5, LOW);
delay(s);
digitalWrite(light5, HIGH);
digitalWrite(light4, LOW);
delay(e);
digitalWrite(light4, HIGH);
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light8, HIGH);
digitalWrite(light1, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light7, LOW);
delay(e);
digitalWrite(light7, HIGH);
digitalWrite(light2, LOW);
delay(e);
digitalWrite(light2, HIGH);
digitalWrite(light6, LOW);
delay(e);
digitalWrite(light6, HIGH);
digitalWrite(light3, LOW);
delay(de);
digitalWrite(light3, HIGH);
digitalWrite(light5, LOW);
delay(s);
digitalWrite(light5, HIGH);
digitalWrite(light4, LOW);
delay(e);
digitalWrite(light4, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(e);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(e);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
//13806
digitalWrite(light1, LOW);
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(75);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(75);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
delay(dq);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
delay(75);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
//15235
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(75);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
delay(e);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(e);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
delay(e);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(75);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(75);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light8, LOW);
delay(dq);
digitalWrite(light1, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
digitalWrite(light8, LOW);
delay(75);
digitalWrite(light1, HIGH);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light8, HIGH);
//17339
digitalWrite(light2, LOW);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
digitalWrite(light7, LOW);
delay(75);
digitalWrite(light2, HIGH);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
digitalWrite(light6, LOW);
delay(e);
digitalWrite(light3, HIGH);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light1, LOW);
digitalWrite(light2, LOW);
digitalWrite(light3, LOW);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
digitalWrite(light6, LOW);
digitalWrite(light7, LOW);
digitalWrite(light8, LOW);
delay(q);
digitalWrite(light1, HIGH);
digitalWrite(light2, HIGH);
digitalWrite(light3, HIGH);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light8, HIGH);
//18315
digitalWrite(light1, LOW);
digitalWrite(light8, LOW);
delay(e);
digitalWrite(light1, HIGH);
digitalWrite(light8, HIGH);
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(de);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(s);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
delay(e);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light3, LOW);
digitalWrite(light6, LOW);
delay(e);
digitalWrite(light3, HIGH);
digitalWrite(light6, HIGH);
putstring_nl(" "); //19817
digitalWrite(light2, LOW);
digitalWrite(light7, LOW);
delay(300);//delay(q);
digitalWrite(light2, HIGH);
digitalWrite(light7, HIGH);
now = millis();
time = now - start;
Serial.println(time); //20117
digitalWrite(light1, LOW);
digitalWrite(light8, LOW);
delay(300);//delay(q);
digitalWrite(light1, HIGH);
digitalWrite(light8, HIGH);
putstring_nl(" last bit ");
// 21018
digitalWrite(light1, LOW);
digitalWrite(light2, LOW);
digitalWrite(light3, LOW);
digitalWrite(light4, LOW);
digitalWrite(light5, LOW);
digitalWrite(light6, LOW);
digitalWrite(light7, LOW);
digitalWrite(light8, LOW);
delay(h);
digitalWrite(light1, HIGH);
digitalWrite(light2, HIGH);
digitalWrite(light3, HIGH);
digitalWrite(light4, HIGH);
digitalWrite(light5, HIGH);
digitalWrite(light6, HIGH);
digitalWrite(light7, HIGH);
digitalWrite(light8, HIGH);
delay(000);
putstring_nl("end of the song");
end = millis();
time = end - start;
Serial.println(time);
Serial.println(start);
Serial.println(end);
}
Attachments

Participated in the
Holiday Contest

Participated in the
Make It Glow Contest
9 Comments
9 years ago on Introduction
**VERY IMPORTANT PLEASE DO NOT FOLLOW THIS INSTRUCTABLE UNTIL IT'S UPDATED**
It looks like you did a lot of planning, but you are unaware of some serious concerns when working with AC mains voltages and this instructable as it is now presents SHOCK AND FIRE HAZARDS. I felt this was important enough that I created an account just to post it.
Breaking the neutral legs is wrong and dangerous presenting a shock hazard, especially given the nature of the projecct. A neutral is basically a dedicated ground for the power to return on. The way you have built this all the strings of lights will be hot when they are off and since Christmas lights are not grounded, they have no easy path to ground. This means someone could cut/damage the wire or pick it up while in contact with something grounded and receive a shock. Everything should be protected by a GFCI outlet, but it should never be relied upon to make up for improper design. To correct this you need to rewire to break the hot legs instead of the neutrals.
The other thing is your use of sprinkler control cable as an extension cord which presents a shock and fire hazard. You don't specify, but 7 conductor sprinkler control cable is typically 18 ga conductor and insulated for low voltage use. For a safe project you MUST design for the maximum current the source can supply, not the anticipated load you will draw. Christmas lights use thin gauge wire because they have a fuse in the plug limiting the maximum draw the wire/string can pull. If the 18ga conductors were insulated for 120V AC (sprinkler cable is typically not) they would have a maximum of ampacity of 14 amps before you adjust for the length. Assuming that this project is plugged into an outlet protected by a 15 or 20 amp circuit breaker you could easily exceed that 14amp maximum before the breaker trips. This means that a short or heavy load down the line could melt the insulation presenting a fire and/or shock hazard. Also of note are the plugs and receptacles you're using. They do not look like they are weather rated and if they are, they likely won't seal properly with just the conductors going into them (without external sheathing). To correct this you need to use wire sized and insulated for the usage (you could still use a 18ga 120VAC conductor, but you would have to add fuses inline to protect them).
I hope you're not offended, you really did do a nice job of planning this out, it just seems like there were some concerns you were unaware of. PLEASE address these concerns ASAP.
Reply 9 years ago on Introduction
Offended?!!? Are you kidding?!? THANK YOU!!
I totally messed up on the hot/ground thing... I can't believe I did that... it should be fairly easy to fix by just switching my plug.
This was actually made for a Christmas Float, so it won't be outside in weather, and a fuse is something I didn't even think about, but am certainly going to add.
This is why I love things like instructables... I hope I can help someone else learn to do some, and in the process learn more myself. So offended?!!? Please, thank you very much. I have a life time "be nice" policy, but I am glad they have an official one here.
Reply 9 years ago on Introduction
It's obvious you put a lot of thought into the project and the instructable, but sometimes people react to corrections/constructive criticism like you told them their kid is ugly. So I figured I'd just disclaimer it, glad it wasn't necessary.
The fusing is only really necessary to protect the relays (what are they rated for?) or the custom extension cord. If you're going to keep the custom extension cord, see if you can find more info on the wire/conductors, maybe you'll get lucky and they're marked with a AC rating so you can pick a fuse. Keep in mind that typical mini-lights use about 0.4 watts per bulb or 40 watts per 100 ct strand. Since they're incandescent lights we can use a power factor of 1 and assume that 100 lights is 0.333 amps. In all reality the loads are probably pretty low and the 18ga wire is probably ok, but it still isn't right using it for voltage it's not rated for.
Also since this is going to be used on a float, make sure you have a working GFCI (especially if people will be on the float) powering the whole thing. GFCI's work by comparing the current on the hot leg to the current on the neutral leg, if it senses more on the hot than on the neutral it assumes that something/someone is providing a better path to ground and shuts off the power.
As far as your later question in the instructable about using white/black it doesn't actually matter, but the convention of sending power on black/red is there so it's clear to anyone working on it which is hot. On a semi-interesting side note, for a Junction Box with a device (light/receptacle) where the power goes there first then to the switch, power should be sent to the switch on the white conductor so that when it returns to the box it's on the black, preventing confusion in a crowded JB.
9 years ago on Introduction
Hey, so far this has been the most clear instructable on christmas light control and I think I'm going to try it out. Did you find that the wave shield was able to produce loud, semi-decent quality audio? Also would there be any way to play music from your computer without just having to start your Arduino code and press play at the same time? Thanks!
Reply 9 years ago on Introduction
Good, it was fun.
The wave shield works great... you will have to make some changes to the hardware for use with the mega, but it isn't any big deal... just figure out which wires go where... and there are several things in the AdaFruit blog about it.
The sounds is 16bit mono... so it isn't high quality CD best, but plenty good enough for something like this.
I am really not sure about starting the music from the computer... the problem would be syncing it together... I really thought about that, but never really came to a conclusion.
Let me know how it goes!
10 years ago
Talonsblade.... Do it... I have only been doing Arduino for a few weeks, and there is just nothing like writing some code that does something in the real world! And programing is nothing but C. Sure there are some functions you may not want to use on a little Arduino chip, but it makes it fun and simple. Something like this with relays is a great place to start because you have one pin that just turns one light on with one line if code. I am looking for my next project!
10 years ago
I certainty can't disagree with upptown.... You can also buy a spool of lamp cord wire from Home Depot.
10 years ago on Introduction
Please do NOT use speaker wire! If you have to use twisted strand wire cannibalize a heavy duty extension cord. If you have a lot of incandescent strings the speaker wire will heat up and melt the insulation.
10 years ago on Introduction
looks awesome. ive been thinking about doing this for a while now but i am more a software junkie than hardware so i never knew where to start. now, im going to get one of these and get started. i will let you know how it works out