Pass GUI handles through addlistener function in the session based interface

I am trying to control a NI Daq using Session based interface through a GUI and I am having problems sending handles through addlistener function.
lh = handles.ai.addlistener('DataAvailable', {@datacallback1,handles});
handles.ai.startBackground()
I get the following error
One or more output arguments not assigned during call to "_feval".
Error in daq.Session/addlistener (line 125) [el] = addlistener@handle(varargin{:});
Error in MAIN_GUI>monitor_Callback (line 165) lh = handles.ai.addlistener('DataAvailable', {@datacallback1,handles});
Error in gui_mainfcn (line 96) feval(varargin{:});
Error in MAIN_GUI (line 42) gui_mainfcn(gui_State, varargin{:});
Error in @(hObject,eventdata)MAIN_GUI('monitor_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating uicontrol Callback.
I want the function handles so that i can plot them on my GUI.
Is there anyother way to send handles through the addlistener funciton.
Thanks.

 Accepted Answer

Try
lh = handles.ai.addlistener('DataAvailable', @(src,evt) datacallback1(src,evt,handles));

5 Comments

Thanks for the timely help. I was held up there for the last 4 hours.
I have another doubt. I want to update handles in the function datacallback1 so that it can be used in the main function. How should I go about that.
Thanks
guidata(src,handles)
Provided that src is an object in the same figure as the GUI; if not then you need to pass down the figure handle of the GUI and guidata() against that instead.
I am still having trouble sending back my handles. I read online that even if you update using guidata() it does not update the GUI but just creates a copy in the sub function. Is there any way i can send back data while using addlistener command.
Thanks,
guidata() uses setappdata() to set a property in the figure object of the GUI.
The update to the figure object property happens as soon as the internals allow, and will be available to any routine that uses guidata() after that point.
GUIDE codes all callbacks so that guidata() is used at the time of callback and the updated version is available to all future GUIDE callbacks (and to anything that uses guidata() explicitly.)
What guidata(hObject,handles) can _not_ do is change the handles in the workspace of any routine that was already executing. Any routine that knows or suspects that the master object has been updated and which cares about the possible changes, should use guidata(hObject) to fetch the updated version.
If the handles structure to be changed is in your caller, then you could use assignin('caller', 'handles', handles) to update it. This is not good practice though: better would be have handles as input and output parameters for the called routine and have the caller assign the returned output. The cases where a routine cannot return an output parameter to the caller correspond to cases where the caller is ill-defined or some internal system routine.
One approach that would work would be to create shared variables uses by nested functions: then assignments inside called routines would affect the other routines.
Note that GUIDE does not generate code which is designed for shared; they could be edited in to place later, but would only last until GUIDE regenerated the code.
I managed to get this to work by setting up both session and legacy based aquisitions concurrently within a GUI, using the following configuration, (32 bit windows, Matlab 2011b version 7.13.0.564, Data Acquisition Toolbox sersion 3.0, with a National Instruments USB 6211.
The following has been taken from the StartUp function button Callback which is used to begin the pulse generation/signal aquisition:
---------------------
Using the Legacy based interface I set up input channels with a Timerfunc to regularly update the logged input signal for recording and plotting:
handles.ai = analoginput('nidaq', 'Dev1');
ai_ch = addchannel(handles.ai, [0 1]);
set(handles.ai, 'SampleRate', 1000);
set(handles.ai, 'SamplesPerTrigger', Inf);
set(handles.ai, 'TimerPeriod', 0.001);
set(handles.ai, 'TimerFcn', {@daqtimer, gcf});
---------------------
Then I set up a Session based pulse generator to run in the background:
handles.s = daq.createSession('ni');
handles.s.Rate = 1000;
handles.s.IsContinuous = true;
handles.s.addCounterOutputChannel('Dev1',0,'PulseGeneration');
handles.ch = handles.s.Channels(1);
handles.ch.Frequency = 5;
handles.ch.InitialDelay = 0.5;
handles.ch.DutyCycle = 0.5;
---------------------
Update Handles
guidata(hObject, handles);
---------------------
Finally, started both the session and legacy aquisitions
start(handles.ai);
handles.s.startBackground();
---------------------
Note, I was running this using a GUI and therefore needed to pass handles between function while the pulse generation operated in the background. There was a little messing about with the order to function calling and using guidata(), especially when changing the background session based parameters of the pulse generator and having the aquisition stop itself, reset parameters, and then restart.
FYI, the application is providing a output pulse signal along with various voltage input signal aquisitions in a fluid circuit used to simulate arterial flow. The background pulse generator signal was amplified via a transitor to open/close a solenoid valve. The GUI allows various data aquisition options to be selected along with adjustment of the heart rate/systolic time (i.e. frequency and duty cycle).

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!