/*
============================
Selfmade For-Loop IV
============================
This is an example of a "selfmade" for-loop
which is usually required where a a non-blocking
loop is required e.g. to blink an LED
This is an example of a non-blocking millis() function replacing delay()
to blink a LED and counting a variable in given time intervals
It is more or less identical to Selfmade For-Loop III but
the handling of the LED and the counting are taken out of loop()
into separate functions to "reduce complexity"; it is easier to understand
and test functions which are short and at least do not require scrolling
of the screen
First Edition 2023-04-02
ec2021
Simulation: https://wokwi.com/projects/360905879808368641
Discussion: https://forum.arduino.cc/t/millis-instead-of-delay-and-loop-instead-of-for-loop/1110044
Changed 2023-07-26
*/
constexpr byte LEDPin = 13;
constexpr int MaxCount = 9;
void setup() {
Serial.begin(115200);
pinMode(LEDPin, OUTPUT);
}
void loop() {
handleLED();
doCountingUpTo(MaxCount);
}
void handleLED(){
static unsigned long lastChange = 0; // Variable to store the time in ms when ledState was changed
static unsigned long delayTime = 300; // Delay in [ms] when then next change shall take place
static boolean firstChange = true; // To make sure that the if-clause is entered in the first call
// of this function
if (millis()-lastChange >= delayTime || firstChange){
lastChange = millis();
firstChange = false;
boolean ledState = digitalRead(LEDPin);
digitalWrite(LEDPin, !ledState);
}
}
void doCountingUpTo(int iMax){
static unsigned long lastCount = 0;
static unsigned long delayCount = 500;
static boolean firstCount = true;
static int i = 0;
if (millis()-lastCount >= delayCount||firstCount){
lastCount = millis();
firstCount = false;
if (i <= iMax) {
Serial.print(i);
Serial.print("\t"); // prints tabs
i++;
} else {
Serial.println();
i = 0;
}
}
}