I’ve been trying to build some code that makes good use of the Simple Timer Library. Things seem to work as expceted with all the timer functions until I try to use the .setTimeout one. I’ve been calling
int numTimers = timer.getNumTimers();
at the bottom and the more i run .setTimeout timers, the more timer counts I get. Isn’t .setTimeout suppose to run once and than be deleted? So I went digging through the BlynkLibrary I’m currently using and I find this down on lines 181-188:
int SimpleTimer::setTimeout(unsigned long d, timer_callback f) {
return setupTimer(d, (void *)f, NULL, false, RUN_ONCE);
}
int SimpleTimer::setTimeout(unsigned long d, timer_callback_p f, void* p) {
return setupTimer(d, (void *)f, p, true, RUN_ONCE);
}
Ok… Where am I missing it here. where does the RUN_ONCE magic happen here in the run loop??
void SimpleTimer::run() {
int i;
unsigned long current_millis;
// get current time
current_millis = elapsed();
for (i = 0; i < MAX_TIMERS; i++) {
timer[i].toBeCalled = DEFCALL_DONTRUN;
// no callback == no timer, i.e. jump over empty slots
if (timer[i].callback != NULL) {
// is it time to process this timer ?
// see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
if ((current_millis - timer[i].prev_millis) >= timer[i].delay) {
unsigned long skipTimes = (current_millis - timer[i].prev_millis) / timer[i].delay;
// update time
timer[i].prev_millis += timer[i].delay * skipTimes;
// check if the timer callback has to be executed
if (timer[i].enabled) {
// "run forever" timers must always be executed
if (timer[i].maxNumRuns == RUN_FOREVER) {
timer[i].toBeCalled = DEFCALL_RUNONLY;
}
// other timers get executed the specified number of times
else if (timer[i].numRuns < timer[i].maxNumRuns) {
timer[i].toBeCalled = DEFCALL_RUNONLY;
timer[i].numRuns++;
// after the last run, delete the timer
if (timer[i].numRuns >= timer[i].maxNumRuns) {
timer[i].toBeCalled = DEFCALL_RUNANDDEL;
}
}
}
}
}
}
for (i = 0; i < MAX_TIMERS; i++) {
if (timer[i].toBeCalled == DEFCALL_DONTRUN)
continue;
if (timer[i].hasParam)
(*(timer_callback_p)timer[i].callback)(timer[i].param);
else
(*(timer_callback)timer[i].callback)();
if (timer[i].toBeCalled == DEFCALL_RUNANDDEL)
deleteTimer(i);
}
}
So it looks like there’s 3 types of timers: setTimer(Run_n times), setInterval(Run_Forever) and SetTimeout(Run_Once). Now I can see how the run forever and the run n times one’s work, but can someone show me how the Run_Once ones are handled and why they don’t seem to be deleting in my code after they’ve ran?
@Gunner 's helpful post and the snippet of code I’ve been puzzling over for awhile already:
// "Sacrificial" Timer - Seems to be needed when deleting timers as that will kill first timer created...
redblueLEDtimer = timer.setTimeout(10L, []() {
// Do nothing
}); // END sacrificial Function
}