Main

Arduino Christmas Lights

With the recent purchase of an Arduino microcontroller, my interest in electronics was rekindled after many years hiatus. One of my goals back in the day was to create a colour organ where lghts would flash in beat with the music. With the Arduino, I can easily do that and much more, so I set about coming up with a project that made use of modern day LED’s. The result will be Christmas lights that:

is a strip of colour LED’s that wraps around a tree where each LED is individually controllable

the LED colours respond to music (the color organ)

uses an IR remote control to change light sequences

I have already designed/tested the technology for each function and will need to add additional functionality and then integrate them and then package it all up.

LED Strip

The LED’s currently consist of a 1 meter strip of 32 – WS2801 RGB drivers connected to 5050 type LED’s. This strip uses 5V, and the SPI protocol for driving the LED’s. Essentially you:

Define an array whose length is the # of LED’s in the strip

Fill that array with 24 bit RGB values

Clock the values in the array to the first WS2801

Repeat to #2

This worked out quite well, and I have already programmed a number of different light sequences. This will need to be significantly expanded in order to support the Color Organ and the IR controller.

The published version used software based ‘bit banging’ to push the data to the LED’s. Future versions will use the FastSPI library, which now works with the current Arduino environment. Here’s a test circuit:

www.tuline.com/dru/content/led-strip-test

Color Organ

A graphics equalizer chip called the MSGEQ7 provides data on 7 frequency bands, whereby you send an analog signal (ie iPod) into the MSGEQ7, and sequentially clock out values on another pin for each of these frequency bands. These values can then be fed into the light show software. Here’s the test circuit:

www.tuline.com/dru/content/colour-organ

InfraRed Control

An infrared receiver called a KSM-603LM has a digital output that can be fed to an Arduino. There is a software library by Ken Shirriff that can decode the output of a remote controller. Since the library doesn’t decode ALL IR devices, I programmed a universal remote to emulate a controller that the library supports. Here’s a link to the IR test circuit:

www.tuline.com/dru/content/infrared-circuit

Full Test

Here’s the setup as of July, 2012:

Although I’m publishing my current code, I plan to re-write it to support the FastSPI library as well as provide increased IR responsiveness and add additional sequences, such as a persistence of vision routine. Oh, and the MSGEQ7 functionality hasn’t been added yet.

In the meantime, here’s the first publicly available version of the code:

This software controls one or more WS2801 based LED's and uses an MSGEQ7 to respond to music as well
as supporting an IR remote control.

None of the signals uses PWM or analog and should be able to be ported over to a Raspberry Pi.

WS2801 notes

Each IC has its own internal clock so that it can do all the PWM for that specific LED for you. Each IC
requires 24 bits of data. This means you can have 256 levels of red, 256 of blue, and 256 levels of green for each RGB LED.

To control the chips/strip, you clock in data continually. Each IC automatically passes the data onto
the next IC. Once you pause for more than 500us, each IC 'posts' or begins to output the colour data
you just clocked in. So, clock in (24bits * 32LEDs = ) 768 bits, then pause for 500us. Then
repeat if you wish to display something new.

In order to use the IR, which allows me to have a list of sequences, I need to support nested structures or an array of a structure or something.
Just need to learn how to use them. Term may be called nested structures.

long strip_colours[NUM_LEDS]; // Array of values for the strip colours

// Innovage Jumbo Universal Remote - Sony VCR Code 004
unsigned long keydown = 0; // Used to determine if key is pressed or not
unsigned long oldmillis = 0; // Used to slow down the repeat speed of the keys
int irchoice = 0; // Current set to be displayed, values 0 - 9

// Generic sequencing variables
int sequence_count = 0; // This counter determines which sequence we are on
int num_count = 0; // This counter determines how many times we've gone through each individual sequence

memset(strip_colours,0,sizeof(strip_colours)); // Clear the LED array
post_frame(); // Push the current colour frame to the strip

Serial.begin(9600);

} // end of setup()

void loop() {
sequencer();

if (miseq[irchoice][sequence_count].seqtype !=0) { // Only post a frame if seqtype is !=0
post_frame(); // Push the current colour frame to the strip
delay(miseq[irchoice][0].seqdel); // And delay a bit to slow it down (synchronize to the first in the list)
}