Using timers in a class

19 visualizaciones (últimos 30 días)
Brandon du Toit
Brandon du Toit el 22 de En. de 2020
Respondida: Guillaume el 22 de En. de 2020
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.

Respuesta aceptada

Guillaume
Guillaume el 22 de En. de 2020
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.

Más respuestas (0)

Categorías

Más información sobre Startup and Shutdown en Help Center y File Exchange.

Etiquetas

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by