Arduino - multiple LEDs with different delays

Hi all

I’m trying to write code to get 3 LEDs flashing independently, each with a different ON and OFF period.

For example:

LED1: ON for 25 ms, OFF for 500 ms

LED2: ON for 50 ms, OFF for 800 ms

LED3: ON fo 100 ms, OFF for 300 ms

So far I have set up the hardware: 3 LEDs on digital pins 6, 7 and 8 using my Arduino UNO board and a breadboard.

Code-wise I understand that I can’t use the “delay” function because it causes the whole system to delay i.e. causes ‘blocking’. At the moment I’m using the millis() function. My problem is that at the moment my code causes LED1 to turn ON for 25 ms and off for 25 ms, LED2 turns ON for 50 ms and off for 50 ms etc. So I need to somehow alter the OFF period independently.

In summary: I need a new approach or an alteration to my code to be able to independently change the ON and OFF periods for each of my LEDs independently.

Here is my code so far:

// Which pins are connected to which LED
const byte LED1 = 6;
const byte LED2 = 7;
const byte LED3 = 8;

// Assigning delays. 
const unsigned long LED1_interval = 25;
const unsigned long LED2_interval = 50;
const unsigned long LED3_interval = 100;

// Declaring the variables holding the timer values for each LED. 
unsigned long LED1_timer;
unsigned long LED2_timer;
unsigned long LED3_timer;

// Setting 3 digital pins as output pins and resetting timer
void setup () 
  {
  pinMode (LED1, OUTPUT);
  pinMode (LED2, OUTPUT);
  pinMode (LED3, OUTPUT);
  LED1_timer = millis ();
  LED2_timer = millis ();
  LED3_timer = millis ();
  }  // end of setup

//LED1 loop that turns it ON if it is OFF and vice versa
void toggle_LED1 ()
  {
   if (digitalRead (LED1) == LOW)
      digitalWrite (LED1, HIGH);
   else
      digitalWrite (LED1, LOW);

  // remember when we toggled it
  LED1_timer = millis ();  
  }  // end of toggleLED_1

//LED2 loop
void toggle_LED2 ()
  {
   if (digitalRead (LED2) == LOW)
      digitalWrite (LED2, HIGH);
   else
      digitalWrite (LED2, LOW);

  // remember when we toggled it
  LED2_timer = millis ();  
  }  // end of toggle_LED2
  
  //LED 3 loop
 void toggle_LED3 ()
  {
   if (digitalRead (LED3) == LOW)
      digitalWrite (LED3, HIGH);
   else
      digitalWrite (LED3, LOW);

  // remember when we toggled it
  LED3_timer = millis ();  
  }  // end of toggle_LED3

void loop ()
  {

  // Handling the blink of LED1.
  if ( (millis () - LED1_timer) >= LED1_interval)
     toggle_LED1 ();

  // Handling the blink of LED2.
  if ( (millis () - LED2_timer) >= LED2_interval) 
    toggle_LED2 ();
    
 // Handling the blink of LED3.
  if ( (millis () - LED3_timer) >= LED3_interval) 
    toggle_LED3 ();
    
/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

}  // end of loop

Any help would be greatly appreciated because I’m very new to this!

Thanks!

I would research finite state machines.

now = millis();

if (now > led1on) {
  turn on led1
  led1off = now + time you want led1 on
}
if (now >led1off) {
  turn off led1
  led1on = now + time you want led1 off
}
...

I was gonna say same thing.

Structure the code to keep the loop running, maintaining a “clock” interval … with (if) statements to hook the loop to trigger flash intervals, only when the “clock” variable is right.

But as for duration for flash itself, and not hanging up the “clock” loop waiting for flash duration to expire… need a cup or two more coffee for that…maybe my methodology would be rely on hardware for the duration for LED flash by simple use of measured capacitor…have each LED paired with its own capacitor to regulate approximate flash duration…this way the “clock” loop is not interrupted. //

CircuitBurner:
But as for duration for flash itself, and not hanging up the “clock” loop waiting for flash duration to expire… need a cup or two more coffee for that…maybe my methodology would be rely on hardware for the duration for LED flash by simple use of measured capacitor…have each LED paired with its own capacitor to regulate approximate flash duration…this way the “clock” loop is not interrupted. //

I think the method you're looking for is the modulo function.

http://www.arduino.cc/en/Reference/Modulo

The way I’d code it is have the loop() run at the time resolution needed, perhaps every msec. Then ask, for each LED, whether the present time indicates whether the LED should be on or off. To do that you need to compute the LED period from the given ON and OFF times, PERIOD = ON + OFF.

Now use the modulo function and compute the “M_time”; M_time = millis() % PERIOD. And then condition the ifs() to turn on and off the LEDs like the below. So for each LED :

PERIOD = ON_time + OFF_time;

M_time = millis() % PERIOD;
if(M_time < ON_time) {
  digitalWrite(LED_pin, HIGH);  //turns LED on
} else {
  digitalWrite(LED_pin, LOW);   //turns LED off
}

I’d put the ON and OFF times in 2 arrays and compute the periods in the setup() function. Then put rest of the above in a for() loop and cycle through the if() for each LED that way once per loop(), which runs ecery msec in my example. Of course the OP might have the logic levels reversed, a LOW might turn on the LED and a HIGH turn it off, but that’s a detail he can attend to.

Take the case for the OP’s LED1.

LED1: ON for 25 ms, OFF for 500 ms

So at 526 msec the M_time would return 1 msec and since that’s < 25, the LED would be on. Fastforward to 551 msec and what happens ? M_time now returns 26 and so the LED would turn off. Do the above calculations for other times and see if you agree.

OK

Do code for one (1) LED without using delay().

Make the code into a class. You’ll need some variables to control the timings and 2 functions, something like LEDFlash.init and LEDFlash.update.

Stuff the class in the library.

and … use it

easy peasy, your problem lies in not knowing enough about programming, but you’ll get there if you keep at it :slight_smile:

I have a sketch I’m running that flashes 2 led’s at different rates, ramps up a third led, fires off a fourth led, ramps down the third led, all running simultaneously.

… quick google search …

ah Gammon has made his available

have a look here:-

http://www.gammon.com.au/forum/?id=11411

mmm he did just what I did! Good man.

you should see a link on that page to the Arduino code for the LEDFlasher class, just grab it, read the example, stuff it in the Arduino library and use it.

http://gammon.com.au/Arduino/LED_flasher.zip

Have fun :slight_smile:

Isaid “DoWhat?”