return value from timer callback function

30 views (last 30 days)
I want to update a matrix on each call of the timer function in a timer object. I read in the news group that the return variable should be assigned in the base MatLab workspace. So even after that I get a strange result. Here is the code:
% define constants
total_time = 12;
swap_count = 3;
swap_period = floor(total_time/swap_count);
% assign output variable from callback function
assignin('base','X','AB');
% crete a timer object and set properties
t_obj = timer;
set(t_obj, 'StartDelay', swap_period);
set(t_obj, 'Period', swap_period);
set(t_obj, 'TasksToExecute', swap_count);
set(t_obj, 'ExecutionMode', 'fixedRate');
set(t_obj, 'UserData', 'X');
set(t_obj, 'StartFcn',{@swap_fcn, X});
set(t_obj, 'TimerFcn',{@swap_fcn, X});
set(t_obj, 'StopFcn',{@swap_fcn, X});
% start timer loop
start(t_obj);
pause(total_time+1);
stop(t_obj);
delete(t_obj);
% callback function
function [X] = swap_fcn(obj, event, X)
% event properties
event_type = event.Type;
event_time = datestr(event.Data.time,'HH:MM:SS, dd mmm YYYY');
% get times executed
exec_count = get(obj, 'TasksExecuted');
% write step and write to file
switch event_type
case 'StartFcn'
fprintf('start experiment: %s\n',event_time);
disp(X);
case 'TimerFcn'
fprintf('swap%02d: %s\n',exec_count, event_time);
X = fliplr(X);
disp(X);
case 'StopFcn'
fprintf('stop experiment: %s\n',event_time);
disp(X);
end
end
so after running that i got the following result
start experiment: 13:53:18, 19 Sep 2013
AB
swap01: 13:53:22, 19 Sep 2013
BA
swap02: 13:53:26, 19 Sep 2013
BA
swap03: 13:53:30, 19 Sep 2013
BA
stop experiment: 13:53:30, 19 Sep 2013
AB
I would expect something like that:
start experiment: 13:53:18, 19 Sep 2013
AB
swap01: 13:53:22, 19 Sep 2013
BA
swap02: 13:53:26, 19 Sep 2013
AB
swap03: 13:53:30, 19 Sep 2013
BA
stop experiment: 13:53:30, 19 Sep 2013
BA
It seems like I never return the updated version of X in the next TimerFcn call.

Accepted Answer

go9kata
go9kata on 19 Sep 2013
I found the answer, one should use the timer object UserData property to handle input output in timer: here is the change in the code:
% define constants
total_time = 12;
swap_count = 3;
swap_period = floor(total_time/swap_count);
% assign output variable from callback function
X = 'AB';
% crete a timer object and set properties
t_obj = timer;
set(t_obj, 'StartDelay', swap_period);
set(t_obj, 'Period', swap_period);
set(t_obj, 'TasksToExecute', swap_count);
set(t_obj, 'ExecutionMode', 'fixedRate');
set(t_obj, 'UserData', X);
set(t_obj, 'StartFcn',{@swap_fcn});
set(t_obj, 'TimerFcn',{@swap_fcn});
set(t_obj, 'StopFcn',{@swap_fcn});
% start timer loop
start(t_obj);
pause(total_time+1);
stop(t_obj);
delete(t_obj);
% callback function
function [X] = swap_fcn(obj, event)
% event properties
event_type = event.Type;
event_time = datestr(event.Data.time,'HH:MM:SS, dd mmm YYYY');
% get times executed
exec_count = get(obj, 'TasksExecuted');
% get current user data
X = get(obj, 'UserData');
% write step and write to file
switch event_type
case 'StartFcn'
fprintf('start experiment: %s\n',event_time);
disp(X);
case 'TimerFcn'
fprintf('swap%02d: %s\n',exec_count, event_time);
X = fliplr(X);
disp(X);
case 'StopFcn'
fprintf('stop experiment: %s\n',event_time);
disp(X);
end
% update any changes
set(obj,'UserData',X);
end
  2 Comments
Gilles Desvilles
Gilles Desvilles on 28 May 2019
Edited: Gilles Desvilles on 29 May 2019
Useful because mathworks help is such a big bang spash of incomplete docs, you need to go fishing all over the net to fill in the puzzle
Help is their fifth wheel of the cart, but that's a big marketing mistake
Why putting swap_fcn into { } ? I have tested without { }, seems to work alright.
Same with [X] = swap_fcn, I have taken out [X] = and it works fine.
Another point: I had to store swap_fcn in a .m file as an external function.
Walter Roberson
Walter Roberson on 24 Nov 2021
The initial code had calls such as
set(t_obj, 'StartFcn',{@swap_fcn, X});
which is perfectly valid code, and means that swap_fcn will be called with the two default arguments and that X will also be passed to swap_fcn .
This syntax is equivalent to
set(t_obj, 'StartFcn', @(hObject,event)swap_fcn(hObject,event,X));
but the syntax was created before anonymous functions existed in MATLAB.
Calling
set(t_obj, 'StartFcn',{@swap_fcn});
Is thus not an error: it just means that all zero extra arguments will be passed -- so it is the same as
set(t_obj, 'StartFcn',@swap_fcn);
So it is not wrong, just not common these days.
With respect to the [X] = -- there are a small number of callback functions that can return values, such as some kind of position constraint functions for ROIs and some kind of zoom or pan constraint functions for axes. Most callback functions cannot return (meaningful) values. There is a lot of confusion over this aspect of callback functions.
In the case of the callback functions used in this code: you are correct that they should not return any value.

Sign in to comment.

More Answers (0)

Categories

Find more on Entering Commands 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!