Here's one adapted from Millis() instead of delay and loop() instead of for-loop - #21 by DaveX
You could add an external switch instead of the boolean constant to toggle between blocking an non-blocking modes.
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN,OUTPUT);
}
void loop() {
const bool doBlocking = true; // choose between blocking or non-blocking code
const unsigned long quickInterval = 250; //
const unsigned long slowInterval = 1000;
if (doBlocking == true) { // use delay() and for(;;)
for (int i = 0 ; i < 4 ; ++i) {
toggleLed();
Serial.print(i);
Serial.print(" ");
delay(quickInterval);
}
Serial.println("-- blocking");
delay(slowInterval);
} else { // unblocked loop() by:
// * replacing delays with millis() edge-detectors/state machines
// * replacing for(;;) loop with a counter state machine
// state variables to persist values past the end of loop()'s scope
static int i = 0; // digit to print
static unsigned long lastDigitMs = -quickInterval; // backdate by -quickInterval for immediate operation
static unsigned long lastLineMs = 0; // state variable for edge-detecting slow delay
unsigned long now = millis(); // remember the loop time
// edge detecting state machine {i,now-las}
if (i < 4 && now - lastDigitMs >= quickInterval) { // edge-detect interval change
lastDigitMs = now; // measure digit delay from last digit print
toggleLed();
Serial.print(i);
Serial.print(" ");
++i;
lastLineMs = now; // measure line ending delay from last print time
}
// edge-detecting state machine
if (i >= 4 && now - lastLineMs >= slowInterval) {
Serial.println( "-- nonblocking");
i = 0; // reset the count
}
}
}
void toggleLed(void){
digitalWrite(LED_BUILTIN,digitalRead(LED_BUILTIN)==HIGH?LOW:HIGH);
}
