element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Arduino Forum Arduino - multiple LEDs with different delays
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Suggested Answer
  • Replies 8 replies
  • Answers 5 answers
  • Subscribers 404 subscribers
  • Views 4258 views
  • Users 0 members are here
Related

Arduino - multiple LEDs with different delays

Former Member
Former Member over 12 years ago

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]

 

 

// 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

[/code]

 

 

Any help would be greatly appreciated because I'm [b]very[/b] new to this!

 

 

Thanks!

  • Sign in to reply
  • Cancel

Top Replies

  • billabott
    billabott over 12 years ago +1 suggested
    Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3). Official Arduino.cc Example int pin = 13 ; volatile int state = LOW ; void setup ( ) { pinMode …
Parents
  • billabott
    0 billabott over 12 years ago
    Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3).

    Official Arduino.cc Example

     

     

    int pin = 13;
    volatile int state = LOW;

     

    void setup()
    {
      pinMode(pin, OUTPUT);
      attachInterrupt(0, blink, CHANGE);  //0 is digtal pin 2
    }

     

    void loop()
    {
      digitalWrite(pin, state);
    }

     

    void blink()
    {
      state = !state;
    }

     

     

    Observing that all your time factors are multiples of 25 ms, I would suggest that you use a digital pin on your UNO to initiate a self generated external interrupt.

     

    Adding code: const byte iSignal =9;

    Adding physical wire/resister+LED/cap. between pins 9 and 2.

     

    Here is the guts of it:   pin 9 is pulsed every 25 ms by your loop(), the iHandler() bumps a counter, the main loop() has a case statement that allows the required LED transistion actions to take place depending on the counter value only when old_counter is not equal to counter. 

     

    0 <= counter <= 32  (because 800/25=32), reset counter to 0 after 32 interrupts have occurred.  (I am not sure if you want to count to 32 or 31.)


    To make the implementation easier(reliable) change

    LED1: ON for 25 ms, OFF for 500 ms 

    LED2: ON for 50 ms, OFF for 800 ms

    to

    LED1: ON for 25 ms, OFF for 450 ms

    LED2: ON for 50 ms, OFF for 750 ms

     

     

    FYI: http://arduino.cc/en/Reference/AttachInterrupt

     

    Then again, you could just call the iHandler directly without the external interrupt -  but what fun would that be?   image

     

     


    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • Former Member
    0 Former Member over 12 years ago in reply to billabott

    Thank you very much for replying so quickly billabot. Unfortunately there will be times when I need to LED to flash 3 times a second i.e. with an interval of 333ms, so not everything will be divisble by 25. Is your method adaptable to any value?

     

    I've been working on this tonight and made a few alterations to my code. I think I'm going in the right direction with the method I've chosen.

    • Defined seperate ON and OFF intervals for each LED

    • Adapted my loops to use both the OFF and ON intervals.

     

    Unfortunately 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 badly wrong?

     

    I hope I'm slowly moving in the right direction. If not I might have to try a different approach like using the interupt function. I am very new to the Arduino and writing code of any sort, so that approach seems quite daunting to me.

     

    Below is my altered code.

     

     

    [code]

     

     

    //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

    [/code]

     

     

    Thanks!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • billabott
    0 billabott over 12 years ago in reply to Former Member

    Sorry, no, I am out of ideas.  I will, however, share with you that there are other uC that have multiple timers on board that can be configured to generate interrupts at any predetermined interval.  

     

    Q:  Just out of curiosity, what exactly controls the periodicity of your LEDs?

           Or in other words; "What is your application, eh?"

     

    You might simplify your program by adopting a more conventional approach by using

     

    boolean LED1_state = false;    // place these very near the top of script so their scopes are GLOBAL

    boolean LED2_state = false;

    boolean LED3_state = false;

     

     

    If time to turn off LED1

         Set LED1_on_timer to milles() +800;      //  turning off; so it is known when to turn it on again.

         toggle_LED(&LED1, &LED1_state);   //  call function to toggle LED between 1 and 0

         Set LED1_off_timer to milles() +2048;    //  presumeably will be reset to a correct value

                                                     //  after turning LED1 on prior to the expiration of this value  

    else if  time to turn on LED1

          Set LED1_off_timer to milles() +50;       //  turning on; so it is known when to turn it off again.

          toggle_LED(&LED1, &LED1_state);;   // call function to toggle LED between 0 and 1

          Set LED1_on_timer to milles() +2048;   //  presumeably will be reset to a correct value

                                                       //  after turning LED1 off prior to the expiration of this value  

     


     

    void toggle_LED(int  *LEDxP, boolean *LEDxP_state)      // will need ONLY this one function to toggle ANY LED since pointers are used

      {

             digitalWrite (*LEDxP, (*LEDxP_state = !(*LEDxP_state)));  // see note below

         }  // End of toggle_LED

     

    note: According to http://arduino.cc/en/Reference/BooleanVariables

    digitalWrite does accept boolean arg of true/false in lieu of HIGH/LOW arg.

     

    Message was edited by: William Bottger

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
Reply
  • billabott
    0 billabott over 12 years ago in reply to Former Member

    Sorry, no, I am out of ideas.  I will, however, share with you that there are other uC that have multiple timers on board that can be configured to generate interrupts at any predetermined interval.  

     

    Q:  Just out of curiosity, what exactly controls the periodicity of your LEDs?

           Or in other words; "What is your application, eh?"

     

    You might simplify your program by adopting a more conventional approach by using

     

    boolean LED1_state = false;    // place these very near the top of script so their scopes are GLOBAL

    boolean LED2_state = false;

    boolean LED3_state = false;

     

     

    If time to turn off LED1

         Set LED1_on_timer to milles() +800;      //  turning off; so it is known when to turn it on again.

         toggle_LED(&LED1, &LED1_state);   //  call function to toggle LED between 1 and 0

         Set LED1_off_timer to milles() +2048;    //  presumeably will be reset to a correct value

                                                     //  after turning LED1 on prior to the expiration of this value  

    else if  time to turn on LED1

          Set LED1_off_timer to milles() +50;       //  turning on; so it is known when to turn it off again.

          toggle_LED(&LED1, &LED1_state);;   // call function to toggle LED between 0 and 1

          Set LED1_on_timer to milles() +2048;   //  presumeably will be reset to a correct value

                                                       //  after turning LED1 off prior to the expiration of this value  

     


     

    void toggle_LED(int  *LEDxP, boolean *LEDxP_state)      // will need ONLY this one function to toggle ANY LED since pointers are used

      {

             digitalWrite (*LEDxP, (*LEDxP_state = !(*LEDxP_state)));  // see note below

         }  // End of toggle_LED

     

    note: According to http://arduino.cc/en/Reference/BooleanVariables

    digitalWrite does accept boolean arg of true/false in lieu of HIGH/LOW arg.

     

    Message was edited by: William Bottger

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
Children
  • Former Member
    0 Former Member over 12 years ago in reply to billabott

    Even with using only one timer, you may be able to do something like this:

     

    You have 6 events to schedule (turning each of 3 LED's On and Off).

    For each event, you need to store 4 fields: which LED, On vs. Off,

    the time-of-day the event should be taken next, and the amount of time

    between events.  For LED1, the time between events would be 525 ms. 

    You can store these 6 events in an array.  (They don't have to be sorted

    in any particular order.)  It may help to think of this array as the "delay-queue"

    of a task scheduler.

     

    Then you can write a function that will scan this array and find the event with the

    soonest next time-of-day.  Set an interrupt timer for that time-of-day.  While

    waiting for the timer, any work can be going on.  When the timer goes off,

    turn the specified LED On or Off, and update the next time-of-day field by adding

    the specified time between events for that LED.   Loop back and scan the array

    again to find the next soonest event.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube