madhavdivya:
Thank you PaulS, you are right in suggesting "the way we think".
Arduino has a clock that maintains a 32-bit unsigned value as milliseconds since startup.
At any time you can copy that value into an unsigned long variable, it marks the time it was set.
At any later time you may subtract the time mark value from the current millis() value (always increasing 1000 times per second) and get the difference in time.
Always use the later time minus the earlier time. Since they are unsigned, the answer will always be correct even when the time being subtracted is higher value.. it is like a clock, from 11 to 1 is 2 hours.
So you can tell time difference then you can make:
void loop()
{
// some code here -- maybe a button that turns the "timer" on or off by setting timeWait
if ( timeWait ) // this lets the timer be turned off and on by set timeWait to 0 or > 0
{
if ( millis() - timeStart >= timeWait ) // trigger warning! LOL!
{
// do that thing you waited for without delay()!
timeStart += timeWait; // and now set up to do it again.
}
}
// some code here
}
The other code can change the wait, stop or start the timer, and do any without adding indent levels to the timer code itself. The 'reaching in' is done through the variables in those triggering if() statements.
This is a basis to make very responsive code able to do many things together. As long as loop() runs quickly the code will be able to check times and pin states to react quickly.
If you have a process that will take more than 200 microseconds (analog read takes 105, digital read is faster than 1) then see about breaking it into sub-tasks to run 1 per pass through loop(). It will get done soon anyway when loop() is running more than 1000 times a second.
void loop()
{
static byte runSubTask = 0; // it is 0 to start. static local variables keep their value unlike non-static.
// some code
switch ( runSubTask )
{
case 0 :
// code for the first sub-task
runSubTask = 1; // this could have an if() and case 0 would run again until the if() succeeded.
break;
case 1 :
// code for the next sub-task
runSubTask = 2;
break;
case 2 :
// code for the next sub-task
runSubTask = 0;
break;
}
// some code
}
I have put the code for sub-tasks like above inside of a function to get rid of many delay()s.
void myTasks()
{
static byte runSubTask = 0; // it is 0 to start. static local variables keep their value unlike non-static.
if ( timeWait ) // this lets the timer be turned off and on by set timeWait to 0 or > 0
{
if ( millis() - timeStart < timeWait ) // time is NOT up yet
{
return; // so come back later
}
else
{
timeWait = 0; // time is up, turn the timer off
}
}
switch ( runSubTask )
{
case 0 :
// code for the first sub-task
timeStart = millis();
timeWait = 500; // next sub task to run 500 millis after "now"
runSubTask = 1; // this could have an if() and case 0 would run again until the if() succeeded.
break;
case 1 :
// code for the next sub-task
runSubTask = 2;
break;
case 2 :
// code for the next sub-task
runSubTask = 0;
break;
}
}
Time as unsigned long is good for 49.7-some days as the longest countable interval.