Matlab GUI using GUIDE: want to dynamically update graphics

I wrote a Matlab script that reads data using the virtual COMM port in real time . I have done a significant amount of signal processing in mfile.

Then I felt the need to have a compact graphical interface that displays information in a summary.

I just recently started digging and reading more of Matlab's built-in GUI tool, GUIDE. I followed several tutorials and can successfully display graphs in the graphical interface after clicking a button .

However, I want the GUI to be updated in real time . My data vector is constantly being updated (reading data from the COMM port). I want the GUI to keep the graphs updated with new data, rather than relying on the button to update. Can someone point me in the right direction to update the background?

The following is the appropriate code for the 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); 

EDIT Modified Code:

 % --- 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); 

The error I get is:

 ??? 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 
+7
source share
4 answers

Here is an example using a timerFcn callback. I made a simple graphical interface with 1 axis and 1 button.

In the opening function, I initialize the chart and create a timer. In the start button callback, I start the timer and start manipulating the data. The timer function callback function simply updates the y-data of the line through its descriptor. Below are the corresponding functions from the M GUI file (cut off section init and output fcn.

 function testTimer_OpeningFcn(hObject, eventdata, handles, varargin) global yx 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 yx 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); 

You can click the Stop button to stop the timer depending on how your GUI is structured and how / how the data is updated.

Edit: Basic Help. Some of them are quite simple, and you may already know this:

An individual object descriptor contains a bunch of properties that you can read using the get () function or the specified set () function. So, for example, maybe I wanted to change the startButton text for some reason in my GUI.

 set(handles.startButton,'String','Something Other Than Start'); 

You may just want to set a breakpoint in your code somewhere (perhaps with the click of a button) and play with structs struct. Executing get() commands on different objects to examine their properties.

Now the handle structure contains everything ... umm ... processes your GUI objects, as well as any custom elements that may be convenient for storing there. Most GUI callbacks automatically pass the handle structure, so you have easy access to all parts of the GUI.

Ex. The 'startButton' callback was automatically passed to handles . Thus, I had easy access to the timer object via handles.timer .

This leads me to embed custom stuff in handles . In the opening function, I added a new element to the structure of the handles.timer and handles.plot , because I knew that they would be useful in other callbacks (for example, pressing a button and timerFcn callback).

However, to preserve these things for a long time, you need to use the "guidata" function. This function basically either saves the modified handles structure or retrieves a copy of handles depending on how you name it. Thus, the next line in the opening function stores the modified handle structure (added .timer and .plot) in the main graphical interface.

 guidata(hObject,handles); 

Basically, when you add something to handles , you should have this line to make the change permanent.

Now another way to call it:

 handles = guidata(hObject); %hObject can be any handle who is a child of the main GUI. 

This will restore the structure of the handles for the graphical interface.

And the last handles.output = hObject is only the default output when starting your GUI. If you name your GUI using the Matlab command line, like this h = myGUI; , it should return the handle to your GUI.

+10
source

You need to use a timer object . Set the callback as a function that updates the graphics.

+1
source

Take a look at Creating charts that respond to data binding and linkdata .

If the same variable appears on graphs in several figures, you can associate any of the graphs with a variable. You can use related graphs in a concert with labeling graphs with data cleansing, but also their own. Linking charts allows you

  • Create graphs of response to changes in variables in the base workspace or inside a function
  • Make graphs answers when changing variables in the variable editor and command line
  • Change variables by cleaning data that affect various graphical representations of them right away
  • Creating graphical watch windows for debugging purposes

Watch hours are useful if you are programming in MATLAB. For example, when refining the data processing algorithm for your code, you can see that the graphs respond to changes in variables as the Function executes instructions.

I did the quick and dirty test seen below, and I'm not sure how this will work in GUI styles, but it can do the trick.

Note 1: I had to add a breakpoint to my routine, where it changes the global y to actually see the plot auto update. You may need a combination of pressed, pause or timer if the data changes quickly.

 function testLinking() global xy %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 xy for i = 1:10 %This should automatically update the plot. y = sin(x+i/10); end 

Edit: there may be ways to use globals depending on how your functions are structured ... but I donโ€™t have time to delve into this a lot.

+1
source

You can add a callback to a sequential object that performs the function of plotting. You must attach a callback to the "BytesAvailableFcn" event on the object (see > this for properties of the COM object for details).

In fact, when there are bytes in the COM port, you indicate that Matlab is launching a specific function. In your case, it will be a GUI update function. If you need to process the incoming data first, then your callback function will first process the signal and then execute the build commands.

0
source

All Articles