Non-blocking led loop

Hi guys, im looking for some help getting the function airStrobe() to be non-blocking. I get the concept but I just carn't seem to get my head around this nested non-blocking code. Below is the original code with delays, and also my attempt at making it non-blocking. Thanks

Code with delays:

void airStrobe(int t) {
  static unsigned long previousUpdateTime;
  if(millis()-previousUpdateTime > t){
    previousUpdateTime = millis();
    digitalWrite(ledPins[0], HIGH);
    digitalWrite(ledPins[1], HIGH);
    delay(50);   
    digitalWrite(ledPins[0], LOW);
    digitalWrite(ledPins[1], LOW);
    delay(100);   
    digitalWrite(ledPins[0], HIGH);
    digitalWrite(ledPins[1], HIGH);
    delay(50);
    digitalWrite(ledPins[0], LOW);
    digitalWrite(ledPins[1], LOW);
    delay(10);
    digitalWrite(ledPins[2], HIGH);
    digitalWrite(ledPins[3], HIGH);
    delay(50);   
    digitalWrite(ledPins[2], LOW);
    digitalWrite(ledPins[3], LOW);
    delay(100);   
    digitalWrite(ledPins[2], HIGH);
    digitalWrite(ledPins[3], HIGH);
    delay(50);
    digitalWrite(ledPins[2], LOW);
    digitalWrite(ledPins[3], LOW);
  }
}

Attempt at non-blocking code:

const int pinCount = 4;
static unsigned long previousUpdateTime;

void setup()  {   
  for (int thisPin = 0; thisPin < pinCount; thisPin++)  {
    pinMode(ledPins[thisPin], OUTPUT);  
  }
} 

void loop()  {
  airStrobe(3000);
}

void airStrobe(int t) {
  if(millis()-previousUpdateTime > t){
  
    static unsigned long updateDelay;    
    static unsigned long blinkDelay = millis()-updateDelay; // non-blocking var
    
    if(blinkDelay < 50) {
      previousUpdateTime = millis();
      digitalWrite(ledPins[0], HIGH);
      digitalWrite(ledPins[1], HIGH); 
    } else if(blinkDelay >= 50 && blinkDelay < 150)  { //delay(50);  
      digitalWrite(ledPins[0], LOW);
      digitalWrite(ledPins[1], LOW);
    } else if(blinkDelay >= 150 && blinkDelay < 200) { //delay(100);
      digitalWrite(ledPins[0], HIGH);
      digitalWrite(ledPins[1], HIGH);
    } else if(blinkDelay >= 200 && blinkDelay < 210) { //delay(50);
      digitalWrite(ledPins[0], LOW);
      digitalWrite(ledPins[1], LOW);
    } else if(blinkDelay >= 210 && blinkDelay < 260) { //delay(10);
      digitalWrite(ledPins[2], HIGH);
      digitalWrite(ledPins[3], HIGH);      
    } else if(blinkDelay >= 260 && blinkDelay < 310) { //delay(50);
      digitalWrite(ledPins[2], LOW);
      digitalWrite(ledPins[3], LOW);
    } else if(blinkDelay >= 310 && blinkDelay < 410) { //delay(100);
      digitalWrite(ledPins[2], HIGH);
      digitalWrite(ledPins[3], HIGH);
    } else if(blinkDelay >= 410 && blinkDelay < 460) { //delay(50);
      digitalWrite(ledPins[2], LOW);
      digitalWrite(ledPins[3], LOW);
    } else if(blinkDelay >= 460) {
      updateDelay = millis();
    }
    
  }
}

You declare a variable blinkDelay, but never assign it a value.

Arrch:
You declare a variable blinkDelay, but never assign it a value.

Is this any better ?

void airStrobe(int t) {
  if(millis()-previousUpdateTime > t){
  
    static unsigned long blinkDelay = millis(); // non-blocking var
    
    if(blinkDelay < 50) {
      previousUpdateTime = millis();
      digitalWrite(ledPins[0], HIGH);
      digitalWrite(ledPins[1], HIGH); 
      Serial.println("airStrobe: 1");    
    } else if(blinkDelay >= 50 && blinkDelay < 150)  { //delay(50);  
      digitalWrite(ledPins[0], LOW);
      digitalWrite(ledPins[1], LOW);
      Serial.println("airStrobe: 2");   
    } else if(blinkDelay >= 150 && blinkDelay < 200) { //delay(100);
      digitalWrite(ledPins[0], HIGH);
      digitalWrite(ledPins[1], HIGH);
      Serial.println("airStrobe: 3");    
    } else if(blinkDelay >= 200 && blinkDelay < 210) { //delay(50);
      digitalWrite(ledPins[0], LOW);
      digitalWrite(ledPins[1], LOW);
      Serial.println("airStrobe: 4");
    } else if(blinkDelay >= 210 && blinkDelay < 260) { //delay(10);
      digitalWrite(ledPins[2], HIGH);
      digitalWrite(ledPins[3], HIGH);      
      Serial.println("airStrobe: 5");
    } else if(blinkDelay >= 260 && blinkDelay < 310) { //delay(50);
      digitalWrite(ledPins[2], LOW);
      digitalWrite(ledPins[3], LOW);
      Serial.println("airStrobe: 6");
    } else if(blinkDelay >= 310 && blinkDelay < 410) { //delay(100);
      digitalWrite(ledPins[2], HIGH);
      digitalWrite(ledPins[3], HIGH);
      Serial.println("airStrobe: 7");
    } else if(blinkDelay >= 410 && blinkDelay < 460) { //delay(50);
      digitalWrite(ledPins[2], LOW);
      digitalWrite(ledPins[3], LOW);
      Serial.println("airStrobe: 8");
    } else if(blinkDelay >= 460) {
      blinkDelay = 0;
    }
    
  }
}

