How to set timer queue to zero

3 visualizaciones (últimos 30 días)
Florian
Florian el 13 de Mzo. de 2020
Comentada: Florian el 13 de Mzo. de 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

Respuesta aceptada

Geoff Hayes
Geoff Hayes el 13 de Mzo. de 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 comentario
Florian
Florian el 13 de Mzo. de 2020
Hi Goeff,
thanks for your answer. Very creative! I'll give it a try.
Best,
Florian

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by