How do I plot live data acquired via a NIDAQ inside a GUI window?

13 次查看(过去 30 天)
I currently have a function which plots data acquired via a NIDAQ (NI USB-6218) in real time. This is the following function, "acquirelive" :
% acquirelive function:
% acquire signal in real time
global time;
global data;
s = daq.createSession('ni');
addAnalogInputChannel(s,'Dev1', 0, 'Voltage');
s.Rate = 1000;
s.DurationInSeconds = 10;
lh = addlistener(s,'DataAvailable', @collectData);
s.startBackground();
This function calls the collectData function, which is the following:
function collectData(s,event)
time = event.TimeStamps;
data = event.Data;
h = animatedline(time,data);
end
This works well and plots the data in real-time over a 10 second period. However, when I attach this "acquirelive" function to a button in a GUI I'm designing using GUIDE, the GUI opens but nothing happens when the plot button is clicked (inside or outside the GUI). There is also no error message generated. This is the code associated with the button in the GUI:
function PlotButton_Callback(hObject, eventdata, handles)
acquirelive;
The GUI is pretty simple. There are no buttons aside from the plot button (it looks like this):
Any ideas why the placement of the function inside the GUI causes this problem? Do I need to initialize the axes of the plot in the code at some point?
Thanks for any advice you might have, I appreciate it! Let me know if more information is needed to answer the question.
  2 个评论
Geoff Hayes
Geoff Hayes 2016-7-6
Eamon - you may want to put a breakpoint at the line where you call acquirelive from the pushbutton callback so that when you press the button, you can start stepping through the code within the acquirelive script. When you do so, check to see if all variables are initialized properly.
If all code seems to be getting initialized proper but still nothing happens, then try copying and pasting the code from this script into your pushbutton callback (less the global variables since they seem to be unused). Or better yet, save the s to the handles structure so that you don't "lose" it and can access it again (to perhaps stop the data acquisition). Something like
function PlotButton_Callback(hObject, eventdata, handles)
handles.s = daq.createSession('ni');
addAnalogInputChannel(handles.s,'Dev1', 0, 'Voltage');
handles.s.Rate = 1000;
handles.s.DurationInSeconds = 10;
lh = addlistener(handles.s,'DataAvailable', @collectData);
handles.s.startBackground();
guidata(hObject, handles); % to save the updated handles structure
Does the above make a difference?
Eamon
Eamon 2016-7-6
编辑:Eamon 2016-7-6
Hi Geoff, thanks for your response! Your suggested change works. It generates a new window displaying the real-time signal. However, it doesn't display inside the GUI window itself, which is what I'm aiming for. I'll look into that, but any further suggestions you have would be appreciated. Thanks again.

请先登录,再进行评论。

采纳的回答

Vinod
Vinod 2016-7-13

更多回答(1 个)

Geoff Hayes
Geoff Hayes 2016-7-6
编辑:Walter Roberson 2016-7-9
Eamon - animatedline allows you to specify which axes you wish to create the line in, so you will need to pass the handle to your axes into the collectData callback. If the Tag property for your axes is axes1, then I think that you can do something like
...
lh = addlistener(handles.s,'DataAvailable', {@collectData,handles.axes1});
...
In the above, we just pass the axes handles as an input to the collectData function. This function will then change to
function collectData(s,event,hAxes)
time = event.TimeStamps;
data = event.Data;
h = animatedline(hAxes,time,data);
end
That should work. One thing you may want to consider is the line
h = animatedline(hAxes,time,data);
With it, you will be creating a new graphics object each time. This may be a problem depending upon often you are creating a line (does the rate refer to how many times a second or..?). An alternative is to create one animated line and just update its data over time. See the examples from the documentation and how the function addpoints is used.
  16 个评论
Eamon
Eamon 2016-7-19
Hi again, Geoff. I apologize for the delayed response. It seems that both the time and data arrays are of type double. The only part of the argument which is not, is the handles.axes1, which is of type matlab.graphics.axis.Axes, which would mean that the handles.axes1 is the part of the argument triggering the error. This seems odd given that the animatedline function is supposed to allow axes as the first part of the argument. I will look into alternative ways of using animatedline. Thanks again!
Noah Prisament
Noah Prisament 2023-6-7
This error:
Error using animatedline
Invalid type for argument X. Type should be double.
was most likely caused by non-double-typed data being sent to the "animatedline" initializer. The AnimatedLine previously only supported double-typed data for all axes. Now in R2023a, the AnimatedLine supports all numeric datatypes as well as datetimes and durations for all axes. Therefore, this error should not occur in the newest version of MATLAB.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Graphics Performance 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by