Blink without delay

Hi ,
How do i get multiple leds to work with de blink without delay feature?
Best regards pim

How do i get multiple leds to work with de blink without delay feature?

By adding the appropriate code. If you understand what blink without delay is doing, the additional code is trivial. If you don't, well, it's a lot more difficult.

Perhaps you could explain what difficulties you are having.

There ARE stickies at the top of the forum that could prove interesting.

Is it not possible to just use delay for a sequence and somehow use a button to start it? Press button sequence starts press again sequence start again and so on...

No, the delay function blocks further execution of the code; if you have a delay(5000) in your code, you can never react on that faster than every 5 seconds. You have to use a non-blocking delay (or non-blocking functions) to keep the ability to check the button 'any time'.

There is a thread 'several things at a time'; do a search in the sticky that PaulS mentioned.

The demo Several Things at a Time is an extended example of BWoD and shows how multiple LEDs can be controlled.

...R

Pimduino:
Is it not possible to just use delay for a sequence and somehow use a button to start it? Press button sequence starts press again sequence start again and so on...

anything is possible. but everything has tradeoff's

this use of delay will only stop the program for 1 ms.
you count up each time it passes.
then count how many ms

in this case, it should blink on and off each second. plus cumulative errors.
AND, the second will NOT blink on/off equally because it is delayed.

you would have to figure out how to change the timing
you could use a second counter, or one for each LED

this would be possible and it would reduce the problem of blocking, not eliminate it
and would not be recommended.

using blink without delay is preferred because it is used in so many other parts of your work as your knowledge grows.

there are a few tutorials of blink without delay. read a few until one makes sense to you.
the ones in the archives of this forum are usually devoid of actual help in learning. they are more for reference once you already understand and know it and have learned it, but need a very basic format.

with some tweeking, this could work for you.

delay(1)
cycle_count = cycle_count + 1 ;

if cycle_count > 1000  && cycle_count < 1100 // it only needs to turn on once
   digitalWrite(led1,LOW)

if cycle_count > 1500 && cycle_count < 1600 
   digitalWrite(led2,LOW)


if cycle_count > 2000
   digitalWrite(led1,HIGH)

if cycle_count > 2500 {
    digitalWrite(led2,LOW)
    cycle_count = 0   // reset to zero after the last line or by a separate if() statement
}

I use this technique all the time. For anything that needs a delay, set a LONG variable (not int - if you use int it wont work, not big enough) to millis() - thats the # of milliseconds since the arduino started up, and run off that. Also probably set a state (on or off) variable to track if its on or off.

Super fast example:

Turn LED 1 on, wait 4 seconds, turn it off, wait 2 seconds, turn it on, keep doing that.
Turn LED 2 on, wait 3 seconds, turn it off, wait 1.5 seconds, turn it on, keep doing that.

Using delay won't work, because you'd turn them both on, and the delay(4000) would miss the turn off time for LED 2 - it pauses execution.

So something like this:

long led1_clock = 0, led2_clock = 0;
int led1_ison = 0, led2_ison = 0;

void loop() {
  if(led1_clock < millis()) { // is it time to do something with led1?
    if(!led1_ison) { // Is led1 off? If so, turn it on
      digitalWrite(led1pin, HIGH); // turn it on
      led1_ison = 1;
      led1_clock = millis() + 4000; // Set the timer for led1 to be now + 4000 milliseconds
    } else { // it must be on then, turn it off
      digitalWrite(led1pin, LOW); // turn it off
      led1_ison = 0;
      led1_clock = millis() + 2000; // Set the timer for led1 to be now + 2000 milliseconds
    }
  }

  if(led2_clock < millis()) { // is it time to do something with led2?
    if(!led2_ison) { // Is led2 off? If so, turn it on
      digitalWrite(led2pin, HIGH); // turn it on
      led2_ison = 1;
      led2_clock = millis() + 3000; // Set the timer for led2 to be now + 3000 milliseconds
    } else { // it must be on then, turn it off
      digitalWrite(led2pin, LOW); // turn it off
      led2_ison = 0;
      led2_clock = millis() + 1500; // Set the timer for led2 to be now + 1500 milliseconds
    }
  }
}

How this works is you do an action, like turning a led on, then you set a timer for millis() + X milliseconds. You then loop and check and see if the target time has passed, if so, do something, and set the timer again.

This way you can make delays that don't hang your program. There are MUCH cleaner ways to do this, but I figured I had a free moment so I'd type out the basic idea so you could get the hang of it.

This video may help.

When you have your mind around it, I have a library that does what you need

  if(led1_clock < millis()) { // is it time to do something with led1?
          .
          .
          .
      led1_clock = millis() + 4000; // Set the timer for led1 to be now + 4000 milliseconds

Unfortunately, this does not work when the millis() clock rolls over from 232 - 1 to zero. It also fails when the signed long you're using cross 231 and becomes negative. (JimboZ, you should use const unsigned long types for your intervals.)

To avoid these rollover problems, you must use unsigned integers, which requires a comparison like this:

unsigned long led1_clock = 0;

void loop()
{
  if (millis() - led1_clock > 4000UL) {
    led1_clock += 4000UL;  // next expiration maintains equal period, even if we got here late

Unsigned math allows this to work, even across a rollover.

And if your intervals are short, and you are testing frequently, you can use a smaller type than a 32-bit integer:

// The max interval for a 16-bit timer is 32768ms, the rollover period
unsigned int t = 0;

void loop()
{
  if ((unsigned int)millis() - t > 10000U) {

or even

// The max interval for an 8-bit timer is 256ms, the rollover period
unsigned char t = 0;

void loop()
{
  if ((unsigned char)millis() - t > 100) {

The casting of millis() is required to keep the comparison in the (efficient) smaller sizes.

Cheers,
/dev

/* With this sketch we can blink in the same time multiple leds
  *  with different intervals at the HIGH and LOW state for each led.
  */

 int ledPin =  11; 
 int ledPin_2 = 9;    
 int ledPin_1 = 10;
 
 void setup(){
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin_1, OUTPUT);
  pinMode(ledPin_2, OUTPUT);
 }
 void loop(){

 //cm = current time
   
  unsigned long cm = millis();
  unsigned long cm_1 = millis();
  
// "cm/x%y"  with different values in 'x' and 'y' we can control intervals.
    
    if (cm/1000%4 == 1) {
   digitalWrite(ledPin,HIGH);
   digitalWrite(ledPin_2,HIGH);
    } else {
      digitalWrite(ledPin,LOW);
      digitalWrite(ledPin_2,LOW);
    }
if (cm_1/600%2 == 1) {
   digitalWrite(ledPin_1,LOW);
   digitalWrite(ledPin_2,LOW);
    } else {
      digitalWrite(ledPin_1,HIGH);
      digitalWrite(ledPin_2,HIGH);
    }
 }

Try this one