I shaved off a few bytes and added names to the cases. Easy to add more, in any order, as their numeric representation isn't used. The names make it easier when debugging:
// NoBlockUndelayDemo2 2022 by GoForSmoke @ Arduino.cc Forum
// Free for use, May 10, 2022 by GFS. Compiled on Arduino 2.1.0.5
// This sketch shows a general method to get rid of delays in code.
// You could upgrade code with delays to work with add-a-sketch.
// .. adding looped cases
// #include <avr/io.h> --- remove this line per Railroader, it's no longer needed
#include "Arduino.h"
enum {LED_ON_500, LED_OFF_500, LED_ON_250, LED_OFF_250, LED_ON_1_SEC, LED_OFF_1_SEC};
const byte ledPin = 13;
unsigned long delayStart;
word delayWait; //65535ms max
const byte indexMax = 12;
byte index;
void setup()
{
Serial.begin( 115200 );
Serial.println( F( "\n\n\n Un-Delay Example, free by GoForSmoke\n" ));
Serial.println( F( "This sketch shows how to get rid of delays in code.\n" ));
pinMode( ledPin, OUTPUT );
};
/* The section of the original sketch with delays:
*
* digitalWrite( ledPin, HIGH ); -- 0
* delay( 500 );
* digitalWrite( ledPin, LOW ); -- 1
* delay( 500 );
* for ( i = 0; i < 12; i++ )
* (
* digitalWrite( ledPin, HIGH ); -- 2
* delay( 250 );
* digitalWrite( ledPin, LOW ); -- 3
* delay( 250 );
* }
* digitalWrite( ledPin, HIGH ); -- 4
* delay( 1000 );
* digitalWrite( ledPin, LOW ); -- 5
* delay( 1000 );
*/
byte blinkStep; // state tracking for BlinkPattern() below
void BlinkPattern()
{
// This one-shot timer replaces every delay() removed in one spot.
// start of one-shot timer
if ( delayWait > 0 ) // one-shot timer only runs when set
{
if ( millis() - delayStart < delayWait )
{
return; // instead of blocking, the undelayed function returns
}
else
{
delayWait = 0; // time's up! turn off the timer and run the blinkStep case
}
}
// end of one-shot timer
// here each case has a timed wait but cases could change Step on pin or serial events.
switch( blinkStep ) // runs the case numbered in blinkStep
{
case LED_ON_500 :
digitalWrite( ledPin, HIGH );
Serial.println( F( "Case 0 doing something unspecified here at " ));
Serial.println( delayStart = millis()); // able to set a var to a value I pass to function
delayWait = 500; // for the next half second, this function will return on entry.
blinkStep = LED_OFF_500; // when the switch-case runs again it will be case 1 that runs
break; // exit switch-case
case LED_OFF_500 :
digitalWrite( ledPin, LOW );
Serial.println( F( "Case 1 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 500;
blinkStep = LED_ON_250;
break;
case LED_ON_250 :
digitalWrite( ledPin, HIGH );
Serial.println( F( "Case 2 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 250;
blinkStep = LED_OFF_250;
break;
case LED_OFF_250 :
digitalWrite( ledPin, LOW );
Serial.println( F( "Case 3 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 250;
// this replaces the for-loop in non-blocking code.
if ( index++ < indexMax ) // index gets incremented after the compare
{
blinkStep = LED_ON_250;
}
else
{
index = 0;
blinkStep = LED_ON_1_SEC;
} // how to for-loop in a state machine without blocking execution.
break;
case LED_ON_1_SEC :
digitalWrite( ledPin, HIGH );
Serial.println( F( "Case 4 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 1000;
blinkStep = LED_OFF_1_SEC;
break;
case LED_OFF_1_SEC :
digitalWrite( ledPin, LOW );
Serial.print( F( "Case 5 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 1000;
blinkStep = LED_ON_500;
break;
}
}
void loop() // runs over and over, see how often
{
BlinkPattern();
}