/*
   ============================
   Millis() Function Example
  ============================
   
   This is an example of a non-blocking millis() function replacing delay() 

   First Edition 2023-04-02
   ec2021

   Simulation: https://wokwi.com/projects/360903822433974273
   Discussion: https://forum.arduino.cc/t/millis-instead-of-delay-and-loop-instead-of-for-loop/1110044/7

   Changed 2023-07-26 

*/

constexpr byte LEDPin = 13;

void setup() {
   Serial.begin(115200);
   pinMode(LEDPin, OUTPUT);
}

unsigned long lastChange = 0;    // Variable to store the time in ms when ledState was changed 
unsigned long delayTime  = 300;  // Delay in [ms] when then next change shall take place 
boolean firstTime = true;        // Boolean that ensures that the if-clause will be performed immediately
                                 // in the first call

void loop() {

  if (millis()-lastChange >= delayTime || firstTime){ 
                                         // As "firstTime" has been set to true when the sketch started
                                         // it will definitely perform what's inside the curly brackets
                                         // immediately in the first loop()
                                         // The greater in ">="" is required as we cannot always be sure
                                         // that this comparison is performed exactly "delayTime" later ...

    lastChange = millis();               // Stores this time so that it takes in mininimum delayTime for
                                         // the next entry to this bracket procedures  

    boolean ledState = digitalRead(LEDPin);  // Read the actual status of the ledPin, so we do not have
                                             // to memorize and handle it in a variable

    digitalWrite(LEDPin, !ledState);         // Change the status by inverting ledState with the ! operator
                                             // !ledState provides the opposite of ledState

    firstTime = false;                       // "firstTime" is set to false to make sure    
                                             // that in future the entry into the if-clause only depends
                                             // on the comparison of the time difference between "millis()"
                                             // and "lastChange" with "delayTime"
   }
 
}