Using millis() and micros() instead of delay

Hello!
I would like to know how to execute a task at certain given intervals, without using delay, so other things can be executed at the same time. One method I found was the BlinkWithoutDelay example, but that example blinks the LED at regular intervals. I want to execute a task at intervals that can change, perhaps very quickly (e.g. pulsing an IR LED using and array of time intervals), or just do something for 5 seconds, wait 7 seconds, do it for 1 second, etc. then stop that function, without affecting other tasks. Also, is millis() accurate enough to execute a task every 15 minutes? Will noInterrupts() disable or affect micros()? Any help or example program is greatly appreciated!

Take another look at the [u]Blink Without Delay example[/u]. You can change the interval every time throught the loop,* and you can have multiple intervals & multiple previous-times (with different variable names) for multiple-different timers running at the same time.

I'd say you should probably avoid using delay, unless you truly want to delay or pause. For most timing applications, you want to keep the program going, while keeping track of the time in the background.

Also, is millis() accurate enough to execute a task every 15 minutes?

Sure! But, it's up to your program to be checking the time in a loop... If you are doing something else complicated, or something else that can't be interrupted, and you only get-back to checking the time every 10 minutes... it ain't gonna be that accruate! :D

I've haven't used interrupts on the Arduino, so someone else can jump-in and help with that.

* P.S. Actually, you wouldn't want to change the time every-time through the loop... You would probably only want to change it when the "time's up". For example, you could change the interval to a random time between 100 and 1000mS, every time the LED goes on or off.

In addition to the "Blink Without Delay" approach Doug describes, I've put together some simple cooperative multi-tasking code and attached it to http://arduino.cc/forum/index.php/topic,93959.0.html - which allows scheduling at specified times and after specified delays. There are three files - one is a header file, one is a simple LED blinking application, and the third contains the multi-tasking code.

int interval[] = {5000, 2000, 800, 1000};
long mill;
long prev = 0;
byte index = 0;
void setup(){
  println(mill-prev+"!!!");
}
void draw(){
  mill = millis();
  if (mill - prev >= interval[index]){
    println(mill-prev);
    prev = mill;
    index++;
    if (index > 3) index = 0;
  }
}

I just made up this code to try in Processing, and it works! It "delays" the println() command in the draw by an array of intervals! Unfortunately, the millis() function is up to +/- 17 ms off, but if the code isn't too time-sensitive, that's fine. I can do something similar for Arduino! I'll try Morris Dovey's code when I have time.

I can do something similar for Arduino!

but without the the "!!!" unless you like mysteries.

but without the the “!!!” unless you like mysteries.

Hehe! That was just randomness (I’ve heard that it causes some glitch on the Mega, or something). If you have Processing, you can try my code. It’s easy to modify for Arduino, too! Problem solved!

/** Millis
By dkl65 on Arduino Forum
This code delays a println statement in the draw by an array of
time to "wait". You can do other random things while the println
is "waiting" to run again. The loop println the number of ms
elapsed. This code is for Processing.
*/
//Array of ms intervals to "wait"
int interval[] = {5000, 2000, 800, 1000};
long mill; //store the current millis
long prev = 0; //store the previous millis
byte index = 0; //the index number of intervals
//store the number of times to println(mill-prev); in draw
byte counter = 0; 
void setup(){
  println(mill-prev+"!!!"); //BEGIN!!!
}
void draw(){
  mill = millis(); //initiate the current millis
  //if interval[index] ms has passed, and ran less than 9 times
  if (mill - prev >= interval[index] && counter < 8){
    println(mill-prev); //the function to be run
    prev = mill;
    index++;
    //go back to the beginning of the array
    if (index > 3) index = 0;
    //you will see 8 ms elapsed lines in the console
    counter++;
  }
  if (counter == 8){
    println("DONE!!!");
    counter = 9; //Never run this function again!
  }
}