Is it possible to pause a timer without calling its StopFcn?

11 次查看(过去 30 天)
I have a timer with a TimerFcn and a StopFcn defined.
Within the TimerFcn I would like to pause the timer itself since I will call another function from it and I would like it to finalize before I start the timer again. This other function will start another timer that will iterate a function several times before it finalizes with starting the paused timer.
The only way I have found to pause a timer is to use "stop" but this will directly call the StopFcn.
function TestFunction1(vector)
TestTimer1 = timer('ExecutionMode', 'fixedSpacing',...
'Period', PeriodTime1,...
'TasksToExecute', length(Vector)-1,...
'TimerFcn', @(~, ~) TestLoop1(),...
'StopFcn', @(~,~) EndTestLoop1());
start(TestTimer)
function TestLoop1()
stop(TestTimer1) %Here is the problem since it calls the StopFcn.
Value = 'some calculations'
TestFunction2(Value)
end
function EndTestLoop1(Value)
GoHome()
end
end
function TestFunction2(Value)
TestTimer2 = timer('ExecutionMode', 'fixedRate',...
'Period', PeriodTime2,...
'TasksToExecute', 500,...
'TimerFcn', @(~, ~) TestLoop2(),...
'StopFcn', @(~,~) EndTestLoop2());
start(TestTimer)
function TestLoop2()
"Do something"
end
function EndTestLoop2(Value)
start(TestTimer1)
end
end
Is there a way to pause the timer without triggering the StopFcn or do I have to remove the StopFcn and handle this in code insted?
  4 个评论
dpb
dpb 2024-9-3
编辑:dpb 2024-9-3
That doesn't make sense -- if the arm is to stay at each position for a fixed time, then the move function needs to be triggered when it times out. If it pauses its count and picks up from that point after the move, then the time at a position will drag out for however long the move actually takes plus the set time; not including the movement time.
If the intent is to move to a new position and then wait at that position until the fixed time has elapsed, what your logic should do is have the "moveComplete" condition restart the wait timer which would be a one-shot reinitialized each time instead of continuous.
The other case would be to have the arm at a specific location at a fixed equally-spaced time interval in which case it would be to move, calculate how long the next move will take and then start the delay time to wait until time to leave to arrive at the next point on time.
Neither of those seem to match up with the continuous timer structure nor would they require pausing a given timer and resuming its count.
Either scenario does require that the time between positions be no more than the wait time, however; if it is not possible to accomplish the move quickly enough, then the conditions simply can't be met and we have a realtime failure condition. Now, what is supposed to happen then isn't defined.
Quist
Quist 2024-9-3
As said, the question was really about pausing a timer and not about my very limited MATLAB skills. :)
But anyway, when the wait timer triggers it is stopped by its own TimerFcn just before the movement timer is started. The movement timer executes the movement (thousands of micro moves) and, as a last thing starts the wait timer again. My assumption is that the timer starts from the value it stoped at, so if 10% of the timer time had elapsed before the stop 90% is left when it is started again. If so the wait time should be correct since the timer is only paused during the actual movement.
If the assumption of the continuation of the timer is not correct I will get a small time error. It's not that critical to me since the waittime is many seconds and the tasks that are performed beween timer trig and timer stop takes only some ms.

请先登录,再进行评论。

回答(1 个)

Ayush
Ayush 2024-9-3
编辑:Ayush 2024-9-3
Hi @Quist,
There are several methods to achieve the functionality of stopping the timer without triggering the stopFcn function.
Method-1: Set the BusyMode property of the timer to drop. This configuration will ignore the event in the case of multiple executions. You can read more about it in the documentation: https://www.mathworks.com/help/matlab/matlab_prog/handling-timer-queuing-conflicts.html
Method-2: you can use a Boolean variable to decide whether to execute “stopFcn” function, depending on whether we need to stop the timer or pause the timer.
I have modified your functions to achieve “timer pause” functionality using the method explained above.
Here’s the modified code:
function TestFunction1(vector)
TestTimer1 = timer('ExecutionMode', 'fixedSpacing', ...
'Period', PeriodTime1, ...
'TasksToExecute', length(vector) - 1, ...
'TimerFcn', @(~, ~) TestLoop1(), ...
'StopFcn', @(~, ~) EndTestLoop1());
% Define a flag to control whether the timer should be paused or not
% using “userData” for storing “pause” within the timer object
TestTimer1.userData = struct("pause",false);
start(TestTimer1);
function TestLoop1()
% making the timer in "pause" state
TestTimer1.UserData.pause= true;
Value = 'some calculations';
TestFunction2(Value);
end
function EndTestLoop1()
if TestTimer1.UserData.pause == false
GoHome();
end
end
end
function TestFunction2(Value)
TestTimer2 = timer('ExecutionMode', 'fixedRate', ...
'Period', PeriodTime2, ...
'TasksToExecute', 500, ...
'TimerFcn', @(~, ~) TestLoop2(), ...
'StopFcn', @(~, ~) EndTestLoop2());
start(TestTimer2);
function TestLoop2()
% "Do something"
end
function EndTestLoop2()
% no need to start the timer1 again
% start(TestTimer1);
end
end
For more information, you can refer to the following documentation on “timer” function: https://www.mathworks.com/help/matlab/ref/timer.html
Hope it helps!
  3 个评论
Quist
Quist 2024-9-3
I just realized a problem with this approach.
stop(timer) resets Timer.TasksExecuted so it will be 1 in every iteration of the TimerFcn and in this way it is not a fully substitute to pause a timer.
I'd guess that it also means that Timer.TasksToExecute never will be reached?
Ayush
Ayush 2024-9-4
Hi @Quist, The issue you're encountering can be effectively addressed by leveraging a flag within the TestLoop1 function to control execution flow.
For instance, consider a timer object "t1" with "t1.TasksToExecute" = 4, meaning that the "TimerFcn" will execute four times. To implement a pause mechanism, you can prevent the "TimerFcn" from running during certain iterations while adjusting the total number of iterations accordingly. Specifically, you would increment "t1.TasksToExecute" by 1 to account for the postponed execution.
Here's a step-by-step approach:
  1. Pause Implementation: If a pause is required, simply skip executing the "TimerFcn" during that iteration. Simultaneously, increase the "t1.TasksToExecute" property by 1 to maintain the correct number of iterations for the timer.
  2. Resume and End Execution: When the pause is lifted or when the timer needs to end, use the flag to control whether to execute the postponed code.
This approach effectively delays the "TimerFcn" execution rather than stopping the timer, ensuring that "t1.TasksToExecute" reflects the correct number of remaining tasks.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Programming Utilities 的更多信息

产品


版本

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by