LED array blink one led at a time

Hi all,

Can someone please point me in the right direction as I just can’t get my head around my problem. I have three led’s in an array and want to blink these led’s randomly (just one led lit at a time) without using delay, I have tried to adapt the “blink without delay” example and just can’t get it to run properly. So any guidance on how to remove the delay from my posted sketch will be very welcome.

int LEDpins[] = { 3, 4, 5 };
 int time = 100;
 int j;

 void setup()
 {
  
  for (int i = 0; i < LEDpins[i]; i++)
    pinMode(LEDpins[i], OUTPUT);
  
 }

 void loop(){

  j = random(3);
  digitalWrite(LEDpins[j], HIGH);
  delay(time);
  digitalWrite(LEDpins[j], LOW);
  delay(time);
  
  }

have tried to adapt the "blink without delay" example

so, post that code

Pros:

  • You use arrays!
  • you try to loop it
  • You know you don’t want to use delay

Cons:

for (int i = 0; i < LEDpins[i]; i++)

Does not what you want. Now you loop from 0 to some random numer because you overflow the array. Use:

for (int i = 0; i < sizeof(LEDpins)/sizeof(LEDpins[0]); i++)

Or make ledpins a byte and skip the “/sizeof(LEDpins[0])”

  • Give the random a random seed. Otherwise it will be random be the same every time you start the arduino
  • Fix the indentation, the code is all over. Press ctrl+T

I changed the code a bit, now it show be a bit easier to use blink without delay :wink:

const byte LedPins[] = { 3, 4, 5 }; //cammel case is preferred
int time = 100;
//int j; //no need to be global. Also, a single character variable NEVER has a reason to be global

void setup()
{
  for (byte i = 0; i < sizeof(LedPins); i++)
    pinMode(LedPins[i], OUTPUT);
}

void loop(){
  byte j = random(3);
  
  for (byte i = 0; i < sizeof(LedPins); i++){
    digitalWrite(LedPins[i], i == j);
  }
  delay(time);
}

PS, do you want the leds to be off in between?

This might give you some ideas.

const byte red = 5, grn = 6, yel = 7; // LED pins
const byte dur = 30; // duration of blink
const int mn = 500, mx = 2000; // interval between blinks
unsigned long strt1, strt2, strt3;
unsigned long ival1, ival2, ival3; // interval between blinks
byte cnt;

void setup() {
  Serial.begin(9600);
  Serial.println (F(__FILE__"\n"));
  pinMode(red,OUTPUT);
  pinMode(grn,OUTPUT);
  pinMode(yel,OUTPUT);
  strt1 = strt2 = strt3 = millis();
}

void loop() {
  if(cnt > 25){
    randomSeed(analogRead(5)); // new seed after 25 red blinks
    cnt = 0;
  }  
  if(millis() - strt1 > ival1) digitalWrite(red,HIGH);
  if(millis() - strt1 > ival1 + dur){
    digitalWrite(red,LOW);
    ival1 = random(mn,mx);
    strt1 = millis(); cnt++;
  }
  if(millis() - strt2 > ival2) digitalWrite(grn,HIGH);
  if(millis() - strt2 > ival2 + dur){
    digitalWrite(grn,LOW);
    ival2 = random(mn,mx);
    strt2 = millis();
  }
  if(millis() - strt3 > ival3) digitalWrite(yel,HIGH);
  if(millis() - strt3 > ival3 + dur){
    digitalWrite(yel,LOW);
    ival3 = random(mn,mx);
    strt3 = millis();
  }

}

Gammon tip 1, once you start using post-fixes it's time to use arrays....

Hi all,

My apologies for late reply as I was out of town due to work commitments. I have tried to implement “septillion” suggestion and have had success of sorts with my code posted below. It blinks one led at a time with just one led on at any given moment. However the interval between blinks is not consistent. Although this is not important to my project i would like to know the reason why this is happening. Thank you all for your help.

unsigned long previousMillis = 0;
const long interval = 250;
const byte LedPins[] = { 3, 4, 5 };

void setup() {

  Serial.begin(9600);
  for (byte i = 0; i < 3; i++)
    pinMode(LedPins[i], OUTPUT);
  Serial.print("Start new sequence");
  randomSeed(analogRead(A0));
}

void loop() {

  byte randomnumber = random(3);
  Serial.print("The random number is = ");
  Serial.println(randomnumber);
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    //previousMillis = currentMillis;
    for (byte i = 0; i < 3; i++) {
      digitalWrite(LedPins[i], i == randomnumber );//, !digitalRead(LedPins[i]);
      previousMillis = currentMillis;
    }
  }
}

Remove the serial prints or put them inside the if() statement so it isn't spewing out text thousands of times per second.

For more precise timing, add the interval to previousMillis instead of the current time. This is only a tiny error. You won't detect any timing differences just by looking at it.

MorganS thank you for reply,

Can you explain how to add interval to previousMillis instead of the current time as I do not understand.

previousMillis += interval;

cnc0504:
Hi all,

Can someone please point me in the right direction as I just can't get my head around my problem. I have three led's in an array and want to blink these led's randomly (just one led lit at a time) without using delay, I have tried to adapt the "blink without delay" example and just can't get it to run properly. So any guidance on how to remove the delay from my posted sketch will be very welcome.

loop() {
  if no led is on, and it's time to turn one on
    pick an LED at random
    turn it on
    make note of the fact that a LED is now on
    make note of the time
    make note of which LED go turned on
 
  if an led is on, and it's time to turn it off
    turn it off (using the note we made earlier)
    make note of the fact that all the LEDs are now off
    make note of the time it got turned off
}

In order to make note of a fact so that the next iteration of loop() can remember it, it needs to be put in a global or static variable.