MATLAB: How to plot a real time signal with axes automatically updating

serial

Hi all, i have an analog signal coming from the usb port of my PC, and i save it in Matlab using fread(serial…); i want to plot them in real time as soon as i acquire them, of course updating the time axis (seconds vs volts). How can i do this? Note that i get a sample every 100 ms! Thanks.

Best Answer

Alessandro - you could use a timer started from within your GUI that would, every 100 milliseconds, read from the bluetooth development board. You can set up your timer in such a way that it can access the handles object of the GUI so that if data has been read, it can be drawn on your axes.
For example, suppose that your timer starts when you press the start button in your GUI. The pushbutton callback would look something like
function start_Callback(hObject, eventdata, handles)
handles.timer = timer('Name','MyTimer', ...
'Period',0.1, ...
'StartDelay',0, ...
'TasksToExecute',inf, ...
'ExecutionMode','fixedSpacing', ...
'TimerFcn',{@timerCallback,handles.figure1});
guidata(hObject,handles);
start(handles.timer);
The above timer will fire (roughly) every 100 milliseconds. Note how we pass the GUI figure handle as an input to the timerCallback function. This is necessary so that we can access the handles structure (from there) to (potentially) update the axes with new data. The callback can be defined as
function [] = timerCallback(~,~,guiHandle)
if ~isempty(guiHandle)
% get the handles


handles = guidata(guiHandle);
if ~isempty(handles)
% query your bluetooth board using your code from the while loop
% if new data, then update the axes
end
end
In the above, we get the handles structure using guihandles so that we can get the current set of data in the axes control. In your stop button callback, you would then stop the timer
function stop_Callback(hObject, eventdata, handles)
if isfield(handles, 'timer')
stop(handles.timer);
end
When it comes to the code to update the plot with the new data, you can continue as before but bear in mind that every time you call plot you are creating a new graphics object. Which is a lot given that you do this ten times a second. An alternative is to plot once and update it's x and y data every time you have something to plot. In your start_Callback, create the object as
function start_Callback(hObject, eventdata, handles)
handles.timer - ...;
handles.hPlot = plot(NaN,NaN); % creates the graphics object with no data
guidata(hObject,handles);
start(handles.timer);
Then in the timer callback, update this plot as
xdata = [get(handles.hPlot,'XData') handles.T(end)];
ydata = [get(handles.hPlot,'YData') handles.array(end)];
set(handles.hPlot,'XData',xdata,'YData',data);
The above assumes that you are saving your updated T and array data to handles with the new data.
Try implementing the above and see what happens!
EDIT In the above, I replaced the
% get the handles
handles = guihandles(guiHandle);
with
% get the handles
handles = guidata(guiHandle);
so that we get back both the handles to the objects and any user-defined data.