Hi,
no laughing about beeing a beginner. If you write a good joke it is different.
if you ahve any questions about the demo-codes just ask them.
explaining non-blocking-timing based on function millis():
delay() is blocking. As long as the delay is "delaying" nothing else of the code can be executed.
Now there is a technique of non-blocking timing.
The basic principle of non-blocking timing is fundamental different from using delay()
You have to understand the difference first and then look into the code.
otherwise you might try to "see" a "delay-analog-thing" in the millis()-code which it really isn't
Trying to see a "delay-analog-thing" in millis() makes it hard to under stand millis()
Having understood the basic principle of non-blocking timing based on millis() makes it easy to understand.
imagine baking a frosted pizza
the cover says for preparation heat up oven to 200°C
then put pizza in.
Baking time 10 minutes
You are estimating heating up needs 3 minutes
You take a look onto your watch it is 13:02
You start reading the newspaper and from time to time looking onto your watch
watch 13:02 not yet time
watch 13:03 not yet time
watch 13:04 not yet time
watch 13:05 when did I start 13:02 OK 13:05 - 13:02 = 3 minutes time to put pizza into the oven
New basetime 13:05
watch 13:06 not yet time
watch 13:07 not yet time
watch 13:08 not yet time
watch 13:09 not yet time
watch 13:10 not yet time
watch 13:11 not yet time
watch 13:12 not yet time
watch 13:13 not yet time
watch 13:14 not yet time
watch 13:15 when did I start 13:05 OK 13:15 - 13:05 = 10 minutes time to eat pizza (yum yum)
You did a repeated comparing how much time has passed by
This is what non-blocking timing does
In the code looking at "How much time has passed by" is done
currentTime - startTime >= bakingTime
bakingTime is 10 minutes
13:06 - 13:05 = 1 minute >= bakingTime is false
13:07 - 13:05 = 2 minutes >= bakingTime is false
...
13:14 - 13:05 = 9 minutes >= bakingTime is false
13:15 - 13:05 = 10 minutes >= bakingTime is TRUE time for timed action!!
if (currentTime - previousTime >= period) {
it has to be coded exactly this way because in this way it manages the rollover from Max back to zero
of the function mills() automatically
and a demo-code
unsigned long currentMillis;
unsigned long Period = 1000; // after 1000 milliseconds a "period" has passed by
unsigned long LastTime_Period_Elapsed;
unsigned long SlowDownPeriod = 20; // print a new character every 20 milliseconds so your eyes can follow the serial-output
unsigned long LastTime_SlowDownPeriod_Elapsed;
unsigned long DoubleCrossPeriod = 5 * SlowDownPeriod; // every 5th character shall be a #
unsigned long LastTime_DoubleCrossPeriod_Elapsed;
int NumberOfElapsedPeriods = 0;
const char dot = '.';
const char doubleCross = '#';
char CharToPrint;
void setup() {
Serial.begin(115200);
LastTime_Period_Elapsed = millis();
LastTime_SlowDownPeriod_Elapsed = millis();
LastTime_DoubleCrossPeriod_Elapsed = millis();
}
void loop() { // main-loop is running at high speed
currentMillis = millis(); // update timing-variable each time the main-loop starts again
visualiseLooping(); // this function gets called with every run of the loop
// but contains logic to execute parts of its code
// only if a certain amount of time has passed by
// this part shows the same principle check if a certain amount of time has passed by
// if yes execute commands inside the if-condition
// the variable period contains the number of milliseconds
// if THIS number of milliseconds has passed by the if-condition becomes true
// ==> the code inside the if-condition is executed
if (currentMillis - LastTime_Period_Elapsed >= Period) {
LastTime_Period_Elapsed = currentMillis; // first thing to do is updating this variable
NumberOfElapsedPeriods ++;
Serial.println();
Serial.print(NumberOfElapsedPeriods);
Serial.println(" seconds is over");
}
}
// every time a certain amount of time has passed by a character is printed to the serial monitor
// for your application you just put your code that shall be executed in such a timing-pattern
// inside the if-condition that checks the time that has passed by
void visualiseLooping() {
if (currentMillis - LastTime_DoubleCrossPeriod_Elapsed >= DoubleCrossPeriod) {
LastTime_DoubleCrossPeriod_Elapsed = currentMillis;
CharToPrint = doubleCross;
}
else {
CharToPrint = dot;
}
if (currentMillis - LastTime_SlowDownPeriod_Elapsed >= SlowDownPeriod) {
LastTime_SlowDownPeriod_Elapsed = currentMillis;
Serial.print(CharToPrint);
}
}
and here is a variant that I peronally prefer
unsigned long DemoTimerA = 0; // variables that are used to store timeInformation
unsigned long DemoTimerB = 0;
unsigned long DemoTimerC = 0;
unsigned long DoDelayTimer = 0;
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - expireTime >= TimePeriod )
{
expireTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
void setup()
{
Serial.begin(115200);
Serial.println("Program started activate Show timestamp in serial monitor");
}
void loop()
{
if ( TimePeriodIsOver(DemoTimerA,1000) )
{
Serial.println(" TimerA overDue");
}
if ( TimePeriodIsOver(DemoTimerB,2000) )
{
Serial.println(" TimerB overDue");
}
if ( TimePeriodIsOver(DemoTimerC,3000) )
{
Serial.println(" TimerC overDue");
}
if ( TimePeriodIsOver(DoDelayTimer,20000) )
{
Serial.println("every 20 seconds execute delay(3500)... to make all other timers overdue");
delay(3500);
}
}
best regards Stefan