Blink without delay three different timings

Hey guys,
I have been breaking my head over millis the past few days.
I want three different timings for a single led.

blink 3 times with a period of 500milliseconds; stay off for 10seconds.

unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previousOnBoardLedMillis = 0;   // will store last time the LED was updated
byte ledstate=LOW;

void setup() {
  pinMode(9,OUTPUT);

}

void loop() {
  currentMillis=millis();
  for(unsigned i=0; i<3; ++i){
  blinkled();
  digitalWrite(9,ledstate);
  }
 shut();
  digitalWrite(9,ledstate);
  
 
}

void blinkled() {
if(currentMillis - previousOnBoardLedMillis >=500) {
    // save the last time you blinked the LED 
    previousOnBoardLedMillis+=500;   

    // if the LED is off turn it on and vice-versa:
    if (ledstate == LOW)
    {
      ledstate = HIGH;
       }
    else
    { 
     ledstate = LOW;
    }
  }
}

void shut(){
  if(currentMillis - previousOnBoardLedMillis >=10000){
    previousOnBoardLedMillis+=10000;
    ledstate=LOW;
    }
  }

This code doesnt seem to work. It blinks with 500millisec period but doesnt stay off for 10 seconds.

This Adafruit tutorial has a good explanation about using millis. You should be able to adapt your code looking at the tutorial.

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/now-for-two-at-once

This is the same question as in the OP's earlier Thread

...R

Yes. I have made a previous post earlier. I made this again to get help. Doing two things at once is not the same as what in need.

I need:
on(500ms)off(500ms)on(500ms)off(500ms)on(500ms)off(500ms)off(10000ms)

This is the code I wrote and it doesnt work.

unsigned long currentmillis=0;
unsigned long previousmillis1=0;
unsigned long previousmillis2=0;
byte ledstate=LOW;
int ledpin=9;

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

void loop(){
  currentmillis=millis();
  for(uint8_t i=0;i<3;i++){
  blinkled();
  }
shut();
}

void blinkled(){
  if(ledstate==LOW){
  if(currentmillis-previousmillis1<=500){
    ledstate=HIGH;
    digitalWrite(ledpin,ledstate);
    previousmillis1+=500;
  }
}
else{
  if(currentmillis-previousmillis1<=500){
    ledstate=LOW;
    digitalWrite(ledpin,ledstate);
    previousmillis1+=500;
}
}
}

void shut(){
  if(ledstate==LOW){
  if(currentmillis-previousmillis2<=10000){
    ledstate=LOW;
    digitalWrite(ledpin,ledstate);
    previousmillis1+=10000;
  }
}
}

I would really appreciate the help

How about a less convoluted approach?

const char ledPin = 9;

bool blinking = true;
byte blinks = 0;

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

void loop() {
  static unsigned long lastEvent;
  unsigned long topLoop = millis();
  if (blinking) {
    if (topLoop - lastEvent >= 500) {
      lastEvent = topLoop;
      digitalWrite(ledPin, !digitalRead(ledPin));
      if (++blinks >= 6) {
        blinking = false;
        blinks = 0;
      }
    }
  } else if (topLoop - lastEvent >= 10000) {
    blinking = true;
  }
}

Your code seems simpler but the there seems to be a rather big glitch in it. Every once in a while, instead of staying off for 10 seconds, it would stay on. Any thoughts?

fame3096: Your code seems simpler but the there seems to be a rather big glitch in it. Every once in a while, instead of staying off for 10 seconds, it would stay on. Any thoughts?

Yes.

You did not use my code (there is no 'once in a while' possibility in it).

You could be writing to the pin with other code.

unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previousOnBoardLedMillis = 0;   // will store last time the LED was updated
byte ledstate=LOW;

void setup() {
  pinMode(9,OUTPUT);

}

void loop() {
  currentMillis=millis();
  for(unsigned i=0; i<3; ++i){
  blinkled();
  digitalWrite(9,ledstate);
  }
 shut();
  digitalWrite(9,ledstate);
  
 
}

void blinkled() {
if(currentMillis - previousOnBoardLedMillis >=500) {
    // save the last time you blinked the LED 
    previousOnBoardLedMillis+=500;   

    // if the LED is off turn it on and vice-versa:
    if (ledstate == LOW)
    {
      ledstate = HIGH;
       }
    else
    { 
     ledstate = LOW;
    }
  }
}

