Stopping and restarting a timer within its own callback - why does it then run the callback twice at a time, but only with fixedSpacing?

9 次查看(过去 30 天)
I want to start and stop a timer within the timer callback function*. I do this with code like the following script:
global timerRunCount
timerRunCount = 0;
% Try changing "fixedDelay" to "fixedSpacing".
timerObj = timer(ExecutionMode="fixedDelay", Period=1, StartDelay=1, TimerFcn=@timerFunction);
timerObj.start;
function timerFunction(tmr, ~)
global timerRunCount
timerRunCount = timerRunCount + 1;
if isnan(tmr.InstantPeriod)
disp("Iteration: " + timerRunCount + "; interval: N/A")
else
disp("Iteration: " + timerRunCount + "; interval: " + tmr.InstantPeriod)
end
switch timerRunCount
case 5
tmr.stop
tmr.start
case 10
tmr.stop
tmr.start
case 15
tmr.stop
tmr.delete
end
end
Result:
% Iteration: 1; interval: N/A
% Iteration: 2; interval: 1.001
% Iteration: 3; interval: 1.001
% Iteration: 4; interval: 1.001
% Iteration: 5; interval: 1.001
% Iteration: 6; interval: N/A
% Iteration: 7; interval: 1.002
% Iteration: 8; interval: 1.001
% Iteration: 9; interval: 1.001
% Iteration: 10; interval: 1.001
% Iteration: 11; interval: N/A
% Iteration: 12; interval: 1.001
% Iteration: 13; interval: 1.001
% Iteration: 14; interval: 1
% Iteration: 15; interval: 1.001
We see that it happily runs timerFunction() about every second. (I know that global variables are poor practice; it's just to keep this example simple).
Now see what happens when we change ExecutionMode to "fixedSpacing":
% Iteration: 1; interval: N/A
% Iteration: 2; interval: 1.046
% Iteration: 3; interval: 1.002
% Iteration: 4; interval: 1.002
% Iteration: 5; interval: 1.003
% Iteration: 6; interval: N/A
% Iteration: 7; interval: 0.004
% Iteration: 8; interval: 1
% Iteration: 9; interval: 0.003
% Iteration: 10; interval: 0.999
% Iteration: 11; interval: N/A
% Iteration: 12; interval: 0.001
% Iteration: 13; interval: 1.001
% Iteration: 14; interval: 0.002
% Iteration: 15; interval: 1.001
The first five iterations work as expected; but after we first start and stop the timer, it runs timerFunction() twice every time the timer triggers. We see this from the intervals alternating between ~1s and a few ms. In the third section, I have sometimes seen the timerFunction() run three times for every timer trigger (depending on how long the second stage runs for).
Can anyone please explain why a change to ExecutionMode causes this issue? By my understanding of the Matlab help, this should only change whether or not the duration of timerFunction() is included in the timer period. I don't actually need this issue fixed (the exact period of my timer isn't important), but I want to understand any strange subtleties of the timer object before basing my application on it.
* The reason is that I want to repeatedly run a function with a timer (checking a shared memory location for changes) and when it detects changes, switch to a different polling function, and when *that* detects changes, switch to yet another different polling function, etc. You have to stop a timer before you can change the period, and then restart it.
  3 个评论
raym
raym 2023-2-18
https://www.mathworks.com/matlabcentral/answers/1914920-stop-and-re-start-timer-inside-timerfcn-cause-pseudo-multiple-parallel-duplicated-timer-in-fact-onl

请先登录,再进行评论。

回答(1 个)

Sugandhi
Sugandhi 2023-2-15
Hi David,
I work at MathWorks, and the relevant people are aware of the issue.
Regards,
Sugandhi.
  2 个评论
David Szwer
David Szwer 2023-2-15
That's good to know, thank you.
(I won't "Accept" this answer, until I hear about a workaround or a fix, but it's still very helpful).
raym
raym 2023-2-18
  1. I eucountered the same problem today:
  2. https://www.mathworks.com/matlabcentral/answers/1914920-stop-and-re-start-timer-inside-timerfcn-cause-pseudo-multiple-parallel-duplicated-timer-in-fact-onl

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Startup and Shutdown 的更多信息

产品


版本

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by