Christmas Lighting Project

Hello,

I am trying to write a program that will control multiple strands of christmas lights in time with music. Basically I am going to use the arduino outputs to flip relay switches that will control the christmas lights. But for right now, its easier to just use Led’s to time the lighting with the music, as I have already proven I can use the relays to control the christmas lights.

The problem that I am having came when I started to write the introduction sequence for the song for a second LED. I had already timed up the first LED for about 30 seconds of the song and wanted to start with the second and realized I couldn’t do it the way I was currently timing the first LED. Here is my program thus far (I am a noob programmer, so I am sure there are easier ways to do a lot of the things that I am doing):

int ledpin = 9;
int ledpin2 = 10;
int startpin = 6;
int val = 0;
float a = 431;
float b = 214.875;
int c = 214;
int x = 0;
int y = 0;
int z = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(ledpin, OUTPUT);
  pinMode(startpin, INPUT);
  pinMode(ledpin2, OUTPUT);
  digitalWrite(ledpin, LOW);
  digitalWrite(ledpin2, LOW);
}

void loop()
{
  val = digitalRead(startpin);
  Serial.println(val);
  if(val == HIGH)
    {
      for(x = 0; x <= 2; x++)
      {
        for(y = 0; y <= 2; y++)
        {
        digitalWrite(ledpin, HIGH);
        delay(a);
        digitalWrite(ledpin, LOW);
        delay(420);
        digitalWrite(ledpin, HIGH);
        delay(319);
        digitalWrite(ledpin, LOW);
        delay(325);
        digitalWrite(ledpin, HIGH);
        delay(175);
        digitalWrite(ledpin, LOW);
        delay(41);
        }
        
        digitalWrite(ledpin, HIGH);
        delay(a);
        digitalWrite(ledpin, LOW);
        delay(420);
        digitalWrite(ledpin, HIGH);
        delay(429/2);
        digitalWrite(ledpin, LOW);
        delay(429/2);
        digitalWrite(ledpin, HIGH);
        delay(429/2);
        digitalWrite(ledpin, LOW);
        delay(429/2);
        
        for (y = 0; y <= 2; y++)
       { 
          digitalWrite(ledpin, HIGH);
          delay(a);
          digitalWrite(ledpin, LOW);
          delay(420);
          digitalWrite(ledpin, HIGH);
          delay(319);
          digitalWrite(ledpin, LOW);
          delay(325);
          digitalWrite(ledpin, HIGH);
          delay(175);
          digitalWrite(ledpin, LOW);
          delay(41);
       }
        
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
      }

    }
  delay(100);
}

What I wanted to have running during this entire loop was this:

for (z = 0; z <= 48; z++)
      {
        digitalWrite(ledpin2, HIGH);
        delay(c);
        digitalWrite(ledpin2, LOW);
        delay(c);
        digitalWrite(ledpin2, HIGH);
        delay(c);
        digitalWrite(ledpin2, LOW);
        delay(c);
      }

(tags added by moderator)
Does anyone have any ideas, or can this even be done?

Plz, select your code and hit a button #.

Don't use delay, look into example BlinkWithoutDelay

int ledpin = 9;
int ledpin2 = 10;
int startpin = 6;
int val = 0;
float a = 431;
float b = 214.875;
int c = 214;
int x = 0;
int y = 0;
int z = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(ledpin, OUTPUT);
  pinMode(startpin, INPUT);
  pinMode(ledpin2, OUTPUT);
  digitalWrite(ledpin, LOW);
  digitalWrite(ledpin2, LOW);
}

void loop()
{
  val = digitalRead(startpin);
  Serial.println(val);
  if(val == HIGH)
    {
      for(x = 0; x <= 2; x++)
      {
        for(y = 0; y <= 2; y++)
        {
        digitalWrite(ledpin, HIGH);
        delay(a);
        digitalWrite(ledpin, LOW);
        delay(420);
        digitalWrite(ledpin, HIGH);
        delay(319);
        digitalWrite(ledpin, LOW);
        delay(325);
        digitalWrite(ledpin, HIGH);
        delay(175);
        digitalWrite(ledpin, LOW);
        delay(41);
        }
        
        digitalWrite(ledpin, HIGH);
        delay(a);
        digitalWrite(ledpin, LOW);
        delay(420);
        digitalWrite(ledpin, HIGH);
        delay(429/2);
        digitalWrite(ledpin, LOW);
        delay(429/2);
        digitalWrite(ledpin, HIGH);
        delay(429/2);
        digitalWrite(ledpin, LOW);
        delay(429/2);
        
        for (y = 0; y <= 2; y++)
       { 
          digitalWrite(ledpin, HIGH);
          delay(a);
          digitalWrite(ledpin, LOW);
          delay(420);
          digitalWrite(ledpin, HIGH);
          delay(319);
          digitalWrite(ledpin, LOW);
          delay(325);
          digitalWrite(ledpin, HIGH);
          delay(175);
          digitalWrite(ledpin, LOW);
          delay(41);
       }
        
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
        digitalWrite(ledpin, HIGH);
        delay(b);
        digitalWrite(ledpin, LOW);
        delay(b);
      }

    }
  delay(100);
}

sorry about that

Don't sweat the missing code tags, lots of people miss them the first time.

Syntax question - I don't think you can you float delays: float b = 214.875; and things like this: delay(429/2);

I thought you were limited to integer values:

Syntax delay(ms)

Parameters ms: the number of milliseconds to pause (unsigned long)

If you need 1/2 millisecond delays, I think you would have to do it as: delayMicroseconds (500) to get delay(0.5) for instance.

Also, relays will take a beating in this application. Can you use transistors instead? What kind of lights are you switching?

... everything CrossRoads said, and ... move away from using delay(), especially when handling multiple LEDs/lights.

Just was thinking a little about it, even you follow advise and get rid off delay functions in your code, it still would be as hell contrproductive to generate right led-light timing sequence for every led for every song and then synchonize it all together! Better way to use analog input connected to audio signal line and give work order to arduino to do all this stuff. There is an example: http://fftarduino.blogspot.com/2011/02/color-organ-spectrum-analyzer-on.html or this: http://www.loneoceans.com/labs/arduinolights/

CrossRoads: Also, relays will take a beating in this application.

He might have a solid-state relay. I got one in the mail the other day but, due to chaos here, haven't tested it yet.

I agree though about not trying too hard with timing. Some low-pass filters (I don't know personally how to do this) wired up to analog pins might give you the "beat". Or some fast Fourier transforms on the audio signal, perhaps.

I am thinking myself of getting some LED "ropes" and trying to make a nice seasonal effect from them ... somehow.

Idk if it just rounds off the decimals in the delay() operation, but they were working fine on the small scale LED testing I was doing. I have everything matched up and running with just one LED. My friend, who knows a little bit more about modifying music than I do, mentioned doing something with low-pass filters.

But for now, I think I am just going to resort to the tedious job of combining if statements with the millis function to millisecond by millisecond modify each individual LED. I'm on break from college, so i've got some time ;)

Also, I was using regular relays. I had considered using MOSFETs down the road to get an analog signal to my strands of christmas lights by using PWM as the output.

You could simplify that I think my making a 2-dimensional array, with the time as one element and the LED to turn on/off as the other.
Then write a small loop to read the next time to be added to the current millis() to watch for to do something.
The LED element could be more complex even, each bit on a 16-bit int could represent a light, you could then do a bunch of digitalWrites hi/lo to each output based on the bit, or direct port manilulation, or a for_next loop to mask off all but 1 bit & write that bit high /low to the pin, read from an array of pins. I posted something like that a day or so ago.