我编写了一个Matlab脚本,该脚本使用实时中的虚拟COMM端口读取数据。我在mfile中完成了大量的信号处理。
接下来,我觉得需要一个紧凑的GUI,将信息显示为摘要。
我最近才开始挖掘和阅读更多Matlab的内置GUI工具GUIDE。我已经按照了一些教程,成功地将我的图表显示在我的GUI 按下按钮之后。
但是,我希望 GUI能够实时更新。我的数据向量不断更新(从COMM端口读取数据)。我希望GUI能够使用较新的数据保持更新图表,而不是依靠按下按钮进行更新。有人可以指出我正确的方向进行背景更新吗?
以下是目前GUI的相关代码:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global data
global time
% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);
编辑更改代码:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%Setting it to display something when it ends
% t = timer('TimerFcn', 'timerOn=false; disp(''Updating GUI!'')',...
t = timer(...
'TasksToExecute', 10, ... % Number of times to run the timer object
'Period', 3, ...
'TimerFcn', GUIUpdate());
%Starting the timer
start(t)
function GUIUpdate()
global data
global time
%Parameters below axes
global min
global max
% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);
%Other parameters:
set(handles.mean, 'String', mean);
set(handles.max, 'String', max);
我得到的错误是:
??? Error using ==> GUI_Learning>GUIUpdate
Too many output arguments.
Error in ==>
@(hObject,eventdata)GUI_Learning('pushbutton1_Callback',hObject,eventdata,guidata(hObject))
??? Error while evaluating uicontrol Callback
答案 0 :(得分:10)
以下是使用带有timerFcn回调的计时器的示例。我用一个轴和一个按钮做了一个简单的GUI。
在打开功能中,我初始化绘图并创建计时器。在开始按钮回调中,我启动计时器并开始操作数据。定时器函数回调只是通过其句柄更新行的y数据。下面是GUI的M文件中的相关函数(剪切的init部分和输出fcn。
function testTimer_OpeningFcn(hObject, eventdata, handles, varargin)
global y x
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
handles.plot = plot(handles.axes1,x,y);
handles.timer = timer('ExecutionMode','fixedRate',...
'Period', 0.5,...
'TimerFcn', {@GUIUpdate,handles});
handles.output = hObject;
guidata(hObject, handles);
% --- Executes on button press in startButton.
function startButton_Callback(hObject, eventdata, handles)
global y x
start(handles.timer)
for i =1:30
y = sin(x+i/10);
pause(1)
end
function GUIUpdate(obj,event,handles)
global y
set(handles.plot,'ydata',y);
您可能需要一个“停止”按钮来停止计时器,具体取决于GUI的结构以及数据的更新方式。
编辑:基本处理信息其中一些非常基础,你可能已经知道了:
对象的单个句柄包含一组属性,您可以使用get()函数读取或使用set()函数进行设置。因此,例如,我想在GUI中出于某种原因更改startButton的文本。
set(handles.startButton,'String','Something Other Than Start');
您可能只想在代码中设置一个断点(可能是按下按钮)并使用句柄结构。在各种对象上运行get()
命令以了解其属性。
现在,句柄结构包含GUI对象的所有... umm ...句柄以及可能方便您存储的任何自定义项目。大多数GUI回调会自动传递handle struct,因此您可以轻松访问GUI的所有部分。
实施例。 'startButton'回调自动传递handles
。所以我可以通过handles.timer
轻松访问计时器对象。
这使我将自定义内容粘贴到handles
中。在open函数中,我向句柄结构handles.timer
和handles.plot
添加了一个新项,因为我知道它们在其他回调中很有用(比如按下按钮和timerFcn回调)。
但是,要永久存储这些东西,您需要使用'guidata'功能。此函数基本上存储修改后的handles
结构或根据您调用它的方式检索handles
的副本。因此,open函数中的以下行是将修改后的句柄结构(添加.timer和.plot)存储到主GUI中。
guidata(hObject,handles);
基本上,只要您在handles
中添加内容,就应该使用该行来永久更改内容。
现在调用它的另一种方法是:
handles = guidata(hObject); %hObject can be any handle who is a child of the main GUI.
这将检索GUI的句柄结构。
最后handles.output = hObject
只是启动GUI时的默认输出。如果你通过Matlab的命令行调用你的GUI,就像这个h = myGUI;
一样,它应该返回GUI的句柄。
答案 1 :(得分:1)
您需要使用timer object。将回调设置为更新图表的函数。
答案 2 :(得分:1)
查看Making Graphs Responsive with Data Linking 和linkdata命令。
如果多个图中的图中出现相同的变量,则可以 将任何图表链接到变量。您可以使用链接图 音乐会与数字刷新标记图表,但也在他们的 拥有。链接图可以让你
- 使图表响应基础工作区或函数
中变量的变化- 在“变量编辑器”和“命令行”中更改变量时,使图形响应
- 通过数据刷牙修改变量,一次影响它们的不同图形表示
- 为调试目的创建图形“监视窗口”
如果使用MATLAB语言编程,观察窗口非常有用。对于 例如,在细化数据处理算法时要逐步完成 你的代码,你可以看到图表响应变量的变化 函数执行语句。
我在下面看到了一个快速而肮脏的测试,我不确定它如何在GUI中与函数一起工作但是可以做到这一点。
注1:我必须在子程序中添加一个断点,它修改全局y
以实际看到图自动更新。如果数据快速变化,您可能需要一些drawow,pause或timer的组合。
function testLinking()
global x y
%Links failed if the global did not also exist in the base workspace
evalin('base','global x y');
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
h = plot(x,y,'ydatasource','y','xdatasource','x');
linkdata on
testSub
function testSub()
%Test to see if a sub can make a linked global refresh
global x y
for i = 1:10
%This should automatically update the plot.
y = sin(x+i/10);
end
编辑:根据你的函数结构的不同,可能有很多方法可以使用全局变量......但是我没有时间深入研究它。
答案 3 :(得分:0)
您可以在执行绘图功能的串行对象上添加回调。您必须将回调附加到对象上的“BytesAvailableFcn”事件(有关com对象属性的更多详细信息,请参阅this。)
基本上,当com端口上有可用的字节时,您指示matlab运行特定的功能。在您的情况下,它将是更新GUI的功能。如果您需要先处理传入的数据,那么您的回调函数将首先执行信号处理,然后执行绘图命令。