Turning on a sequence of LEDs with a delay between each?

Hi everyone,

I am using the bargraph code from arduino.cc but in response to values from an LDR, not a potentiometer.

I would like to add to the code so that the LEDs turn on and off more slowly when the light levels change dramatically.

For instance, with my current code, the LEDs are off in daylight, but if i cover the LDR so that the values show it is suddenly dark, each of the 12 LEDs plugged in comes on immediately. I would like it so that number one turns on, pause, number two turns on, pause etc. so that it is more of a wave effect down the line of LEDs.

I have tried using the delay function for each instance of the array, with the intention of the code being read as “when the light falls to this level number one turn on. delay. number two turn on. delay. number three turn on.” but this has simply made LEDs 1-4 turn off totally. I have read that delay isn’t the best function to use, but I have never used millis() or any other time function so I would be very grateful of some help.

Here is the basic unedited code:

//ROTATING THROUGH LEDS

//VARIABLES
#define sensor 1
const int nLEDs=24;
int ledPins[nLEDs]={
  2,3,4,5,6,7,8,9,10,11,12,13};
int val=0;
int level=0;


//SETUP
void setup()
{
  for(int i=0; i<nLEDs;i++)
  {
    pinMode(ledPins[i],OUTPUT);
  }
  Serial.begin(9600);
}

//LOOP
void loop()

{
  val=analogRead(sensor);
  Serial.println(val);
  //Value, fromLow, fromHigh, toLow, toHigh
  level=map(val,800,10,0,(nLEDs-1));

  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[i],HIGH);
  }
  delay(10);

  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[i],LOW);
  }
}

And here the same code but showing where I have tried to implement a delay between each LED which is not working:

//ROTATING THROUGH LEDS

//VARIABLES
#define sensor 1
const int nLEDs=24;
int ledPins[nLEDs]={
  2,3,4,5,6,7,8,9,10,11,12,13};
int val=0;
int level=0;
unsigned long timerA


//SETUP
void setup()
{
  for(int i=0; i<nLEDs;i++)
  {
    pinMode(ledPins[i],OUTPUT);
  }
  Serial.begin(9600);
}

//LOOP
void loop()

{
  val=analogRead(sensor);
  Serial.println(val);
  //Value, fromLow, fromHigh, toLow, toHigh
  level=map(val,800,10,0,(nLEDs-1));

  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[i],HIGH);
  }
  delay(10);


  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[1],LOW);
    delay(300);  
    digitalWrite(ledPins[2],LOW);
    delay(300); 
    digitalWrite(ledPins[3],LOW);
    delay(300);
    digitalWrite(ledPins[4],LOW);
    delay(300);   
  }
}  









/*digitalWrite(ledPins[1],HIGH);
 {delay(1000);
 }digitalWrite(ledPins[2],HIGH);
 {delay(1000);
 }digitalWrite(ledPins[3],HIGH);
 {delay(1000);}
 digitalWrite(ledPins[4],HIGH);
 {delay(1000);}
 digitalWrite(ledPins[5],HIGH);
 */
/*digitalWrite(ledPins[1],LOW);
 {delay(1000);
 }digitalWrite(ledPins[2],LOW);
 {delay(1000);
 }digitalWrite(ledPins[3],LOW);
 {delay(1000);}
 digitalWrite(ledPins[4],LOW);
 {delay(1000);}
 digitalWrite(ledPins[5],LOW);
 {delay(1000);}*/

You've got a problem that you've told the compiler you've got more LEDs (24) than you've got output pins.
So, the compiler's going to use pin zero for all the pins you forgot to tell it about.
Hope you're OK with that.

Hi AWOL,

Ah yes, I forgot to change that back to 12, I was experimenting with how differently the LEDs behave with the same LDR values if the arduino thinks there are more of them. Just trying to see if the maths meant that the LEDs would be more sensitive because the values would be spread twice as far…

I don’t know if that makes any sense to anyone, but it makes sense in my head! Just an experiment, will change it back. But yes - I am okay with it.

Do you have any insight in to how I can introduce a delay between the response of each LED?

