Blink Multiple Leds at Different Rates, 1 Function, No Delay

13,480

14

21

Introduction: Blink Multiple Leds at Different Rates, 1 Function, No Delay

About: Apprentice Maker

In this Instructables we will go step-by-step from the standard BlinkWithoutDelay sketch to a single function that we can recall for every leds we have.

Required:

  • Arduino Board
  • Arduino IDE installed
  • at least 2 Leds
  • 2 Current Limiting Resistors
  • Breadboard and Jumper Wires

If you want just to read the final code jump to the final step.

Connect the hardware like in the picture and open the Arduino IDE.

Step 1: From BlinkWithoutDelay to a Single Function

Here is a short example of the standard sketch that use millis() instead of Delay().

#define blueLed 3

unsigned long previousMillis = 0;        // stores last time Led blinked

long interval = 100;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(blueLed, OUTPUT);

}

void loop() {
  if (millis() - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = millis();
    digitalWrite(blueLed, !digitalRead(blueLed)); //change led state

  }

}

And this is how we can compress it in a function, with some limitation yet.

#define blueLed 3

void setup() {
  pinMode(blueLed, OUTPUT); //pin3 Output
}
void loop() {
  BlinkBlue(200); //the led will blink every 200ms

}
void BlinkBlue (int interval){ 
   static long prevMill=0; //prevMill stores last time Led blinked
   if (((long)millis() - prevMill) >= interval){ 
   prevMill= millis(); //stores current value of millis()
    digitalWrite(blueLed, !digitalRead(blueLed)); 
  }

With this function we dont need to declare any variables except the led pin and they can have different interval but we can't use it for more than one led. Every led must have his own function, pretty annoying:

#define blueLed 3
#define greenLed 2


void setup() {
  pinMode(blueLed, OUTPUT); //pin3 Output
  pinMode(greenLed, OUTPUT); //pin2 Output
}

void loop() {
  BlinkGreen(100);
  BlinkBlue(200); 
}
void BlinkBlue (int interval){
   static long prevMill = 0;
   if (((long)millis() - prevMill) >= interval){ 
    prevMill = millis(); 
    digitalWrite(blueLed, !digitalRead(blueLed));
  }
 }
  void BlinkGreen (int interval){
   static long prevMill = 0;
   if ((millis() - prevMill) >= interval){ 
    prevMill = millis(); 
    digitalWrite(greenLed, !digitalRead(greenLed));
 } 
}

In the next step we'll try to write a single function that can be used with multiple leds.

Step 2: A Single Function for Multiple Leds

Finally this is the code for a single function to control multiple Leds.

The previousMillis variable has been sostituited with an array that stores all the previousMillis for each led.

When you call the function you have to insert 3 arguments: led (pin or variable), interval (in ms), array (must be different for each led).

This way every led can have is own interval, minimal variables required (only the array) and Delay is never used.

BLINK FUNCTION FOR MULTIPLE LED

#define blueLed 3   //
#define greenLed 2  //pin for each led

unsigned long previousMillis[2]; //[x] = number of leds

void setup() { 
  pinMode(blueLed, OUTPUT);   
  pinMode(greenLed, OUTPUT);  
}
void loop() {
 BlinkLed(blueLed, 100, 0);   //BlinkLed( which led, interval, one of the stored prevMillis
 BlinkLed(greenLed, 200, 1);  //last parameters must be different for each led
}

void BlinkLed (int led, int interval, int array){   
  
  //(long) can be omitted if you dont plan to blink led for very long time I think
   if (((long)millis() - previousMillis[array]) >= interval){ 
   
    previousMillis[array]= millis(); //stores the millis value in the selected array
   
    digitalWrite(led, !digitalRead(led)); //changes led state
  }
 }
// Written by FabrizioP @ Instructables.com</p>

Thanks for reading. I've bought my first arduino some days ago so if you have tips, hint, critics and everything please comment below!

1 Person Made This Project!

Recommendations

  • Science Fair Challenge

    Science Fair Challenge
  • Tinkercad to Fusion 360 Challenge

    Tinkercad to Fusion 360 Challenge
  • Make It Modular: Student Design Challenge

    Make It Modular: Student Design Challenge

21 Comments

0
Bombaddillo
Bombaddillo

8 months ago

Really useful, thanks. It looks like the LED's stay on for the same length of time as the interval. Is there a way to have different blink durations for each LED? I'd like them just to flash quickly (simulating starship nav lights!!).

0
Bombaddillo
Bombaddillo

Reply 8 months ago

Hi all, thanks for the comments. Managed to get it running the way I wanted. I take no credit or responsibility for this code (I researched a few articles to get my head round how the functions worked. -

Blink LED using millis() with different ON and OFF time Arduino - Robojax
Arduino: Independent On-Off Times with Millis() - Bald Engineer
millis() Tutorial: Arduino Multitasking - Bald Engineer)


const int LEDpin12 = 12;
const long onDuration12 = 50;// OFF time for LED
const long offDuration12 = 1500;// ON time for LED
int LED12State =HIGH;// initial state of LED
long rememberTime12=0;
void setup() {
pinMode(LEDpin12,OUTPUT);
digitalWrite(LEDpin12,LED12State);
}
void loop() {
if( LED12State ==HIGH )
{
if( (millis()- rememberTime12) >= onDuration12){
LED12State = LOW;
rememberTime12=millis();// remember Current millis() time
}
}
else
{
if( (millis()- rememberTime12) >= offDuration12){
LED12State =HIGH;// change the state of LED
rememberTime12=millis();// remember Current millis() time
}
}
}

Cheers,

Bombaddillo

0
FabrizioP
FabrizioP

Reply 8 months ago

Do you mean different ON and OFF time for each led?

0
DUPLICATE_HOHOHE
DUPLICATE_HOHOHE

Reply 8 months ago

Yes, I would like to add one more led, different on/off time for all three, and also have one start in the off position . In other words I want the start up in off position, delay, and than turn led on.

0
FabrizioP
FabrizioP

Reply 8 months ago

the easiest way that comes in my mind is to nest another millis loop in the function with another variable interval "intervalOFF" and in instead of writing !digitalRead use the standard write 0 write 1 in each loop

0
DUPLICATE_HOHOHE
DUPLICATE_HOHOHE

Reply 8 months ago

Thanks for quick reply, will try.

0
hohohe
hohohe

8 months ago

trying to add 2 more leds (4) to your project, not working out. Can you offer any help

0
FabrizioP
FabrizioP

Reply 8 months ago

Well it work for any number or leds. The first thing that comes in my mind is some problem regarding the array. Consider that any array start from number 0 and so on. How is it not working? Just the two extra led not blinking?

0
ArcAiN6
ArcAiN6

Question 1 year ago on Step 2

Would it be possible with this method, to store an array of blink patterns for each LED?
so, instead of using a single int interval and repeat it over and over.. i could have an array of
integers and increment through them.. so...

unsigned long intervals1[] = {100,200,100,200,100,500,50,500,50};
in this case, every other number would be the off position.. i .e. on for 100, off for 200, on for 100... .. ... .. .

0
FabrizioP
FabrizioP

Reply 1 year ago

sure, why not!
Remember to declare it as an array while declaring the function and you should add a loop to increment the array to the next value

0
nickglobal101
nickglobal101

2 years ago

Thanks so much for this! Have been searching for a way to independently delay two functions without delay and this was such an elegant solution!

0
FabrizioP
FabrizioP

Reply 2 years ago

Thank you so much! Feel free to improve it anyway you want!

0
rolandblais
rolandblais

3 years ago

Thanks for this! I was manipulating some leds but couldn't figure out how to have them stay illuminated for the defined durations - this line "digitalWrite(blueLed, !digitalRead(blueLed)); //change led state" was super helpful!

0
JoshK36
JoshK36

4 years ago

This has been very helpful to me. Can't thank you enough

0
FabrizioP
FabrizioP

Reply 4 years ago

Glad to hear it! thanks to you!

0
wolft4292
wolft4292

6 years ago

Thanks. Have different project on my board but will try it soon.

0
wolft4292
wolft4292

6 years ago

You left some Spanish in there. No understand.

Thanks, Wolf

0
FabrizioP
FabrizioP

Reply 6 years ago

Sorry! I'm going to correct it asap! And it's italian btw. Thanks to you!

0
FabrizioP
FabrizioP

Reply 6 years ago

Try now, every time I edit an Instructables the code get mixed with some tag and formatting code, so if it doesn't work feel free to ask here!