Timer on function, with variable output?
12 views (last 30 days)
Show older comments
I have a main program that starts a timer function. This function is supposed to take in two variables, 'TASK' (a structre), and 'a' (a logical), and then OUTPUT 'TASK' again (after being modified by the function). The main program also alters TASK variable. My issue is the function seems to not recieve updated TASK.
I cannot figure out how to output TASK from the function to the main program. Currently, it does not recieved updated TASK (from the main program) with each timer period.
How do you get output from a timer function, and send it to the workspace of the main program, without using a global variable?
Any why is my timer not recieved updated TASK fromthe main program? OR MUST you use TASK as a global for this situation?
I once had it working with TASK as a global variable, but now I want not use global, as it is a cheater way of coding.
Function called by main program:
function [TASK] =displayCurrent(TASK,a) %TASK = input
clf(f1)
if a == false
return; %If program has ended, stop updating the Display
end
%TASK is modified-->
TASK=TASK %simplified
end
MAIN PROGRAM that calls the timer:
%% TASK INITIALIZATION
%______________Fields (Task Structure Columns)
FIELD_NAMES = {'Greg_date', 'date', 'date_str', 'datetime', 'HH', 'MM', 'title', 'name', 'hh_mm_ss', 'dur_ss', 'dur_mm',...
'manHr', 'grpTsk_members', 'currentGrpSize', 'ID1', 'ID2', 'ID3', 'ID4', 'ID5', 'ID6', 'ID7', 'ID8', 'ID9', 'ID10', 'Unperformed',...
'ID1tic', 'ID2tic', 'ID3tic', 'ID4tic', 'ID5tic', 'ID6tic', 'ID7tic', 'ID8tic', 'ID9tic', 'ID10tic'}; % Cell with field names
empty_cells = repmat(cell(1),1,numel(FIELD_NAMES));
fwecb = {FIELD_NAMES{:} ; empty_cells{:}}; %field w/ empty cells belw
%______________Task Vectors Initialization
TASK = struct(fwecb{:});
%% CALL TIMER
f1=figure('units','normalized','outerposition',[0 0 1 1]);
set(f1,'CloseRequestFcn', ''); %Set figure to do nothing ('') when exiting (prevents error)
set(f1, 'PaperPositionMode', 'auto') %allows figure to be saved correctly (what does this do again?)
set(findall(gcf,'-property','FontSize'),'FontSize',14);
t=timer; t.StartDelay = 1; t.ExecutionMode = 'fixedRate'; t.Period=3;
t.TimerFcn = @(~,~)displayCurrent(TASK,a); %Specified the displayCurrent as the desired timer function (what executes every 5 sec)
%The above timer successfully accepts TASK, and a, and timer repeately runs the fucntion...
%...but does not recieve the updated TASK w/ repeating timer..
%What I really want from the timer is output from the timer function,
%But I know this is incorrect format..but how do you do this?
t.TimerFcn = @(~,~) [TASK]=displayCurrent(TASK,a);
%% Rest of program manipulates TASK while a =true
while a==1
%manipulate TASK!!
end
Accepted Answer
Steven Lord
on 7 May 2020
The TimerFcn for a timer cannot return an output. In which workspace would that output argument be stored? There's no guarantee that the function call in which the timer was created and/or started is still executing at the time the TimerFcn runs!
But that's not the cause of the problem "My issue is the function seems to not recieve updated TASK."
You define your TimerFcn as an anonymous function. As stated in the "Variables in the Expression" section on this documentation page because the TASK variable appears in the expression used to create the anonymous function and is available when the anonymous function is created, the anonymous function "remembers" it and to change the remembered copy you would have to recreate the anonymous function. Changes to TASK after that time do not change the TASK in the anonymous function.
So how can you ask the TimerFcn to change TASK in a way that other functions can use it and so that it can use an updated TASK? Global variables is one way, but using globals is discouraged. Another approach is to put the TASK variable somewhere other than in the anonymous function but somewhere the anonymous function (or the function the anonymous function calls) can access it.
The timer object has a property named UserData and the timer object is passed into the TimerFcn, so you could store it there. As long as your "main function" has access to the timer object it and the TimerFcn could "communicate" via the UserData property. Alternately, since I'm guessing your main function is going to use information from TASK to modify the figure object you could store it in the figure object's UserData property and pass the handle to the figure into the TimerFcn. That would mean the TimerFcn would "remember" the figure handle and you couldn't have it operate on a different figure, but you can change the properties of the figure and access them via the "remembered" figure handle.
0 Comments
More Answers (0)
See Also
Categories
Find more on Startup and Shutdown in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!