How to properly pass handles into TimerFcn? Handles is currently showing up as emtpy

9 vues (au cours des 30 derniers jours)
Hi everyone,
This question is sort-of a follow-up to a previous question.
The problem is that I followed all the suggested steps and I have encountered a new problem. Here is a brief overview of what I am trying to do. I have a program that is reading data from 1 to 10 RFID readers simultaneously via bluetooth. I know that I cannot use simultaneous while loops so I am trying to use separate timers to start and stop data collection from each reader.
I create the timer object in the opening function:
handles.TimerA = timer('ExecutionMode','fixedrate','Period',1,...
'TimerFcn',{@StartReaderA,varargin});
After the GUI opens, a bluetooth connection is initiated with each reader and the user inputs a filename for saving the data. Once the filename is valid, the user can press the Start/Stop toggle button to begin reading/saving from the RFID reader. When the start button is pressed (i.e., when the toggle is down) I execute
start(handles.TimerA);
This begins executing the reading process within the reader function
function StartReaderA(obj,event,handles)
Unfortunately, handles is somehow being lost between the start command and when the function is entered. Obj and event are the timer's information, but handles is appearing as a 0x0 cell. I need information within handles to properly execute StartReaderA.
How do I correctly pass handles to StartReaderA so that I can use the information?
Thank you for your help.
Justin

Réponse acceptée

Geoff Hayes
Geoff Hayes le 21 Oct 2014
Justin - remember that function signature for Opening_Fcn is
function myGui_OpeningFcn(hObject, eventdata, handles, varargin)
and so when you set the TimerA field as
handles.TimerA = timer('ExecutionMode','fixedrate','Period',1,...
'TimerFcn',{@StartReaderA,varargin});
unless varargin is non-empty, then the StartReaderA will have an empty cell for its third input parameter.
And so the next thought might be to pass in handles as
handles.TimerA = timer('ExecutionMode','fixedrate','Period',1,...
'TimerFcn',{@StartReaderA,handles});
which will work and will set the third input of your StartReaderA function as the handles structure BUT it will only be a copy of that structure when the timer was created and so will not have any user-defined data or other fields that may be set by you (or your code) at any later point in the GUI processing.
Usually, what I do when I want my timer function to have access to the handles structure, I pass the handle to the figure, hObject, and use that handle to get the structure. Try the following - in your OpeningFcn, do
handles.output = hObject;
% create the timer and pass hObject as an input to StartReaderA
handles.TimerA = timer('ExecutionMode','fixedrate','Period',1,...
'TimerFcn',{@StartReaderA,hObject});
% your other code
% Update handles structure
guidata(hObject, handles);
Then, in StartReaderA grab the handles structure as
function StartReaderA(obj,event,hFigure)
% since hFigure is the figure handle, use that to get the handles
handles = guidata(hFigure);
% your other stuff
Try the above and see what happens!
  2 commentaires
Justin
Justin le 21 Oct 2014
Hi Geoff,
Thanks so much for your response. That worked!! I have one follow-up question. I am continuously reading, but I only save data if the reader has scanned an RFID card.
function StartReaderA(obj,event,hFigure)
handles = guidata(hFigure);
% Read Tag ID
TagID_ReaderA = fscanf(handles.bt.A)
% Store data if ID is read. Do nothing if read is empty
if length(TagID_ReaderA) > 1
Count_btA = handles.DataCounter.A;
% Store Tag ID
Read_btA{handles.DataCounter.A,1} = TagID_ReaderA;
handles.recording.A{Count_btA,1} = TagID_ReaderA;
set(handles.TagID_A,'string',num2str(TagID_ReaderA(1,:)));
% Store time stamp (clock)
Read_btA{handles.DataCounter.A,2} = clock;
clockA = clock;
handles.recording.A{Count_btA,2} = clockA;
% Display read time
roundtime = [num2str(clockA(4)-12) ':' num2str(clockA(5)) ':' num2str(round(clockA(6)))];
set(handles.TagTime_A,'string',roundtime);
% Increase row counter every iteration
handles.DataCounter.A = handles.DataCounter.A + 1;
guidata(hObject, handles);
handles = guidata(hObject);
clear TagID_ReaderA
end
How do I update handles and my guidata now?
Thanks,
Justin
Geoff Hayes
Geoff Hayes le 22 Oct 2014
Hi Justin,
Your code should be fine with the updating of the handles structure since you have added the line
guidata(hObject, handles);
The above line will save the updated handles structure so that other functions will receive this version either when it is passed as an input parameter or when the guidata(hFigure) is called.
Note that you do not need the final two lines of the if body
handles = guidata(hObject);
clear TagID_ReaderA
as you don't need the "updated" handles structure, and as this function goes out of scope, ten the TagID_ReaderA variable will be cleared anyway (since it is not persistent).

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Data Import and Analysis dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by