Guidata not updating handles in timer stop function

2 visualizaciones (últimos 30 días)
Daemonic
Daemonic el 28 de Jul. de 2017
Respondida: Jan el 1 de Ag. de 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 comentarios
Daemonic
Daemonic el 31 de Jul. de 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 el 1 de Ag. de 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?

Iniciar sesión para comentar.

Respuesta aceptada

Akhilesh Thakur
Akhilesh Thakur el 31 de Jul. de 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 comentarios
Adam
Adam el 1 de Ag. de 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 el 1 de Ag. de 2017
Perfect. Yes that appeared to be the issue. Thank you!

Iniciar sesión para comentar.

Más respuestas (1)

Jan
Jan el 1 de Ag. de 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.

Categorías

Más información sobre Audio I/O and Waveform Generation en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by