是否可以更改重复计时器的周期(在TimerFcn中)?
直观地说,在为Windows编程时,我会处理WM_TIMER消息并使用SetTimer来编辑定时器的周期,但类似的方法在MATLAB中似乎不起作用,因为需要重新启动计时器才能更改期间属性。这会扰乱执行,最好将其描述为将周期更改为接近零。不会产生任何错误。
以下是用于创建任务数组的一些示例代码:每个任务项包含要执行的操作和延迟。该数组基本上由计时器走过,计时器应根据当前任务延迟更改其周期。
function obj = Scheduler(~)
obj.scheduletimer = timer(...
'TimerFcn',@obj.OnTimer,...
'BusyMode','queue',...
'TasksToExecute',length(obj.tasklist),...
'ExecutionMode','fixedRate');
end
function OnTimer(obj,source,event)
obj.Start(); // Executed task, schedule next
end
function Start(obj)
// Stop timer if needed
if(strcmp(obj.scheduletimer.Running,'on'))
stop(obj.scheduletimer);
end;
// Set new period and resume
if(~isempty(obj.tasklist))
obj.scheduletimer.Period = obj.tasklist(1).something;
start(obj.scheduletimer);
end;
end
当我在OnTimer中没有弄乱计时器时,一切显然都能正常工作,但我想在每次迭代时更改句点。
编辑:我试图实现Pursuit建议的乒乓解决方案,但它仍然无效。请注意,切换计时器的想法确实有效,但似乎还没有应用周期。
function obj = Scheduler(~)
obj.timer1 = timer(...
'TimerFcn',@obj.OnTimer);
obj.timer2 = timer(...
'TimerFcn',@obj.OnTimer);
end
function OnTimer(obj,source,event)
obj.Start(); // Executed task, schedule next
end
function Start(obj)
if(strcmp(obj.timer1.Running,'on'))
obj.timer2.Period = obj.tasklist{1}{2};
start(obj.timer2);
else
obj.timer1.Period = obj.tasklist{1}{2};
start(obj.timer1);
end;
end
呃。
答案 0 :(得分:3)
使用两个计时器(例如timerNamePing
和timerNamePong
)。在每个定时器设置动作结束时,下一个定时器在单次模式下执行一次并有一些延迟。
这避免了不断拆卸和创建新计时器的需要,并避免了当您尝试编辑当前正在执行的计时器时发生的错误。
这是一个展示的工作示例:
function setupPingPong
timerPing = timer;
timerPong = timer;
timerPing.TimerFcn = @(~,~)pingPongActivity(true, timerPing, timerPong);
timerPing.Name = 'PingTimer';
timerPong.TimerFcn = @(~,~)pingPongActivity(false, timerPing, timerPong);
timerPong.Name = 'PongTimer';
timerPing.StartDelay = 0;
start(timerPing);
function pingPongActivity(isPing, timerPing, timerPong)
if isPing
disp(['PING (' datestr(now,'yyyy-mm-dd HH:MM:SS.FFF') ')'])
else
disp(['PONG (' datestr(now,'yyyy-mm-dd HH:MM:SS.FFF') ')'])
end
delayTime = ceil(rand*10);
display([' delaying ' num2str(delayTime) ' sec.'])
if isPing
nextTimer = timerPong;
else
nextTimer = timerPing;
end
set(nextTimer,'StartDelay', delayTime);
start(nextTimer);
一旦这样,为了阻止疯狂,我使用:
t = timerfind; stop(t); delete(t)
答案 1 :(得分:0)
我使用' StopFcn' timer对象中的属性再次重启计数器。
这样的事情(' TimerScale'改变下一个时期)
init:
Timer_OBJ = timer( 'ExecutionMode', 'singleShot', ...
'StartDelay', SystemTicksSecs/TimerScale, ...
'TimerFcn', @(src,evt)obj.TimerCallBack,...
'StopFcn', @(src,evt)obj.TimerStopCallBack );
start(Timer_OBJ);
和TimerStopCallBack内部
set(Timer_OBJ, 'StartDelay', SystemTicksSecs/TimerScale);
start(Timer_OBJ);