MATLAB Answers

How to set timer queue to zero

6 views (last 30 days)
Florian
Florian on 13 Mar 2020
Commented: Florian on 13 Mar 2020
Hi all,
I have a program which extensively uses timers to periodically execute tasks. timer spacing is 1s and BusyMode='drop'. Most of the time my call back runs less than one second, but once in a while it takes longer.
I do not want any event to be put in the event queue in case that happens, but rather stick to the 1s intervals all the time if possible. The default queue for 'drop' is 1. Hence: how can I set the queue size to zero so the execution is dropped if my callback takes longer than the timer spacing?
Thanks in advance for your help,
Florian

  0 Comments

Sign in to comment.

Accepted Answer

Geoff Hayes
Geoff Hayes on 13 Mar 2020
Florian - I'm not sure if you can set the queue size to be zero (the documenation doesn't suggest that this is possible). An alternative (though not necessarily practical) approach could be to create a single shot timer that you fire when you complete your callback "work". So if the work takes longer than a second, then you immediately (0 delay) start the timer to do the next iteration. If the work takes less than a second, then you start the timer with a non-zero delay (the difference between 1 and the duration of the work). For example,
function SingleShotTimerTest
k = 1;
timerCallbackStart = 0;
cumulativeTimerCallbackStart = tic;
myTimer = timer('Name','MyTimer', ...
'StartDelay', 1, ...
'ExecutionMode','singleShot', ...
'TimerFcn',{@timerCallback}, ...
'StopFcn', {@stopCallback});
start(myTimer);
function timerCallback(hObject, eventdata)
timerCallbackStart = tic;
timeToPause = rand;
fprintf('timerCallback called at %.3f seconds (pause of %.3f seconds).\n', toc(cumulativeTimerCallbackStart), timeToPause);
pause(timeToPause);
end
function stopCallback(hObject, eventdata)
timeElapsedSeconds = toc(timerCallbackStart);
delaySeconds = 0;
if timeElapsedSeconds < 1
% casting and multiplication and division to avoid warnings
% with StartDelay precision
delaySeconds = double(int32(1000*max(1 - timeElapsedSeconds, 0.001)))/1000;
end
% stop timer after 10 iterations
if k < 10
k = k + 1;
set(myTimer, 'StartDelay', delaySeconds);
start(myTimer);
end
end
end
The above code creates a single-shot timer that fires after one second. The timerCallback fires and pauses for a random (0-1) amount of time. The stop callback then determines the elapsed time (between calls to the stopCallback and the timerCallback) and if that elapsed time is less than one, then the timer is restarted with a delay. If the elapsed time is greater than or equal to one, then timer starts immediately (0 second delay).
I don't know if this will help or it might introduce an overall delay that gets worse the longer the timer runs.

  1 Comment

Florian
Florian on 13 Mar 2020
Hi Goeff,
thanks for your answer. Very creative! I'll give it a try.
Best,
Florian

Sign in to comment.

More Answers (0)

Sign in to answer this question.