Arduino - multiple LEDs with different delays
Moderators: adafruit_support_bill, adafruit

Arduino - multiple LEDs with different delays

by muteprint on Sun Mar 03, 2013 2:21 pm

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:
Code: Select all | TOGGLE FULL SIZE
 
 
// 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!
muteprint
 
Posts: 2
Joined: Sun Mar 03, 2013 2:20 pm

Re: Arduino - multiple LEDs with different delays

by adafruit_support_bill on Sun Mar 03, 2013 3:17 pm

You are on the right track. You just need to keep a little more information on each led. First you need to define separate InInterval and OffInterval constants for each led. Then you need variables to store the current state of each led (on or off). Then each time through the loop, for each LED you:
    Look at the current state.
    Look at the time of the last state change
    Figure out if it is time to change state again.
    Record the time of any action.
User avatar
adafruit_support_bill
 
Posts: 30817
Joined: Sat Feb 07, 2009 10:11 am

Re: Arduino - multiple LEDs with different delays

by muteprint on Sun Mar 03, 2013 6:46 pm

Thanks for the rapid response!
I've made the following alterations to my code:
• Defined separate ON and OFF intervals for each LED
• Adapted my loops to try and include these off and on intervals

I've ended getting myself really confused and now my LEDs seem to sometimes flash the OFF interval, sometimes with the ON and sometimes with a combination of the both.

Any idea how I've gone so horribly wrong?


Code: Select all | TOGGLE FULL SIZE

//DEFINING CONSTANTS & VARIABLES

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

  // Assigning ON and OFF interval constants.
const unsigned long LED1_ON_interval = 3000; //
const unsigned long LED1_OFF_interval = 6000;
const unsigned long LED2_ON_interval = 500; //
const unsigned long LED2_OFF_interval = 1000;
const unsigned long LED3_ON_interval = 100; //
const unsigned long LED3_OFF_interval = 3000;

  // Declaring the variables holding the timer value, i.e. time of last state change.
unsigned long LED1_statechange_Timei;
unsigned long LED2_statechange_Timei;
unsigned long LED3_statechange_Timei;
unsigned long LED1_statechange_Timeii;
unsigned long LED2_statechange_Timeii;
unsigned long LED3_statechange_Timeii;

//SETUP

  // Setting 3 digital pins as LED output pins and starting millisecond timer
void setup ()
  {
  pinMode (LED1, OUTPUT);
  pinMode (LED2, OUTPUT);
  pinMode (LED3, OUTPUT);
  LED1_statechange_Timei = millis ();
  LED2_statechange_Timei= millis ();
  LED3_statechange_Timei = millis ();
  }  // end of setup






//LOOPS 1

  // LED1 loop that turns LED ON if it is OFF
void toggle_LED1i ()
  {
   if (digitalRead (LED1) == LOW)
      digitalWrite (LED1, HIGH);
      LED1_statechange_Timei = millis (); // Remember when LED1's state was changed from ON to OFF
  }  // End of toggle_LED1i

  // LED1 loop that turns LED OFF if it is ON
void toggle_LED1ii ()
  {
    if (digitalRead (LED1) == HIGH);
       digitalWrite (LED1, LOW);
       LED1_statechange_Timei = millis (); // Remember when LED1's state was changed from OFF to ON
  } // End of toggle_LED1ii


  // LED2 loop that turns LED ON if it is OFF
void toggle_LED2i ()
  {
   if (digitalRead (LED2) == LOW)
      digitalWrite (LED2, HIGH);
      LED2_statechange_Timeii = millis (); // Remember when LED2's state was changed from ON to OFF
  }  // End of toggle_LED2i

  // LED2 loop that turns LED OFF if it is ON
void toggle_LED2ii ()
  {
    if (digitalRead (LED2) == HIGH);
       digitalWrite (LED2, LOW);
       LED2_statechange_Timeii = millis (); // Remember when LED2's state was changed from OFF to ON
  } // End of toggle_LED2ii


  // LED3 loop that turns LED ON if it is OFF
void toggle_LED3i ()
  {
   if (digitalRead (LED3) == LOW)
      digitalWrite (LED3, HIGH);
      LED3_statechange_Timei = millis (); // Remember when LED3's state was changed from ON to OFF
  }  // End of toggle_LED2i

  // LED3 loop that turns LED OFF if it is ON
void toggle_LED3ii ()
  {
    if (digitalRead (LED3) == HIGH);
       digitalWrite (LED3, LOW);
       LED3_statechange_Timeii = millis (); // Remember when LED3's state was changed from OFF to ON
  } // End of toggle_LED3ii




//LOOPS 2

void loop () // Start of loop
  {
   
    //LED 1
      // If the time since the last change in state from OFF to ON is equal or greater than the ON interval
      //then run the loop toggle_LED1i
  if ( (millis () - LED1_statechange_Timei) >= LED1_ON_interval)
     toggle_LED1i ();
      // If the time since the last change in state from ON to OFF is equal or greater than the OFF interval
      //then run the loop toggle_LED1ii
  if ( (millis () - LED1_statechange_Timeii) >= LED1_OFF_interval)
     toggle_LED1ii ();
     
     
    //LED 2
      // If the time since the last change in state from OFF to ON is equal or greater than the ON interval
      //then run the loop toggle_LED2i
  if ( (millis () - LED2_statechange_Timei) >= LED2_ON_interval)
    toggle_LED2i ();
      // If the time since the last change in state from ON to OFF is equal or greater than the OFF interval
      //then run the loop toggle_LED2ii
  if ( (millis () - LED2_statechange_Timeii) >= LED2_OFF_interval)
    toggle_LED2ii ();
   
   
    //LED 3
      // If the time since the last change in state from OFF to ON is equal or greater than the ON interval
      //then run the loop toggle_LED3i
  if ( (millis () - LED3_statechange_Timei) >= LED3_ON_interval)
    toggle_LED3i ();
      // If the time since the last change in state from ON to OFF is equal or greater than the OFF interval
      //then run the loop toggle_LED2ii
  if ( (millis () - LED3_statechange_Timeii) >= LED3_OFF_interval)
    toggle_LED3ii ();
 
}  // End of loop



Thank again!
muteprint
 
Posts: 2
Joined: Sun Mar 03, 2013 2:20 pm

Re: Arduino - multiple LEDs with different delays

by adafruit_support_bill on Mon Mar 04, 2013 6:40 am

You are not storing the current state of the led and taking it into account in your logic. For example - you only want to execute the following logic if LED1 is in the ON state.
Code: Select all | TOGGLE FULL SIZE
    //LED 1
      // If the time since the last change in state from OFF to ON is equal or greater than the ON interval
      //then run the loop toggle_LED1i
  if ( (millis () - LED1_statechange_Timei) >= LED1_ON_interval)
     toggle_LED1i ();
User avatar
adafruit_support_bill
 
Posts: 30817
Joined: Sat Feb 07, 2009 10:11 am