Pages: [1] 2   Go Down
Author Topic: Blink Two LEDs, independent, no delay  (Read 4814 times)
0 Members and 1 Guest are viewing this topic.
Copenhagen, Denmark
Online Online
Edison Member
*
Karma: 32
Posts: 1204
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Some of the frequent contributors thought this might be a good example - for when the tutorial "Blink without Delay" example is not enough
Code:
/* Multiple independent delay - Two blinking LEDs

Working code example that blinks two LEDs, each with its own independent period.
This extends the BlinkWithoutDelay example of a single LED, showing how to
implement multiple independent timing paths in the main loop.

Written by several forum members. In public domain.  Oct 2011.

Note: works even when millis () wraps around to zero after approximately 50 days.
*/

// Which pins are connected to which LED
const byte greenLED = 8 ;
const byte redLED = 10 ;

// Time periods of blinks in milliseconds (1000 milliseconds to a second).
// Time variable and constants are always unsigned long
const unsigned long greenLEDinterval = 555UL ;
const unsigned long redLEDinterval = 1234UL ;

// Variable holding the timer value so far. One for each "Timer"
unsigned long greenLEDtimer = 0 ;
unsigned long redLEDtimer = 0 ;

// Variable to know what the current LED state is
int greenLEDState = LOW ;
int redLEDState = LOW ;

void setup() {
  pinMode (greenLED,OUTPUT) ;
  pinMode (redLED,OUTPUT) ;
  greenLEDtimer = millis () ;
  redLEDtimer = millis () ;
}

void loop() {

// Handling the blink of one LED.
// First, check if it is time to change state
  if ( (millis () - greenLEDtimer) >= greenLEDinterval ) {
    // It is time to change state. Calculate next state.
    if (greenLEDState == LOW)
      greenLEDState = HIGH ;
    else
      greenLEDState = LOW ;
    // Write new state
    digitalWrite (greenLED, greenLEDState ) ;
    // Reset timer
    greenLEDtimer = millis () ;
  }

// The other LED is controlled the same way. Repeat for more LEDs
  if ( (millis () - redLEDtimer) >= redLEDinterval ) {
    if (redLEDState == LOW)
      redLEDState = HIGH ;
    else
      redLEDState = LOW ;
    digitalWrite (redLED, redLEDState ) ;
    redLEDtimer = millis ()  ;
  }

/* Other code that needs to execute goes here.
   It will be called many thousands of times per second because the above code
   does not wait for the LED blink interval to finish. */

}

« Last Edit: November 12, 2011, 03:24:56 pm by Msquare » Logged

Copenhagen, Denmark
Online Online
Edison Member
*
Karma: 32
Posts: 1204
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Someone asked elswewhere if this could be udes with motors. SURE! just replace the digitalWrite with anything else you want to do after a while : servo.write() for example, or avoid reading a switch input for 5ms for the debounce.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 96
Posts: 4773
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.gammon.com.au/forum/?id=11411

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

And to save remembering that number:

http://gammon.com.au/blink
Logged

0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3470
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Good example but I would use interrupts instead like so  http://blog.blinkenlight.net/experiments/basic-effects/persistence-of-vision/.
Logged

Check out my experiments http://blog.blinkenlight.net

Offline Offline
Jr. Member
**
Karma: 0
Posts: 95
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Generalizing (and avoiding fiddling with interrupts):

1) How to do several things at the same time
2) More on doing several things at the same time
Logged


0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3470
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Technically millis() is also utilizing interrupts.  Why do you object against interrupts?
Logged

Check out my experiments http://blog.blinkenlight.net

Offline Offline
Jr. Member
**
Karma: 0
Posts: 95
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't object interrupts, I object them being used directly for blinking an LED, and by someone who's a beginner. Much simpler to take a non-preemptive approach. millis() hides interrupts, you don't have to deal with them. Keep it simple.
Logged


Western New York, USA
Offline Offline
Faraday Member
**
Karma: 32
Posts: 4259
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
2) More on doing several things at the same time
Isn't this using essentially the same technique as the solution in the original post?

Don
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 96
Posts: 4773
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't object interrupts, I object them being used directly for blinking an LED, and by someone who's a beginner. Much simpler to take a non-preemptive approach. millis() hides interrupts, you don't have to deal with them. Keep it simple.

For a beginner to learn about interrupts isn't a trivial task better than a complicated one?

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 95
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, if the purpose of the beginner is to learn about interrupts. But usually it isn't, it is just to blink the LED.
Logged


0
Offline Offline
Faraday Member
**
Karma: 23
Posts: 3470
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, mstimer2 also hides interrupts. It even hides the scheduling mechanism. Whereas the millis approach makes the scheduling transparent. Which one is easier to grasp depends on your point of view. I found pointers /memory allocation slightly harder to grasp than interrupts. Hence I do not understand why beginners should not learn this.
Debugging interrupts is a different issue though. But Arduino offers no debugger anyway.
Logged

Check out my experiments http://blog.blinkenlight.net

Offline Offline
God Member
*****
Karma: 32
Posts: 507
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This reminded me of a macro I wrote once, specifically for the case of blinking LEDs independently with different periods. I'm not sure that I'd recommend using macros in this way though, certainly not to beginners!

Code:
//usage: every(id,time) doSomething();
//   id = some unique identifier
// time = period in microseconds
// Be careful, this macro has a trailing if and can bite you. You have been warned!
// If you use it, don't use delay, dont use blocking code, don't do anything more
// complicated than flash an LED.

#define every(id,time)  static unsigned long _ec ## id = 0;                   \
                        unsigned long _et ## id = micros();                   \
                        boolean _eb ## id = (_et ## id - _ec ##  id) >= time; \
                        if(_eb ## id) _ec ## id += time;                      \
                        if(_eb ## id)             

boolean p13,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11;

void setup() {
  for(int i=2;i<=13;i++)pinMode(i,OUTPUT);
}

void loop() {
  every(tled,1000000) digitalWrite(13,p13=!p13); // eg. toggle LED every 1000000 microseconds
 
  every(t2,30000000/51) digitalWrite(2,p2=!p2); // pendulum waves
  every(t3,30000000/52) digitalWrite(3,p3=!p3);
  every(t4,30000000/53) digitalWrite(4,p4=!p4);
  every(t5,30000000/54) digitalWrite(5,p5=!p5);
  every(t6,30000000/55) digitalWrite(6,p6=!p6);
  every(t7,30000000/56) digitalWrite(7,p7=!p7);
  every(t8,30000000/57) digitalWrite(8,p8=!p8);
  every(t9,30000000/58) digitalWrite(9,p9=!p9);
  every(t10,30000000/59)digitalWrite(10,p10=!p10);
  every(t11,30000000/60)digitalWrite(11,p11=!p11);
}
(I ran out of LEDs - this would probably look really good on the Blinkenlight shield)
Logged


Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Technically millis() is also utilizing interrupts.  Why do you object against interrupts?

Because you only get 2.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Technically millis() is also utilizing interrupts.  Why do you object against interrupts?

Because you only get 2.

Timer interrupts don't use up either of the two user interrupts (five if mega board).

Lefty
Logged

Pages: [1] 2   Go Up
Jump to: