Using timers in a class

19 ビュー (過去 30 日間)
Brandon du Toit
Brandon du Toit 2020 年 1 月 22 日
回答済み: Guillaume 2020 年 1 月 22 日
Hi all, I have the code below that is a simple 2 second timer that clears a flag to allow the program to exit the while loop and it works fine.
waitFlag = 1;
num = 0;
t = timer('TimerFcn', 'waitFlag=0;',...
'StartDelay', 2, ...
'ExecutionMode', 'singleShot');
start(t);
while (waitFlag) && (num == 0)
end
disp('Timer works');
Take that same concept and put it inside a class function and it doesn't work.
function ret = waitForSerial(obj)
waitFlag = 1;
t = timer('TimerFcn', 'waitFlag=0;',...
'StartDelay', 2, 'ExecutionMode', 'singleShot');
start(t);
% Wait for response to come in
% waitFlag becomes 0 when timer expires
% While is broken if timer expires or if serial data comes in
while (waitFlag) && (obj.comPort.NumBytesAvailable == 0)
end
disp("Done waiting");
if obj.comPort.NumBytesAvailable > 0
stop(t);
ret = obj.interpretMsg();
else
stop(t);
commsErr(obj, "COMs timeout");
ret = -2;
return
end
delete(t);
end
What happens is I guess the timer doesn't start, it doesn't trigger or it doesn't clear the waitFlag because the program never exits the while loop. If there is some special behaviour regarding timers/callbacks within classes, any help would be greatly appreciated.

採用された回答

Guillaume
Guillaume 2020 年 1 月 22 日
The problem is most likely one of scope.I'm actually surprised that you first version works, but I never use the char array version of the TimerFcn. The documentation doesn't specify in which context that char expression is evaluated (I'll be raising a bug report for that), but it looks like it's in the base workspace. So your original code would only work in a script. In a function or class method, which have their own workspace, the timer wouldn't affect the local variable.
The best way to fix your problem is, assuming a handle class to:
a) make waitFlag a property of the class
classdef yourclass
properties (Access = private)
waitFlag
end
end
b) create a member function to handle the timer event
methods
function TimerCallback(this)
this.waitFlag = true;
end
c) use that callback as a timer function:
function ret = waitForSerial(this)
this.waitFlag = false;
t = timer('TimerFcn', @(~, ~) this.TimerCallback, ...
'StartDelay', 2, 'ExecutionMode', 'singleShot');
start(t);
while (this.waitFlag) && (this.comPort.NumBytesAvailable == 0)
end
%...
end
However, if the whole purpose of your timer is to wait a limited amount of time for some serial data, you may be better off with just attempting a read with a timeout. Overall it would be simpler and achieve the same result.

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeStartup and Shutdown についてさらに検索

タグ

製品

Community Treasure Hunt

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

Start Hunting!

Translated by