3

(TimerFcn で) 繰り返しタイマーの期間を変更することは可能ですか?

直感的に、Windows 用のプログラミングでは、WM_TIMER メッセージを処理し、SetTimer を使用してタイマーの期間を編集しますが、同様のアプローチは MATLAB では機能しないようです。Period プロパティを変更するにはタイマーを再起動する必要があるためです。 . これは実行を混乱させます。これは、周期をほぼゼロに変更することと最もよく説明できます。エラーは発生しません。

タスク配列を作成するために使用されるコードの例を次に示します。各タスク項目は、実行することと遅延で構成されます。配列は基本的にタイマーによってウォークされ、現在のタスクの遅延に基づいて Period を変更する必要があります。

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

うーん。

4

2 に答える 2

3

2つのタイマー(例timerNamePingtimerNamePong)を使用します。各タイマーのアクションの最後に、次のタイマーを設定して、シングルショットモードで1回実行します。

これにより、常に破棄して新しいタイマーを作成する必要がなくなり、現在実行中のタイマーを編集しようとしたときに発生するエラーが回避されます。

これは、実例を示すための実用的な例です。

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)
于 2013-03-22T19:04:15.677 に答える
1

タイマー オブジェクトの '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);
于 2016-05-31T06:44:15.263 に答える