Go Down

Topic: How to blink 3 leds at different time intervals (Read 1 time) previous topic - next topic


Hi I am working on a simple clock with 3 leds. I want to have one blink every second, another to blink every minute, and the last one to blink every hour. I have this code so far:
int hour = 13;
int minute = 12;
int second = 11;
void setup() {
  pinMode(hour, OUTPUT);
  pinMode(minute, OUTPUT);
  pinMode(second, OUTPUT);   

void loop() {
  digitalWrite(second, HIGH);     
  digitalWrite(second, LOW);     

I only put the led for seconds in the loop but where do I put code for the "minute" led and "hour" led.

Please help the newbie!!! :smiley-mr-green: :smiley-mr-green: :smiley-mr-green:



Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.


Hello and welcome,

I know how, by NOT using delay() :)

I will post a more complete answer once you answer this question: how long the LEDs should stay ON?


1. Keep track of time in seconds;
2. At each second increment, blink the second led;
3. At each minute increment, blink the minute led;
4. At each hour increment, blink the hour led.


One led blinks every second,
The second blinks every minute,
The third blinks every hour.
Can you be more specific about how to do it with and without delay???


One led blinks every second,
The second blinks every minute,
The third blinks every hour.

Do you mean:

The seconds LED is ON for one second, OFF for one second
The minutes LED is ON for one minutes, OFF for one minute
The hours LED is ON for one hour, OFF for one hour



Sorry I mean the seconds led is on for 500 milliseconds, off for 500 milliseconds
the minute led is on for 30 seconds and off for 30 seconds, the hour led is on for 30 minutes and off for 30 minutes, one led blinks once PER second another once PER minute another once PER hour.


The main example for the Run library, available here: https://github.com/billroy/run shows how to blink two LEDs at different rates using the Run library.  You could extend that example, but of course it's best if you understand what's going on by studying the BlinkWithoutDelay example.

You've got three little tasks, each with its own timeline.  You can't use delay in any of them because it disrupts the scheduling for all of them.  Each light needs its own scheduled time for the next thing to happen.



Dec 18, 2012, 01:43 am Last Edit: Dec 18, 2012, 01:56 am by guix Reason: 1
Something like that should work (not tested, might be bugged but it's just an example :)):
Code: [Select]

 time_now  = 0,
 time_past = 0;
 half_seconds    = 0,
 seconds         = 0,
 minutes         = 0,
 LED_seconds_pin = 11,
 LED_minutes_pin = 12,
 LED_hours_pin   = 13;

 LED_seconds_state = false,
 LED_minutes_state = false,
 LED_hours_state   = false;

void setup()
 pinMode( LED_seconds_pin, OUTPUT );
 pinMode( LED_minutes_pin, OUTPUT );
 pinMode( LED_hours_pin,   OUTPUT );

 time_past = millis();

void loop()
 time_now = millis();

 //every 500 milliseconds
 if ( time_now - time_past >= 500 )
   time_past = time_now;

   //toggle LED_seconds
   LED_seconds_state = !LED_seconds_state;
   digitalWrite( LED_seconds_pin, LED_seconds_state );

   //every seconds
   if ( ++ half_seconds >= 2 )
     half_seconds = 0;
     //every 30 seconds
     if ( ++ seconds >= 30 )
       seconds = 0;

       //toggle LED_minutes
       LED_minutes_state = !LED_minutes_state;
       digitalWrite( LED_minutes_pin, LED_minutes_state );

       //every 30 minutes
       if ( ++ minutes >= 30 )
         minutes = 0;

         //toggle LED_hours
         LED_hours_enabled = !LED_hours_enabled;
         digitalWrite( LED_hours_pin, LED_hours_state );


I happen to have a sketch that does this. I wrote it to learn more about OOP techniques and to see what kind of overhead is involved. It's straight forward.

It's basically a blinking led class that has public variables for setting on and off durations or turning blinking on / off. In this case I just instance three leds and give them the appropriate on and off durations. This is only tested with one led but should work.

Code: [Select]
// durations in millis change to suit
// you can also set led.onDuration and led.offDuration directly

// Blinker class
class Blinker
    byte _ledPin;                                                  // pin led is at
    boolean _ledOn;                                                // status flag on is true
    unsigned long _lastToggleMillis;                               // time last toggled
    unsigned long _duration;                                       // for checking time

    unsigned long onDuration;                                      // time led spends on
    unsigned long offDuration;                                     // time led spends off
    boolean blinkOn;                                               // blink or not

    Blinker(byte);                                                 // default expects pin led attached to
    void begin(unsigned long, unsigned long);                      // initilaizes led pin passed values are on and off time in millis
    boolean check(void);                                           // called to check and do blinking

// default constructor
// requires pin of led, assigned to _ledpin inits others
Blinker::Blinker(byte pin)
    _ledPin = pin;
    _lastToggleMillis = 0;
    _duration = 0;
    _ledOn = false;
    blinkOn = false;

// Blinker::begin()
// call at setup inits pin assigns on and off values
void Blinker::begin(unsigned long on, unsigned long off)
    pinMode(_ledPin, OUTPUT);                                      // set led pin to output
    onDuration = on;
    offDuration = off;

// Blinker::check()
// turns led on or off
boolean Blinker::check()
    if (!blinkOn) return false;                                    // only blink if blink on
    if (millis() - _lastToggleMillis > _duration)                  // decide if action needed
        if (_ledOn)                                                // use the ledOn flag to test the led state
            digitalWrite (_ledPin, LOW);                           // its on so turn it off
            _ledOn = false;                                        // clear the flag
            _lastToggleMillis = millis();                          // set  time
            _duration = offDuration;                               // set duration for this state
            digitalWrite (_ledPin, HIGH);                          // its off so turn it on
            _ledOn = true;                                         // set the flag
            _lastToggleMillis = millis();                          // set next action time
            _duration = onDuration;                                // set duration for this state
    return true;

// create our led instances
Blinker everySecondLed(11);                                        // Blinker needs pin led attached to
Blinker everyMinuteLed(12);
Blinker everyHourLed(13);

void setup()
    everySecondLed.begin(500, 500);                     // starts our led object sets on and off durations
    everyMinuteLed.begin(30000, 30000);                   
    everyHourLed.begin(1800000, 1800000);                   

    everySecondLed.blinkOn = true;                      // turn on blinking
    everyMinuteLed.blinkOn = true;                       
    everyHourLed.blinkOn = true;                       

void loop()
    everySecondLed.check();                             // call check function


So can I just copy, paste and download, like a code or should I chan it a bit???


If you want to learn how to make it work on your own, I created 5 steps (or exercises) to get you from delay() to using millis().

(Or you could just try skipping to #5 and playing with the timing variables).

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com


Code: [Select]
  //every 500 milliseconds
  if ( time_now - time_past >= 500 )
    time_past = time_now;

Some thing like that will drift over time. Instead, use this:

Code: [Select]

#define TIM_STEP 500 //timing step is 500ms

  //every 500 milliseconds
  if ( millis() - time_past >= TIM_STEP )
    time_past += TIM_STEP;

time_past is initialized either in setup(); or in loop() as a static.

The timing accuracy of this approach is only dependent on the crystal.


Thank you guix it works, except when its been 30 seconds it stays on for another 30 seconds. I want it so when 60 seconds is up it blinks once and then when 60 seconds is up again it blinks again, same with hours please.thanks


I want it so when 60 seconds is up it blinks once and then when 60 seconds is up again it blinks again, same with hours please.

Blinking is not something a pin can do. A pin can turn on. A pin can turn off. By turning the pin on, pausing, turning the pin off, pausing, and repeating, the LED connected to the pin can appear to blink.

So, far, you haven't defined how long the pause while the pin is on should be, so the fact that it is not to your liking is hardly surprising.
The art of getting good answers lies in asking good questions.

Go Up