Did you mean

 for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[i],LOW);
    delay(300);
}

?

That is about the speed at which I want them to turn on/off!

But when I use the piece of code you have just written, it has them blinking on and off in a loop, what I am trying to achieve is for them all to be on, but when exposed to sudden bright light, they go off one by one.

So, in the code which I haven't messed with (the first one I posted in my original question), the LEDs are all on in the dark, but if a bright light suddenly hits the LDR, they all turn off as one. I am trying to amend the code so that they turn off one by one, with a little pause between each.

Does that make sense?

Hi everyone,

I posted earlier about using the bargraph code from arduino.cc but wanting to introduce a delay each time the LED turned on or off in response to LDR values.

Well I haven’t been able to resolve this but I have created a new fun pattern which responds to the LDR values. With the current code (I will paste below), the first 5 LEDs turn off in a looped chase sequence in the dark, and when a light shines on the LDR they stay off completely. So that is LEDs at index numbers 0,1,2,3,4 which are playing by the rules and behaving themselves.

The other 7 LEDs are unresponsive to both the chain sequence of the first 5, and they are unaffected by light levels - they are simply always on.

I know I’m going to get criticism for the way this code is written as i am SURE it is uneccessarily lengthy, but for now I would love to know why the final 7 LEDs of the array are not playing ball!

Thanks for any help.

//ROTATING THROUGH LEDS

//VARIABLES
#define sensor 1
const int nLEDs=12;
int ledPins[nLEDs]={
  2,3,4,5,6,7,8,9,10,11,12,13};
int val=0;
int level=0;
//unsigned long timerA;


//SETUP
void setup()
{
  for(int i=0; i<nLEDs;i++)
  {
    pinMode(ledPins[i],OUTPUT);
  }
  Serial.begin(9600);
}

//LOOP
void loop()

{
  val=analogRead(sensor);
  Serial.println(val);
  //Value, fromLow, fromHigh, toLow, toHigh
  level=map(val,800,10,0,(nLEDs-1));

  //TURN ALL ON
  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[i],HIGH);
  }
  delay(10);

  //BEGIN TO TURN OFF

  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[0],LOW);
    delay(10); 
  } 


  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[1],LOW);
    delay(10); 
  } 

  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[2],LOW);
    delay(10); 
  }

  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[3],LOW);
    delay(10);
  }
  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[4],LOW);
    delay(10);   
  }
  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[5],HIGH);
    delay(10);
  }

  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[6],HIGH);
    delay(10);
  }

  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[7],HIGH);
    delay(10);
  }

  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[8],HIGH);
    delay(10);
  }

  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[9],HIGH);
    delay(10);
  }

  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[10],HIGH);
    delay(10);

  }
  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[11],HIGH);
    delay(10);

  }


}

Because level is 0 so for (int i=0; i<level; i++) never executes. Could it be that?

Now, if only you could explain the purpose of all those for loops.

Did you delete another Thread?

I had just written a reply and when I clicked Post it said it had disappeared.

...R

I did write another thread but it has been moved to a follow on to this thread...! I assume that is a telling off from a moderator. Sorry - I thought it was a sufficiently different topic!

I would love to hear what you have to say though Robin2!

Shpaget - I thought that might be the problem too so I tried changing the value of i and it didn't seem to make any difference, I changed it to a few random values up to 100 and it didn't change anything. The for loops are a final solution in a day spent trying to introduce a delay to each LED when it is turned on or off dependent on LDR values, which took a tangent to this current code. I know its a mess but it works so well for the first 5...!?

But why do only one thing in each for loop when they are made for repetitive tasks?
Wouldn’t this make more sense?

for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[0],LOW);
    delay(10); 
  }

Also, don’t change the value of i, change levels. And read up on for loop. You seem to not understande its function.

Have you used serial.print to see if level is getting values it should?

Thank you Shpaget, and thank you AWOL who gave me the same solution earlier - I have been being an idiot - Yes this does work!

I now just have a FINAL problem, which if anyone can help me with it, I will stop cluttering your wonderful arduino forum for a long time!

So, here is my code now - all messy for loops removed and working like a dream, the only thing I would like to know how to achieve is how to get ALL the LEDs to stay on until the light level is very bright, 800ish, and THEN it starts its sequence of delay until they are all off and stay off until the level falls back to darkness?

I am sure I just need one line of code which means “unless” so it would read - command to keep LEDs on permanently, UNLESS the light levels are extremely high, then all turn off with a delay of 300 between each LED. Because right now it cycles through a chase sequence, I only want it to start the sequence in response to high LDR readings.

The only thing I am missing is the “unless” - can anyone give me any clues?

Here is the updated code:

//ROTATING THROUGH LEDS

//VARIABLES
#define sensor 1
const int nLEDs=12;
int ledPins[nLEDs]={
  2,3,4,5,6,7,8,9,10,11,12,13};
int val=0;
int level=0;
//unsigned long timerA;


//SETUP
void setup()
{
  for(int i=0; i<nLEDs;i++)
  {
    pinMode(ledPins[i],OUTPUT);
  }
  Serial.begin(9600);
}

//LOOP
void loop()

{
  val=analogRead(sensor);
  Serial.println(val);
  //Value, fromLow, fromHigh, toLow, toHigh
  level=map(val,800,10,0,(nLEDs-1));

  //TURN ALL ON
  
  
  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[i],HIGH);
  }
  delay(10);

  //BEGIN TO TURN OFF

  for (int i=0;i<nLEDs; i++)
  {
    digitalWrite(ledPins[i],LOW);
    delay(300); 
  } 
  delay(3240);
}

Try the following variation…

//ROTATING THROUGH LEDS

//VARIABLES
#define sensor 1
const int nLEDs=12;
int ledPins[nLEDs]={
  2,3,4,5,6,7,8,9,10,11,12,13};
int val=0;
int level=0;
int displayed =-1; // STORES LAST DISPLAYED LEVEL
//unsigned long timerA;


//SETUP
void setup()
{
  for(int i=0; i<nLEDs;i++)
  {
    pinMode(ledPins[i],OUTPUT);
  }
  Serial.begin(9600);
}

#define DELAY 500

//LOOP
void loop()

{
  val=analogRead(sensor);
  Serial.println(val);
  //Value, fromLow, fromHigh, toLow, toHigh
  level=map(val,800,10,0,(nLEDs-1));

  //TURN ALL OFF
  for (int i=0; i<level; i++)
  {
    digitalWrite(ledPins[i],LOW);
  }
  
  // UPDATE DISPLAYED ONES AND INTRODUCES A DELAY
  if (level > displayed) {
    displayed++;
    delay(DELAY);// REMOVE THIS IF YOU WANT LEDS TO TURN ON IMMEDIATELY
  } else if(level<display) {
    displayed--;
    delay(DELAY)// REMOVE THIS IF YOU WANT LEDS TO TURN OFF IMMEDIATELY
  }

  //TURN DISPLAYED ON
  for (int i=0; i<displayed; i++)
  {
    digitalWrite(ledPins[i],HIGH);
  }

}

I am not sure I understand what is your final goal. What is the effect you are trying to achieve?

if (level > something high)
  {
    for(int i=0; i<nLEDs;i++)
    {  
     digitalWrite(ledPins[i],LOW);
     delay(300);
    }
  }

That would turn your LEDs off in sequence, but I still don’t understand the purpose.

westminster:
I would love to hear what you have to say though Robin2!

Sorry, I can't remember now and it may have been covered by someone else.

Good reason to keep all the stuff for one project in one Thread.

...R

Robin2 - never mind! Thanks for the thought of help I guess!

Shpaget - you have helped me no end, the piece of code you wrote helped me understand "if" a lot and now I have been able to write the code I wanted all along, perfect - thank you so much.

AWOL - I should have listened to you to begin with..!

rlogiacco - Thank you very much for trying to help, I tried running your code but it didn't quite do what I wanted, it made my LEDs jump around a little, so I concentrated on the if statement Shpaget kindly advised me on, I am very grateful for the time you took to rewrite my code though!

Over and out.