It has a value, but it never changes:

    static unsigned long blinkDelay = millis()-updateDelay; // non-blocking var

Using "static" means it is only computed once. Try removing "static".

Now it is only ever set to 0.

Try using not led but printing on serial monitor.
on setup:

void setup()  
{ delay(1000);
  Serial.begin(9600);
  ...

First time only okay, after it reach 9 no restart:

void airStrobe(int t) {
  if(millis()-previousUpdateTime > t)
  { static unsigned long updateDelay=millis();    
    static unsigned long blinkDelay=0; // non-blocking var
    
    blinkDelay=millis()-updateDelay;
    Serial.print(blinkDelay); Serial.print("="); Serial.print(millis()); Serial.print("-"); Serial.println(updateDelay);
    if(blinkDelay < 50) {
      Serial.println("1");
    } else if(blinkDelay >= 50 && blinkDelay < 150)  { //delay(50);  
      Serial.println("2");
    } else if(blinkDelay >= 150 && blinkDelay < 200) { //delay(100);
      Serial.println("3");
    } else if(blinkDelay >= 200 && blinkDelay < 210) { //delay(50);
      Serial.println("4");
    } else if(blinkDelay >= 210 && blinkDelay < 260) { //delay(10);
      Serial.println("5");
    } else if(blinkDelay >= 260 && blinkDelay < 310) { //delay(50);
      Serial.println("6");
    } else if(blinkDelay >= 310 && blinkDelay < 410) { //delay(100);
      Serial.println("7");
    } else if(blinkDelay >= 410 && blinkDelay < 460) { //delay(50);
      Serial.println("8");
    } else if(blinkDelay >= 460) {
      Serial.println("9");
      updateDelay = millis();
      previousUpdateTime=millis();
    }
  }
}

because "static unsigned long updateDelay=..." is executed only first time.

static unsigned long updateDelay=millis();

You totally decided to ignore my suggestion.

Not true. We need to remember previous value, so static seem to be useful.
I think it's not possible to find a solution follow this method. But I suggest @driz to use Serial.print to debug.

Now it seem to function:

const byte pinCount = 4;
unsigned long previousUpdateTime;

void setup()  {   
  delay(1000);
  Serial.begin(9600);
  //for (int thisPin = 0; thisPin < pinCount; thisPin++)  {
  //  pinMode(ledPins[thisPin], OUTPUT);  
  //}
} 

void loop()  {
  airStrobe(3000);
}

void airStrobe(int t) {
  if(millis()-previousUpdateTime > t)
  { static unsigned long updateDelay;    
    static unsigned long blinkDelay; // non-blocking var
    static boolean start=false;
    if(!start) 
    { start=true;
      updateDelay=millis();
    }   
    blinkDelay=millis()-updateDelay;
    Serial.print(blinkDelay); Serial.print("="); Serial.print(millis()); Serial.print("-"); Serial.println(updateDelay);
    if(blinkDelay < 50) {
      Serial.println("1");
    } else if(blinkDelay >= 50 && blinkDelay < 150)  { //delay(50);  
      Serial.println("2");
    } else if(blinkDelay >= 150 && blinkDelay < 200) { //delay(100);
      Serial.println("3");
    } else if(blinkDelay >= 200 && blinkDelay < 210) { //delay(50);
      Serial.println("4");
    } else if(blinkDelay >= 210 && blinkDelay < 260) { //delay(10);
      Serial.println("5");
    } else if(blinkDelay >= 260 && blinkDelay < 310) { //delay(50);
      Serial.println("6");
    } else if(blinkDelay >= 310 && blinkDelay < 410) { //delay(100);
      Serial.println("7");
    } else if(blinkDelay >= 410 && blinkDelay < 460) { //delay(50);
      Serial.println("8");
    } else if(blinkDelay >= 460) {
      Serial.println("9");
      updateDelay = millis();
      previousUpdateTime=millis();
      start=false;
    }
  }
}

nid69ita:
Not true. We need to remember previous value, so static seem to be useful.
I think it's not possible to find a solution follow this method. But I suggest @driz to use Serial.print to debug.

An assignment done on a "static" variable is done once. If you want to preserve the variable make the declaration one line, and the assignment another line.

Sorry Nick, I did try your suggestion but could not get it to work. However thank you for explaining to me what a static variable does

Thank you very much nid69ita ! your solution seems to work as intended and I will be using it :slight_smile:

You guys really are awesome and I appreciate your input very much. This truly is a great forum with some very helpful people and ideas.