edit: V3 is in post 44, a ways below.
edit 5/19/22: progress on comments & docs, still to go; state machine doc.
-------------------- wondering when it won't fit one post.
This is version 2 of a code technique demonstration sketch. A how-to.
It now shows how to repeat steps without blocking void loop().
A future version will have functions in loop() running as parallel tasks and that should open minds about easier ways to approach real world coding.
I'd also like to discuss what other blocking code the demo does not address so it can be covered.
// 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"
const byte ledPin = 13;
unsigned long delayStart, delayWait;
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 0 :
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 = 1; // when the switch-case runs again it will be case 1 that runs
break; // exit switch-case
case 1 :
digitalWrite( ledPin, LOW );
Serial.println( F( "Case 1 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 500;
blinkStep = 2;
break;
case 2 :
digitalWrite( ledPin, HIGH );
Serial.println( F( "Case 2 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 250;
blinkStep = 3;
break;
case 3 :
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 = 2;
}
else
{
index = 0;
blinkStep = 4;
} // how to for-loop in a state machine without blocking execution.
break;
case 4 :
digitalWrite( ledPin, HIGH );
Serial.println( F( "Case 4 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 1000;
blinkStep = 5;
break;
case 5 :
digitalWrite( ledPin, LOW );
Serial.print( F( "Case 5 doing something unspecified here at " ));
Serial.println( delayStart = millis());
delayWait = 1000;
blinkStep = 0;
break;
}
}
void loop() // runs over and over, see how often
{
BlinkPattern();
}