void shut(){
  if(currentMillis - previousOnBoardLedMillis >=10000){
    previousOnBoardLedMillis+=10000;
    ledstate=LOW;
    }
  }

You make a problem here. You set currentMillis once and then try to blink 3 times with the same value.

void loop() {
  currentMillis=millis();
  for(unsigned i=0; i<3; ++i){
  blinkled();
  digitalWrite(9,ledstate);
  }
 shut();
  digitalWrite(9,ledstate);
 }

You could move the assignment inside of the for-loop but why bother?
Get rid of the currentMillis variable and use millis() in your functions.

void blinkled() {
if(millis() - previousOnBoardLedMillis >=500) {

....

void shut(){
  if(millis() - previousOnBoardLedMillis >=10000){

Whandall: Yes.

You did not use my code (there is no 'once in a while' possibility in it).

You could be writing to the pin with other code.

Sorry about that. I got rid of the issue. I made a mistake in implementing your code. I added an else statement after your snippet : digitalwrite(ledpin,0) which I think contradicted with digitalWrite(ledPin, !digitalRead(ledPin));

Can you explain how digitalWrite(ledPin, !digitalRead(ledPin)); works?

fame3096: Can you explain how digitalWrite(ledPin, !digitalRead(ledPin)); works?

It sets the logical inverse (LOW gets HIGH, HIGH gets LOW) of the current state as the new state.

I's just a short form of

if (digitalRead(ledPin) == HIGH) {
  digitalWrite(ledPin, LOW);
} else {
  digitalWrite(ledPin, HIGH);
}
if(hr_average>85)
{
 static unsigned long lastEvent;
  unsigned long topLoop = millis();
  if (blinking) {
    if (topLoop - lastEvent >= 500) {
      lastEvent = topLoop;
      digitalWrite(ledPin, !digitalRead(ledPin));
      if (++blinks >= 6) {
        blinking = false;
        blinks = 0;
      }
    }
  } else if (topLoop - lastEvent >= 10000) {
    blinking = true;
  }
  }

In the above, What happens if the heart rate is <85. Should I include an else statement? I want my led to stay off as long as the heart rate is <85.

static unsigned long lastEvent;
unsigned long topLoop = millis();

if(hr_average>85)
{
  if (blinking) {
    if (topLoop - lastEvent >= 500) {
      lastEvent = topLoop;
      digitalWrite(ledPin, !digitalRead(ledPin));
      if (++blinks >= 6) {
        blinking = false;
        blinks = 0;
      }
    }
  } else if (topLoop - lastEvent >= 10000) {
    blinking = true;
  }
} else {
   digitalWrite(ledPin, LOW);
   blinking = false;
   blinks = 0;
}

Isn't it supposed to be

 else {
   digitalWrite(ledPin, LOW);
   blinking = true;
   blinks = 0;
}

I am sorry but my logic comprehension is poor. what state does true and false imply? For the 10 seconds off time, blinking is true, so I thought it should be the same in the else statement also.

You are right, my bad. :wink:

That’s one of the problems with snippets, you can not test them.

Thank you very much for the help.
Let me get this right:
blinking = true is for off state
blinking = false is for on state?

Blinking means the blinking phase of your led cycle (3 on/off), not blinking is the 10 second off phase.

It depends in which state you want to start, when the rate reaches the threshold

There it will be no real problem if you use the first version. Normally the ten second no-blink-phase will be long over when the heartrate rises the next time.

fame3096: I am sorry but my logic comprehension is poor. what state does true and false imply? For the 10 seconds off time, blinking is true, so I thought it should be the same in the else statement also.

false is zero, true is non-zero -- but you can make of them what you want.

This works for bits as well as variables which is why I doubt it will change with binary hardware. The CompSci priesthood likes to say it could change at any time but then they relate to hardware like a Victorian Maiden Aunt relates to sex.

How many programmers does it take to change a lightbulb? Can't be done, it's a HARDWARE PROBLEM.

But really, learn bit math. A single byte can hold 8 T/F states in order, an unsigned long holds 32. There are operations that you work all the bits between 2 integers in a single cycle rather than large/cumbersome if-type logic. http://playground.arduino.cc/Code/BitMath