Pages: [1] 2   Go Down
Author Topic: How to blink 3 leds at different time intervals  (Read 740 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

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

_clay
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Read and understand http://arduino.cc/en/Tutorial/BlinkWithoutDelay, then generalise it to more than one LED.
Logged

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.

France
Offline Offline
God Member
*****
Karma: 34
Posts: 987
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello and welcome,

I know how, by NOT using delay() smiley

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

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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???
Logged

France
Offline Offline
God Member
*****
Karma: 34
Posts: 987
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

?
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 988
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

France
Offline Offline
God Member
*****
Karma: 34
Posts: 987
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Something like that should work (not tested, might be bugged but it's just an example smiley):
Code:
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 );
        }
      }
    }
  }
}
« Last Edit: December 17, 2012, 07:56:53 pm by guix » Logged

Saskatchewan
Offline Offline
Sr. Member
****
Karma: 19
Posts: 362
When the going gets weird, the weird turn pro. - Hunter S. Thompson
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

public:
    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
        }
        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 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
    everyMinuteLed.check();                             
    everyHourLed.check();                               
}

Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Austin, TX
Online Online
Faraday Member
**
Karma: 71
Posts: 6137
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  //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:
#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.
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1] 2   Go Up
Jump to: