Arduino PWM Shield Icicle Lights Prototype
It's getting close to that time of year again. Time to put up Christmas lights. This year I kind of wanted to go a little overboard and have all the lights RGB and Arduino controlled. What I've come up with is a project that's going to use a PWM Shield, RTC, and Wifi/Xbee shield.
Why do I need all that hardware to control lowly Christmas lights? I really want to be able to have some cool effects run, as well as have them turn on and off automatically. As a kicker I also want to be able to control them via my phone (I will admit that's a bit overkill), but the end result is going to be pretty cool.
The main shield behind this project is the PWM Shield. It's basically a shield that has two TLC5940's daisy chained together. For the project I'll be using two (each shield can be daisy chained to another shield using a simple jumper wire).
In the photo above you can see that I've hooked up the RGB LED's to the shield. Each LED required 3 channels and each one is hooked up in order. ie. Channel 0 = Red, Channel 1 = Green, Channel 2 = Blue, Channel 4 = Red etc.
Above you can see a shot of the prototype. I've only got 6 lights hooked up (because I need more jumper wires as they make nice sockets for the led's); however, adding more led's is simply a matter of changing one int within the code.
Video
Next Steps
Sometime in the near future I'm going to finish the string and add in a RTC and either a Wifi or Xbee shield (not sure about the wifi because their shield may use some of the pins that the PWM shield uses). Once that's done I'll make a little webapp so I can control everything from my phone (which of course I'll release :-) ).
If you have any questions, comments or suggestions I'm all ears. I'd love to hear some ideas for sequences.
The Code:
#include "Tlc5940.h"
int green;
int blue;
int red;
boolean flipflop = true;
int num_rgb = 6;
int num_channels = (num_rgb * 3) - 1;
int maxbrightness = 1000;
int seq1_red = 1000;
int seq1_green = 0;
int seq1_blue = 50;
int seq2_red = 0;
int seq2_green = 1000;
int seq2_blue = 0;
/*
Red = 1
Green = 2
Blue = 3
*/
int fadein_color = 1;
int fadeout_color = 2;
int color_min = 0;
int color_max = 1000;
void setup()
{
/*You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
Tlc.init(0);
Serial.begin(9600);
}
void loop()
{
for(int i=0; i<10; i++){
blink_alternate();
}
for(int i=0; i<4;i++){
fade_through_flipflop();
}
for(int i=0; i<4;i++){
fade_through();
}
}
void blink_alternate(){
Tlc.clear();
if(flipflop == true){
for(int i=1; i<=num_rgb; i++){
red = (i * 3) - 3;
green = (i* 3) - 2;
blue = (i * 3) - 1;
if(i % 2){
Tlc.set(green, seq1_green);
Tlc.set(blue, seq1_blue);
Tlc.set(red, seq1_red);
}else{
Tlc.set(green, seq2_green);
Tlc.set(blue, seq2_blue);
Tlc.set(red, seq2_red);
}
}
flipflop = false;
}else{
for(int i=1; i<=num_rgb; i++){
red = (i * 3) - 3;
green = (i* 3) - 2;
blue = (i * 3) - 1;
if(i % 2){
Tlc.set(green, seq2_green);
Tlc.set(blue, seq2_blue);
Tlc.set(red, seq2_red);
}else{
Tlc.set(green, seq1_green);
Tlc.set(blue, seq1_blue);
Tlc.set(red, seq1_red);
}
}
flipflop = true;
}
Tlc.update();
delay(1000);
}
void fade_through_flipflop(){
Tlc.clear();
if(flipflop == true){
for(int j=0; j<=maxbrightness; j++){
for(int i=1; i<=num_rgb; i++){
red = (i * 3) - 3;
green = (i* 3) - 2;
blue = (i * 3) - 1;
if(i % 2){
if(fadein_color == 1){
Tlc.set(red, color_min + j);
}else if(fadein_color == 2){
Tlc.set(green, color_min + j);
}else if(fadein_color == 3){
Tlc.set(blue, color_min + j);
}
if(fadeout_color == 1){
Tlc.set(red, color_max - j);
}else if(fadeout_color == 2){
Tlc.set(green, color_max - j);
}else if(fadeout_color == 3){
Tlc.set(blue, color_max - j);
}
}else{
if(fadeout_color == 1){
Tlc.set(red, color_min + j);
}else if(fadeout_color == 2){
Tlc.set(green, color_min + j);
}else if(fadeout_color == 3){
Tlc.set(blue, color_min + j);
}
if(fadein_color == 1){
Tlc.set(red, color_max - j);
}else if(fadein_color == 2){
Tlc.set(green, color_max - j);
}else if(fadein_color == 3){
Tlc.set(blue, color_max - j);
}
}
}
delay(10);
Tlc.update();
}
flipflop = false;
}else{
for(int j=maxbrightness; j>=0; j--){
for(int i=1; i<=num_rgb; i++){
red = (i * 3) - 3;
green = (i* 3) - 2;
blue = (i * 3) - 1;
if(i % 2){
if(fadein_color == 1){
Tlc.set(red, color_min + j);
}else if(fadein_color == 2){
Tlc.set(green, color_min + j);
}else if(fadein_color == 3){
Tlc.set(blue, color_min + j);
}
if(fadeout_color == 1){
Tlc.set(red, color_max - j);
}else if(fadeout_color == 2){
Tlc.set(green, color_max - j);
}else if(fadeout_color == 3){
Tlc.set(blue, color_max - j);
}
}else{
if(fadeout_color == 1){
Tlc.set(red, color_min + j);
}else if(fadeout_color == 2){
Tlc.set(green, color_min + j);
}else if(fadeout_color == 3){
Tlc.set(blue, color_min + j);
}
if(fadein_color == 1){
Tlc.set(red, color_max - j);
}else if(fadein_color == 2){
Tlc.set(green, color_max - j);
}else if(fadein_color == 3){
Tlc.set(blue, color_max - j);
}
}
}
delay(10);
Tlc.update();
}
flipflop = true;
}
}
void fade_through(){
Tlc.clear();
if(flipflop == true){
for(int j=0; j<=maxbrightness; j++){
for(int i=1; i<=num_rgb; i++){
red = (i * 3) - 3;
green = (i* 3) - 2;
blue = (i * 3) - 1;
if(fadein_color == 1){
Tlc.set(red, color_min + j);
}else if(fadein_color == 2){
Tlc.set(green, color_min + j);
}else if(fadein_color == 3){
Tlc.set(blue, color_min + j);
}
if(fadeout_color == 1){
Tlc.set(red, color_max - j);
}else if(fadeout_color == 2){
Tlc.set(green, color_max - j);
}else if(fadeout_color == 3){
Tlc.set(blue, color_max - j);
}
}
delay(10);
Tlc.update();
}
flipflop = false;
}else{
for(int j=maxbrightness; j>=0; j--){
for(int i=1; i<=num_rgb; i++){
red = (i * 3) - 3;
green = (i* 3) - 2;
blue = (i * 3) - 1;
if(fadein_color == 1){
Tlc.set(red, color_min + j);
}else if(fadein_color == 2){
Tlc.set(green, color_min + j);
}else if(fadein_color == 3){
Tlc.set(blue, color_min + j);
}
if(fadeout_color == 1){
Tlc.set(red, color_max - j);
}else if(fadeout_color == 2){
Tlc.set(green, color_max - j);
}else if(fadeout_color == 3){
Tlc.set(blue, color_max - j);
}
}
delay(10);
Tlc.update();
}
flipflop = true;
}
}
