Timing Events?

Hello,

I am trying to create a project in which LEDs will be timed with music. When I plug the arduino in a LED blinks twice signaling to press play on the music. I dont want to use delay but is there any better way to time the LEDs than the code I am using. I feel like the way I am going about it is over complicated and wrong.

This is the method I am using to tell the LEDs when to turn on and off:

 if(currentMillis - previousMillis > (interval + 5000) && currentMillis - previousMillis < (interval + 10000)){

Here is the whole code:

const int blue1 = 13;
const int blue2 = 9;
long previousMillis = 0;
long interval = 0;

//fade stuff
long previousMillis2 = 0;
long interval2 = 10;
int brightness = 0; 
int fadeAmount = 5;

void setup(){
  pinMode(blue1, OUTPUT);
  pinMode(blue2, OUTPUT);
}

void loop(){
  unsigned long currentMillis = millis();

  
  if(currentMillis - previousMillis > (interval + 5000) && currentMillis - previousMillis < (interval + 10000)){
    unsigned long theseMillis = millis();
    
    if(theseMillis - previousMillis2 > interval2){
      previousMillis2 = theseMillis;
      
      analogWrite(blue1, brightness);
      
      brightness = brightness + fadeAmount;
      
      if(brightness == 0 || brightness == 255){
        fadeAmount = -fadeAmount;
      }
    }
  }

  if(currentMillis - previousMillis > (interval + 5000) && currentMillis - previousMillis < (interval + 10000)){
    unsigned long theseMillis = millis();
    
    if(theseMillis - previousMillis2 > interval2){
      previousMillis2 = theseMillis;
      
      analogWrite(blue2, brightness);
      
      brightness = brightness + fadeAmount;
      
      if(brightness == 0 || brightness == 255){
        fadeAmount = -fadeAmount;
      }
    }
  }
}

Any help is appreciated!:slight_smile:

Thank you,
Eddie

If you're only doing 2 blinks and it only occurs as you boot up. Just do it in your setup and use the delays. It's simple, effective and efficient.

Well the first two blinks are just the first part of what I hope to be a long sequence to about a 30 second song. I just stopped there to see if there was an easier way to triggering LEDs on time instead of using...

  if(currentMillis - previousMillis > (interval + 5000) && currentMillis - previousMillis < (interval + 10000)){

Is there better way to trigger LEDs that are to be synced with music than this?

So if they're to be synched with music, why are you looking at millis? Shouldn't it be a value on an analog input? (ie a feed from the sound source)

No synced with music as in each LED has a predetermined time to come on and turn off like a light show. Its a "programmed" light show.

Ah right.
So you want to be able to write a "score" for the lights, so to speak? I think I could come up with something for that. How many LEDs involved?

Is there better way to trigger LEDs that are to be synced with music than this?

Consider putting the on times in an array and using a for loop to iterate through them.

Your program seems to fade an LED up and down for 5 seconds then do the same with a second LED. Is that what it does and that what you want ? Do the LEDs need to fade up and down or could they just come on ? How many LEDs are in the final project ?

An observation. The interval variable is set to zero and never changes so it could be removed from your code.

Yeah that sounds right. That would be awesome if you could help. There are 15 LEDs.

15 eh? This'll take a little time but I have an idea brewing.

Watch this space :slight_smile:

You can also use TimedAction library :slight_smile:

you could try like 5 LEDs just get a concept if you want. In the end I have 10 TLC5940's that id like to use to get a 100 LEDs but thats ways away lolol! Right now I just have a few LEDs pluged directly into arduino for testing and expermenting with this idea. Anyway thank you for your help Ill check in again here soon!

Thank you Sonic656 Ill look into that too right now!!

Eddie04:
Yeah that sounds right. That would be awesome if you could help. There are 15 LEDs.

Do the LEDs need to fade on and off as in your program or could they just snap on/off ? Will there only be one LED on at a time or could the time periods overlap such that 2 or more are on at the same time ?

Yes eventually I need them to fade on and off however some will also snap on and off. Sometimes there will only be one on and other times there might be multiple on at the same time. But if something is not possible Ill take whatever works!:slight_smile:

Your requirements are becoming clearer and more complicated.

I suggest that you draw a diagram with LEDS down the lefthand side and seconds across the top with a bar in the LED rows indicating when the LED should be on, something like this

         0          1          2          3          4          5
LED0     XXXXXXXXXXX           XXXXXXXXXXX           XXXXXXXXXXX
LED1                XXXXXXXXXXXXXXXXXXXXXX
LED2     XXXXXXXXXXXXXXXXXXXXXXX
LED3                XXXXXXXXXXXX 
LED4                                      XXXXXXXXXXXXXXXXXXXXXX

This will give you (and us) something to work with. If you post it here use [code] tags so that the text is in a fixed width font.

OK Here's my idea. Basically all of your flashes will be defined in a big array,
For every flash we store:
The pin that the LED is attached to
The start time (in milliseconds from the start of the song
The attack (this is how long in milliseconds that it takes to reach full power from the start of the flash)
The decay (this is how long, it takes in milliseconds to fade out back out again.)

It's still a bit rough but with some modifications we could also include routines for regular patterns (instead of single flashes).

We could also build a little interface to get our input from a midi keyboard, rather than tediously defining every single flash

It doesn't matter which pins you use, as long as you don't go over 15 distinct pins. The data I've put in should (very approximately) flash "bah bah black sheep have you any wool" (on pin 12)

//This just defines the structure that each LED event takes
typedef struct
{
  int pin;
  unsigned long when;//millis from start of song
  unsigned long attack;//how quick to go from 0 to full brightness
  unsigned long decay;//how long to take to go from full power back to 0         
}
LedFlash;         

void getLEDEvent(int index,LedFlash* pointer);

//this holds the status activity of each LED 
//we initialise it here to ALL leds inactive
LedFlash channel[15]={
  0,0,0,0,  0,0,0,0,  0,0,0,0,  0,0,0,0,  0,0,0,0,
  0,0,0,0,  0,0,0,0,  0,0,0,0,  0,0,0,0,  0,0,0,0,
  0,0,0,0,  0,0,0,0,  0,0,0,0,  0,0,0,0,  0,0,0,0
};

//This is where the data for all the flashes goes
//I've only put a bit of sample data in and it's just using pin 13 (because I haven't got any more LEDS handy)
const LedFlash PROGMEM song[] = {

  //Pin, When,   fadeUp, FadeDown
  13,    2000,   100,     400,   
  13,    2500,   100,     400,   
  13,    3000,   100,     400,  
  13,    3500,   100,     400,  
  13,    4000,   50,      190,  
  13,    4250,   50,      190,   
  13,    4500,   50,      190,   
  13,    4750,   50,      190,   
  13,    5000,   400,     900,  
  //Add more lines like those above using your own pins and data
  //The next two lines are the end marker of the song
  0,0,0,0
} 
;//End of song data

void setup()
{
}

//Bookmark used to index through the flash events
int songIndex=0;

void loop()
{
  int n;
  LedFlash tempFlash;
  unsigned long t=millis();
  getLEDEvent(songIndex,&tempFlash);
  while((tempFlash.when<t)&&(tempFlash.pin))
  {//find a vacant channel (or one already used for this pin) for this flash
    for(n=0;n<15;n++)
      if((channel[n].pin==0)||(channel[n].pin==tempFlash.pin))//or a channel being used by this pin
      {
        channel[n]=tempFlash;
        break;
      }   
    getLEDEvent(++songIndex,&tempFlash);
  }  

  maintainFades();

}


//This function moves a flash event from PROGMEM space into ram
void getLEDEvent(int index,LedFlash* pointer)
{
  pointer->pin=pgm_read_byte(&(song[songIndex].pin));
  pointer->when=pgm_read_word(&(song[songIndex].when));
  pointer->attack=pgm_read_word(&(song[songIndex].attack));
  pointer->decay=pgm_read_word(&(song[songIndex].decay));
}

//This function works out how bright every LED should be at the moment and updates them
void maintainFades()
{
  byte brightness=0;
  unsigned long elapsed;
  unsigned long t=millis();
  int n;
  for(n=0;n<15;n++){
    if(channel[n].pin)
    {
      if (t>channel[n].when)//check if this flash has started yet
      {
        elapsed=t-channel[n].when;//work out how long ago this flash started
        if(elapsed<channel[n].attack)//if it hasn't reached full power yet
        {
          brightness=map(elapsed,0,channel[n].attack,0,255);//work out it's current power
        } 
        else
        {
          elapsed -= channel[n].attack;//work out when it started fading
          if(elapsed < channel[n].decay)  //if it hasn't finished fading yet
          {
            brightness=map(elapsed,0,channel[n].decay,255,0);//work out how bright it should be now
          }       
        }
        analogWrite(channel[n].pin,brightness); 
      }//end of if flash started
    }//end if(channel pin)
  }//end for loop
}

BTW Each flash is independent so you can have flashes on separate pins starting at the same time, or overlapping with each other.