Go Down

Topic: Sticky - Blink Two LEDs, independent, no delay (Read 7041 times) previous topic - next topic

Jassper

I guess I just don't see what the issue is. What are people complaining about anyways? Advanced code that someone doesn't understand so therefor it shouldn't be there? Whats wrong with the code?

For whatever it's worth I thank all who contributed to the Blink without delay() as it is just what I was looking for.

floresta

Quote
It seems to be on Page 11 of the section now.


It's just going to sink lower and lower because it is locked.

And because it is locked it remains an answer without a question.


Don

Coding Badly

It's just going to sink lower and lower because it is locked.


Are you proposing someone edit the post each day to keep it hovering on the first page?

Quote
And because it is locked it remains an answer without a question.


How does the lock status make it "an answer without a question"?

Nick Gammon

Yeah we could take turns to "bump" it.

An answer without a question, like 42?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Jassper


It's just going to sink lower and lower because it is locked.


Are you proposing someone edit the post each day to keep it hovering on the first page?


Make it a sticky again so it don't sink.
Quote

Quote
And because it is locked it remains an answer without a question.


How does the lock status make it "an answer without a question"?



Because it can't be edited to add the question "How do I delay an action without using the delay() function" (or similar, although I think the question is irrelevant.)

floresta

#65
Nov 01, 2011, 02:47 pm Last Edit: Nov 01, 2011, 03:01 pm by floresta Reason: 1
We are going around and around here but I think we all basically agree that this topic is important and that somehow it ought to be made readily available.  Although I personally believe that putting it in a separate FAQ section is the best answer I think 'Coding Badly' has the power to implement a temporary solution.  The title should be changed, an explanation of the problem that is being solved by the code should be added, and in that explanation the term delay() should be used where appropriate.  Then the new version can be made sticky.

Don

Edit:  In changing the title and in writing the explanation keep in mind that the most important concept here is the fact that the code is implementing a 'delay' without using the 'delay()' function.  The fact that one or more LEDs are blinking is not really what this is all about.

The blinking of an LED is an example of what can be done with any kind of delay technique.  The blinking of an LED while also doing something else is an example of what can be done when the use of delay() is eliminated, as is the independent blinking of two LEDs.

Nick Gammon

I got a bit tired of waiting for our thread to be stickied again, so I did my own variation on my website. At least I can remember where to find that. :)

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

That shows a (slightly modified) version of the sketch we worked on here, with a fairly lengthy explanation of the difference between blocking and non-blocking code, with an analogy of cooking breakfast.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

mmcp42

just had a peer at your site
some good stuff there
hope you don't mind, I've bookmarked it for further research!
there are only 10 types of people
them that understands binary
and them that doesn't

PaulS

Two minute bacon and three minute eggs. Are you sure you're not French?

Nick Gammon

Pretty sure, Paul. :)

To make the page easier to find I added an HTTP redirect:

http://www.gammon.com.au/blink
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Msquare

So I unlocked The Great NON_Sticky ;)  http://arduino.cc/forum/index.php/topic,76140.msg574940.html#msg574940

And bumped it. Bump at discretionary intervals :) Lets see what happens.

footswitch

My two cents to the discussion, just because I loved the fact that such a simple topic is 5 pages long in comments.

My first implementation for blinking several LEDs "independent" of each other involved the use of MsTimer2.h and Metro.h.
This is because the loop() section had some blocking functions, thus preventing LEDs from blinking at their specified times.

By independent I mean that we can set LEDs to blink at different predefined rates, but each rate is applied to all its LEDs at once. So LEDs at the same rate will blink at the same time. This also means that two LEDs with the same rate may blink in opposite states of each other (while one is on, the other is off). To prevent this we'd have to implement additional checks.

Of course this chews up memory, processing cycles and whatnot. Like I cared at the time :P


Code: [Select]
#include <MsTimer2.h> // calls a defined function every x milliseconds
#include <Metro.h> // handling of timers made easy

