The basics are simple once you understand them.
To write a non-blocking delay function
/*
non-blocking delay
In:
delay duration
*/
bool myDelay(uint32_t duration)
{
static uint32_t startTime;
static bool inProgress = false;
// if delay not started yet
if(inProgress == false)
{
// remember the start time
startTime = millis();
// indicate that delay is in progress
inProgress = true;
}
// if delay is in progress
else
{
// check if time has lapsed
if(millis() - startTime >= duration)
{
// indicate that the delay has finished
inProgress = false;
// tell caller that delay is finished
return true;
}
}
// tell caller that delay is still in progress
return false;
}
You will have to call this function repeatedly (something that loop() will do for you). The static keyword indicates that the variables will be remembered between successive calls of the function.
Typical use
void loop()
{
if(myDelay(1000) == true)
{
digitalWrite(LED_BUILTIN, !digitalread(LED_BUILTIN));
}
}
The above will blink the builtin LED. Note that you can not use this function multiple times. E.g.
void loop()
{
if(myDelay(1000) == true)
{
digitalWrite(LED_BUILTIN, !digitalread(LED_BUILTIN));
}
if(myDelay(10000) == true)
{
Serial.println(F("It's time"));
}
}
The two calls will interfere with each other because the shortest 'delay' in loop() will reset the inProgress flag.
Therefore it will be far better to write dedicated functions for that. Use the myDelay approach to blink a LED would look like
/*
non-blocking blink
In:
delay duration
*/
bool blink(uint32_t duration)
{
static uint32_t startTime;
static bool inProgress = false;
// if delay not started yet
if(inProgress == false)
{
// switch the LED on
digitalWrite(LED_BUILTIN, HIGH);
// remember the start time
startTime = millis();
// indicate that delay is in progress
inProgress = true;
}
// if delay is in progress
else
{
// check if time has lapsed
if(millis() - startTime >= duration)
{
// switch the LED off
digitalWrite(LED_BUILTIN, LOW);
// indicate that the delay has finished
inProgress = false;
// tell caller that delay is finished
return true;
}
}
// tell caller that delay is still in progress
return false;
}
and to print the millis every 10 seconds
/*
non-blocking print time
In:
delay duration
*/
bool printTime(uint32_t duration)
{
static uint32_t startTime;
static bool inProgress = false;
// if delay not started yet
if(inProgress == false)
{
// switch the LED on
Serial.println(millis());
// remember the start time
startTime = millis();
// indicate that delay is in progress
inProgress = true;
}
// if delay is in progress
else
{
// check if time has lapsed
if(millis() - startTime >= duration)
{
// indicate that the delay has finished
inProgress = false;
// tell caller that delay is finished
return true;
}
}
// tell caller that delay is still in progress
return false;
}
Each of these functions has now its own timing. The functions still return a bool to indicate when they are finished but you don't have to use it.
And in loop()
void loop()
{
blink(1000);
printTime(10000);
}
So for each functionality in your code, you write a function that maintains its own timing.
PS
Code not compiled.