Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 改变重复定时器周期_Matlab_Timer - Fatal编程技术网

Matlab 改变重复定时器周期

Matlab 改变重复定时器周期,matlab,timer,Matlab,Timer,是否可以更改重复计时器的周期(在TimerFcn中)? 直观地说,在为Windows编程时,我会处理WM_定时器消息并使用SetTimer编辑定时器的周期,但类似的方法在MATLAB中似乎不起作用,因为需要重新启动定时器才能更改周期属性。这会扰乱执行,最好将周期更改为接近零。不会产生任何错误 下面是一些用于创建任务数组的示例代码:每个任务项都包含一些要做的事情和一个延迟。数组基本上是由一个计时器遍历的,它应该根据当前任务延迟更改其周期 function obj = Scheduler(~)

是否可以更改重复计时器的周期(在TimerFcn中)?

直观地说,在为Windows编程时,我会处理WM_定时器消息并使用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
呃。

使用两个计时器(例如
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)

我再次在timer对象中使用“StopFcn”属性来重新启动计数器

类似于此(“TimerScale”会在下一个时段发生变化)

初始化:

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);

您收到了什么错误?@wakjah:请看编辑后的问题。我可以重现您的问题,但不知道如何修复。我得到的唯一解决方案是将计时器的模式设置为singleShot,并使用StartDelay属性控制回调触发前的时间。然后,在回调中,停止计时器并删除它,然后创建一个新的计时器并启动它。次优,但由于某些原因,它不想以任何其他方式工作。修复了您的评论。您可能还对Matlab语法的用户脚本感兴趣,因此(请参阅Matlab标记信息的链接)@wakjah:我将放弃并切换到该方法…一种合理的方法,但我认为,由于处理程序的预定到期时间和实际执行时间之间的差异,错误会累积。如果这确实是一个问题,您可以在回调中执行tic/toc,并调整下一个执行计时器的StartDelay,以补偿当前执行计时器的期望时间和实际时间之间的差异(以及任何过去累积的错误)。如果需要绝对时间精度,我将根据当前值
now
计算下一次迭代的偏移量。这将防止错误累积,尽管我仍然不相信它是非常精确的。@追求:精度不是很重要:大约50毫秒的错误不是问题。我已尝试实施您的修复是的,使用乒乓球或定时娱乐(参见wakjah的评论)基本上是因为无法更改运行计时器的周期。这意味着StartDelay是唯一可配置的延迟选项。不过,乒乓球和重新创建似乎同样快,因此我认为更简单的重新创建修复可能更可取。