Go Down

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

#### i_luv_arduino

##### Dec 17, 2012, 11:38 pm
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);
delay(1000);
digitalWrite(second, LOW);
delay(1000);

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

_clay

#### dc42

#1
##### Dec 18, 2012, 12:03 am
Read and understand http://arduino.cc/en/Tutorial/BlinkWithoutDelay, then generalise it to more than one LED.
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.

#### guix

#2
##### Dec 18, 2012, 12:08 am
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?

#### dhenry

#3
##### Dec 18, 2012, 12:17 am
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.

#### i_luv_arduino

#4
##### Dec 18, 2012, 12:53 am
Can you be more specific about how to do it with and without delay???

#### guix

#5
##### Dec 18, 2012, 01:06 am

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

?

#### i_luv_arduino

#6
##### Dec 18, 2012, 01:12 am
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.

#### billroy

#7
##### Dec 18, 2012, 01:24 am
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.

-br

#### guix

#8
##### Dec 18, 2012, 01:43 amLast 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]
`uint32_t  time_now  = 0,  time_past = 0;  uint8_t  half_seconds    = 0,  seconds         = 0,  minutes         = 0,  LED_seconds_pin = 11,  LED_minutes_pin = 12,  LED_hours_pin   = 13;bool  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 );        }      }    }  }}`

#### Jimmy60

#9
##### Dec 18, 2012, 01:53 am
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 classclass 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 timepublic:    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 othersBlinker::Blinker(byte pin){    _ledPin = pin;    _lastToggleMillis = 0;    _duration = 0;    _ledOn = false;    blinkOn = false;}// Blinker::begin()// call at setup inits pin assigns on and off valuesvoid 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 offboolean 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        }        else        {            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 instancesBlinker everySecondLed(11);                                        // Blinker needs pin led attached toBlinker 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    everyMinuteLed.check();                                 everyHourLed.check();                               }`

#### i_luv_arduino

#10
##### Dec 18, 2012, 01:54 am
So can I just copy, paste and download, like a code or should I chan it a bit???

#### cmiyc

#11
##### Dec 18, 2012, 01:55 am
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).

http://www.cmiyc.com/blog/2011/01/06/millis-tutorial/
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

#### dhenry

#12
##### Dec 18, 2012, 03:10 am
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.

#### i_luv_arduino

#13
##### Dec 18, 2012, 03:52 am
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

#### PaulS

#14
##### Dec 18, 2012, 12:50 pm
Quote
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.