MATLAB Answers

Guidata not updating handles in timer stop function

6 views (last 30 days)
Daemonic
Daemonic on 28 Jul 2017
Answered: Jan on 1 Aug 2017
I created a simple audio player that simultaneously captures data from a USB device during playback via a timer object. The timer is initialized during play and stopped when paused. Data from the device is captured every second with the timer's timer function and is saved to the handles structure. However, when the timer is stopped, I want the timer's stop function to notate the amount of elapsed time (using the toc function) and save this in a marker within the handles structure.
function SacredRNG_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
handles.data = []; % creates an empty bed for the data.
handles.Markers = [];
%%Sets Default Parameters for RNG
handles.tmr = timer('TimerFcn',{@FieldRNG_callback,hObject},... % Creates timer object as default Field RNG
'ExecutionMode','fixedRate',...
'StopFcn',{@StopRecording_callback,hObject});
guidata(hObject, handles);
Here is the timer function which works fine:
function FieldRNG_callback(obj,event,hObject) % Captures data from a connected USB based on timer
handles=guidata(hObject);
portObj = handles.portObj; % calls the serial port
ReadRate = handles.freqSam;%captures the read rate (i.e. dimensions of the numbers to be pulled from the RNG);
newdata = fread(portObj,ReadRate,'int8'); % pulls n data points each second when called by the timer
handles.data = [handles.data; newdata]; % updates the data in handles with the new data captured from the device.
guidata(hObject, handles);
Here is the timer's stop function which works but does not actually update the handles structure when guidata is executed. I tested this in debugging mode and the markers are created, however, they are just not saved.
function StopRecording_callback(obj,event,hObject)
handles=guidata(hObject);
handles.Markers(end+1) = toc; %Note tic is set when playback starts
handles.MrkrLabels{end+1,1} = ['stopped @ ',num2str(round(toc)),' seconds'];
guidata(hObject, handles);
I can used the disp(handles.Markers) command and verify that the markers are created properly and appended to the existing Markers and Marker labels. However, they are not saved. My understanding was that guidata should update the current handles structure and save these values. Notably this is working in the timer function so I don't understand why it wouldn't work in the stop function. Thanks for your help!

  3 Comments

Adam
Adam on 28 Jul 2017
Where are you checking that it does not work? Do you have another function initiated after StopRecording_callback where you call
handles = guidata( hObject )
?
Daemonic
Daemonic on 31 Jul 2017
Hi Adam. Well the audio player has a play / pause button. Pause stops the timer (and executes the stop function) and when unpaused, the timer re-initializes. Presumably the handles structure would update with the call at the end of the stop function.
I've checked it a couple of ways. First, I used the disp(handles.Markers) command within the stop function so that the Markers would appear in the command window. I also tried placing a breakpoint in the stop function in the debugger. Either method reveals that handles.Markers is showing the current elapsed time. However, when unpaused and the timer restarts, the data in handles.Markers is lost. Hence, handles = guidata( hObject ) doesn't seem to be working to save the data to the handles structure.
Saurabh Gupta
Saurabh Gupta on 1 Aug 2017
It looks like you have debugged "start to pause" and have determined the data is lost during "unpause". How is this "unpause" functionality written? Have you tried debugging it to see if you are accidentally clearing the data there?

Sign in to comment.

Accepted Answer

Akhilesh Thakur
Akhilesh Thakur on 31 Jul 2017
Okay the code I see here, there are possibilities why your handles are not stored. First thing the placement of guidata is fine but did you check which hObject it is pointing to? You should set a breakpoint and check whether the hObject is the same at all other functions you are pointing to. Another thing is check the sequence of the program is the location where the guidata is updated and you are trying to get a grab of it, will it hold the handles or pinpoint to new set. If you are pointing to wrong hobject use this command get(hObject,'parent'); . If you want to keep handles structure global and available all across your program use of setappdata(0,..) would be efficient. I hope this helps.

  2 Comments

Adam
Adam on 1 Aug 2017
So long as hObject is one of the components of the same figure handles will get saved to the figure. This is why it works fine in any callback, even though the hObject is different in each.
Daemonic
Daemonic on 1 Aug 2017
Perfect. Yes that appeared to be the issue. Thank you!

Sign in to comment.

More Answers (1)

Jan
Jan on 1 Aug 2017
I assume that there is a mistake in your way to check the success of the update of the handles struct. You did not show the GUI function, which triggers the stopping. Imagine this looks like this:
function StopButtonCallback(hObject, EventData, handles)
handles = guidata(hObject);
oldLength = numel(handles.Markers);
stop(handles.tmr);
while numel(handles.Markers) == oldLength
pause(0.02); % Are you sure that the timer's stop callback is finished?!
handles = guidata(hObject);
end
Now what do you observe? Is the figure's handles struct updated?
I would not use the name "hObject" for the figure handle in the timer callback. "hFigure" would be easier to understand.

  0 Comments

Sign in to comment.


Translated by