How do I eliminate delay()?

How do I eliminate delay() from the following function (similar to the example "BlinkWithoutDelay")?

//function to blink LED status code
void blinkLED(int code)
{
  for(int i = 0; i < code; i++)
    {
    	digitalWrite(ledPin, HIGH);
    	delay(200);
    	digitalWrite(ledPin, LOW);
    	delay(200);
    }
    delay (1000);
}

I know I should use millis(), but I don't know how.

Thanks Nick that was very helpful. I have come up with the following but the LED stays on.

//function to blink LED status code
void blinkLED2(int code)
{
      int x = 0;
  startcycle:
      digitalWrite(ledPin, HIGH);
      HpreviousMillis = millis(); // when it went HIGH

      if(millis() - HpreviousMillis > 200)
      {
        digitalWrite(ledPin, LOW);
        LpreviousMillis = millis(); // when it went LOW
        x=x+1;
      }
      
      if(millis() - LpreviousMillis > 200)
      {
        if (x < code) goto startcycle;
      }
}

What I need to do is step through this code or set break points and display the variables (debug) to see where my logic fails. I can't see how I can do this with Arduino.Exe. Are there other debugging tools I can use?

First, please please rewrite without goto. You'll thank me for it later.

Now:

     HpreviousMillis = millis(); // when it went HIGH

      if(millis() - HpreviousMillis > 200)

That "if" will never be true will it? Unless it takes over 200 mS to go from the first line to the second line, which it won't.

If you are calling a function to blink the led, why does it matter if you use delay()? Program execution will wait until the function is done anyway...

Instead of counting how many times the led has flashed, keep track of how long in terms of time it has been flashing.

why does it matter if you use delay()? Program execution will wait until the function is done anyway...

The whole point is that I don't want the processor to wait because while the processor sits and waits and twiddles its thumbs it will miss encoder pulses and loose track of it's location, it will miss the bumper switches and might crash into the wall, it will delay updating the ultrasonic distance sensor and crash into another wall, it will miss remote IR control transmissions, it won't stop the motor when it should, etc... Flashing the LED has priority number 97 in all the other tasks the processor has to do. The real world can't sit around and wait while it finishes flashing.

warren631:
The whole point is that I don't want the processor to wait

The point of my question was to help you realize that just because you are using millis() doesn't automatically mean your program does more. In your current structure it appears you plan to call a function which will flash the LED a specific number of times. The problem is that whether you do that counting loop with millis() or delay(), nothing else is executed until the function returns. (Unless all of the important events are interrupt based, in which case delay() isn't an issue.)

If you just want a heart beat, that is really simple. Setup these globals and put this code in your loop() function.

// Setup some globals for the heart beat
#define heartINTERVAL 500
unsigned long heartWait=millis() + heartINTERVAL;

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  // check to see if it time to toggle yet
  if ((long)(millis() - heartWait)>=0) { 
    // easy way to toggle an output
    digitalWrite(13, !digitalRead(13));  // toggle state
    // wait until the next time to toggle
    heartWait += heartINTERVAL;
  }
}

If you want the LED to flash for a specific number of times, you need to re-write your function so that it uses globals to track the state of the LED's flashing. Then in the loop() you call that function on a periodic basis so that it can properly update the led.

// Globals necessary to track the state of the LED
bool startFlashLED = false;
unsigned int flashCount = 0;
unsigned long waitUntilFlash = 0;
#define INTERVAL 500

// Call this function on a regular basis.  It will maintain the LED independent of the rest of the code.
void updateLED() {
  // whenever you want the led to flash, set the global startFlashLED to true
  if (startFlashLED == true) {
    // this will kick-off the flashing sequence, adjust flashCount and INTERVAL to suit your needs
    startFlashLED = false;
    flashCount = 10;  // set 2x the number of times you want the LED to turn on
    waitUntilFlash = millis() + INTERVAL;
    digitalWrite(13, HIGH);
  }
   
  // if flashCount is 0, we weren't suppose to be flashing so return
  if (flashCount==0)
   return; 
  
  // check if enough time has passed to toggle the LED
  if ((long)(millis() - waitUntilFlash)>=0) {
    // simple way to toggle the LED state
    digitalWrite(13, !digitalRead(13)); // toggle LED
    // wait for another INTERVAL
    waitUntilFlash += INTERVAL;
    flashCount--;
  }
  // reached the end of flash sequence, turn off the LED
  if (flashCount==0)
    digitalWrite(13, LOW);  
}


// Example Code:
void setup() {
  pinMode(13, OUTPUT);
}

void loop() { 
  // this example will flash the LED 5 times, every 10 seconds.
  startFlashLED = true;  // put this line anywhere you want to start the flashing 
  updateLED();  // placed somewhere inside of loop()
  for(int x=0; x<10000; x++) {
    delay(1);
    updateLED();  // it is placed here to demonstrate a long operation. 
  }
}

Thanks to all replies, but I cheated: I copied Byron Guernsey's "syncLED" library from http://arduino-library-syncled.googlecode.com/svn/trunk/SyncLED/
It does exactly what I need - a status LED flasher without delay(). Useful for anyone else looking for a LED status flasher.