// you can set an array of 12 elements to use all the digital pins (except RX/TX)
int LED[3]={11,12,13}; // led pins
int LED_Set[3] = {1,0,0}; // to change operating mode of each LED
                                        // also sets initial operating mode
// call LED_REFRESH() to update LED status
// 0 - LED off
// 1 - LED on
// 2 - slow blink (500ms)
// 3 - moderate blink (250ms)
// 4 - fast blink (150ms)
// 5 - very fast blink (50ms)

// timers with autoreset (ignore missed events)
Metro LED_BLINK_SLOW = Metro(500,1);
Metro LED_BLINK_MODERATE = Metro(250,1);
Metro LED_BLINK_FAST = Metro(150,1);
Metro LED_BLINK_LIGHTSPEED = Metro(50,1); // just kidding here :)

void setup()
{
  // initialize LEDs:
  for (int i=0; i<3; i++)
  {
    digitalWrite(LED[i],LOW); // sets initial state of output LEDs (off)
    pinMode(LED[i],OUTPUT); // sets operation mode for LED pins (output)
  }
 
  // refresh LED status every 10ms
  // (the Arduino won't complain, but really, poor thing)
  MsTimer2::set(10, LED_REFRESH);
  MsTimer2::start();
 
  Serial.begin(9600);
  Serial.println("Ready, set, go!");
}

void loop()
{
  // all LEDs blink slowly
  LED_Set[0]=2;
  LED_Set[1]=2;
  LED_Set[2]=2;
  delay(2000);
  LED_Set[0]=2; // blink slow
  LED_Set[1]=3; // blink moderate
  LED_Set[2]=4; // blink fast
  delay(2000);
  LED_Set[0]=3;
  LED_Set[1]=4;
  LED_Set[2]=5; // blink very fast
  delay(2000);
}


// This function is called periodically by MsTimer2.
// The MsTimer2 period should be a defined in such a way that
// the shortest Metro timer is a multiple of MsTimer2
// (so that the blinking has a natural feel to the eye)
// Example: smallest Metro timer is 50 ms; MsTimer2 should be 25, 10 or 5...
void LED_REFRESH()
{
  // check what timers apply
  boolean LED_BLINK_SLOW_CHECK = LED_BLINK_SLOW.check();
  boolean LED_BLINK_MODERATE_CHECK = LED_BLINK_MODERATE.check();
  boolean LED_BLINK_FAST_CHECK = LED_BLINK_FAST.check();
  boolean LED_BLINK_LIGHTSPEED_CHECK = LED_BLINK_LIGHTSPEED.check();
 
  for (int i=0; i < sizeof(LED) / sizeof(LED[0]); i++)
  {
    switch (LED_Set[i])
    {
      case 0: // turn off
        digitalWrite(LED[i],LOW);
        break;
       
      case 1: // turn on
        digitalWrite(LED[i],HIGH);
        break;
       
      case 2: // blink slow
        if (LED_BLINK_SLOW_CHECK)
        {
          digitalWrite(LED[i],!digitalRead(LED[i]));
        }
        break;
       
      case 3: // and so on
        if (LED_BLINK_MODERATE_CHECK)
        {
          digitalWrite(LED[i],!digitalRead(LED[i]));
        }
        break;
       
      case 4:
        if (LED_BLINK_FAST_CHECK)
        {
          digitalWrite(LED[i],!digitalRead(LED[i]));
        }
        break;
       
      case 5:
        if (LED_BLINK_LIGHTSPEED_CHECK)
        {
          digitalWrite(LED[i],!digitalRead(LED[i]));
        }
        break;
    }
  }
}
//////////////////////////////////////////////////////

Coding Badly


Sharing a simple non-byte variable (LED_Set) between loop and an ISR is a big no-no.

footswitch

I know, right?
At the time, when I realized how wrong that was, I was actually surprised that the sketch didn't fail miserably.

Coding Badly


It works for two reasons...

1. The values stored in LED_Set fit in a byte (are always >= 0 and <= 255).

2. loop calls another function (delay) and returns to its caller.

If those two conditions had not been met, the sketch would potentially fail.

Go Up