MATLAB Answers

Adding stop button to stop the data streaming from comport to GUI builder

1 view (last 30 days)
Hello,
I am new into making Matlab GUI and want to add basic things to made the GUI.
I made a function(stream_data) GUI for streaming the data from Microcontroller into matlab and the sampling rate of the signal being coming through termianl is 20Hz.
can someone help in adding a stop button such that the data streaming should stopped when the stop button is hit or clicked in the GUI created using GUI builder.
start button:when the start is clicked or selected it should start to stream the terminal data.
start button:when the stop is clicked or selected it should stop to stream the terminal data.
In the below code open_com_port function is comport read function.
GUI function created from GUI builder ::
function varargout = p_gui(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @p_gui_OpeningFcn, ...
'gui_OutputFcn', @p_gui_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function p_gui_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = p_gui_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function pushbutton1_Callback(hObject, eventdata, handles)
com_port = 12;
stream_data(com_port);
function pushbutton2_Callback(hObject, eventdata, handles)
stream_data fucntion ::
function stream_data(com_port)
com_port = 10;
sampleCounter = 1;
dt = 1e-2;
data_file_name = 'pulsedata.txt';
FID = [];
s_writetofile = false;
s_quitgui = false;
%%GUI Geometry
%Get screen information, used for initial positioning of GUI.
screensize = get(0,'screensize');
% Specify some sizes and geometry
fontsize = 12; %ceil(1/60*coverratio*screensize(4));
linewidth = 1; %1/400*coverratio*screensize(4);
main_height = 600; %coverratio*min(screensize(4),1/goldenratio*screensize(3));
main_width = 1100; %goldenratio * main_height;
main_left = screensize(1)+(screensize(3)-main_width)/2;
main_bottom = screensize(2)+(screensize(4)-main_height)/2;
window_title = 'streaming Pulse Data';
% Close old demos that are still open
try
while true
close(window_title)
end
catch
% just continue if close failed
end
% Create main figure
fh = figure('Visible','off',...
'Name',window_title,...
'Color', [0 0 0],...%[0.941176 0.941176 0.941176],...
'Resize','on',...
'Position',[main_left,main_bottom,main_width,main_height],...
'MenuBar','none',...
'NumberTitle','off',...
'Renderer','opengl');
% Set background color scheme to either white or black
colordef(fh,'white');
rawax_left = 0.5*main_height;
% rawax_bottom =
rawax_height = 0.5*main_height;
rawax_width = 1*(main_height);
% Create axis for raw output
rawax_gyr = axes('Parent',fh,...
'Units','pixels',...
'XGrid','on',...
'FontSize',fontsize,...
'Position',[rawax_left, ...
(2/2+0.01)*main_height,...
rawax_width,...
rawax_height]);
% for X output
raw1_gyr = line('Parent',rawax_gyr,...
'XData',[],...
'YData',[],...
'Color',[0 0 1],...
'LineWidth',linewidth);
rawaxtitle = title(rawax_gyr,'Raw Pulse data');
rawaxylabel = ylabel(rawax_gyr,'Measured Amplitude'); %,'Color',orange);
rawaxxlabel = xlabel(rawax_gyr,'Number of pulses'); %,'Color',orange);
% try
delete(instrfindall);
s1 = open_com_port(com_port);
gui_update_freq_divisor = 20;
flushBytesThreshold = 500;
k = 1;
pulse_count=0;period(20)=0;results(100)=0;max1=0;
while ~s_quitgui
nb = s1.BytesAvailable;
if nb > flushBytesThreshold
error('serial data overflow')
end
if(nb)
currtime(k) = sampleCounter*dt;
[tline,count] = fgetl(s1);
data_tmp = str2num(char(tline));
data(k)=(data_tmp);
if s_writetofile
fprintf(FID,'%f %f \n',currtime,data);
end
% update gui not so often
if (~mod(sampleCounter,gui_update_freq_divisor))
for i=1:1:20
if (data(i)==4095)
results(i)=1;
else
results(i)=0;
end
end
max1=max(results);
axes(rawax_gyr)
set(raw1_gyr,'XData',[get(raw1_gyr,'Xdata') currtime]);
set(raw1_gyr,'YData',[get(raw1_gyr,'YData') data]);
% Slide x-axis of the smaller axes
set(rawax_gyr,'XLim',[currtime(1)-10 currtime(1)])
set(rawax_gyr,'YLim',[-10 5000])
k = 0;i=1;
%drawnow
end
sampleCounter = sampleCounter + 1;
k = k + 1;
end
%pause(0.0001);
end
delete(s1)
close(fh)
end
can someone help me in adding the stop button to stop the data streaming.

Accepted Answer

Benjamin Avants
Benjamin Avants on 14 Mar 2014
OK, where to start.
Buttons... You create buttons from code with the uicontrol function. A pushbutton could be made like this:
buttonHandle = uicontrol(f,'Style','Pushbutton','Position',[x,y,w,h],'Callback',{@ButtonCBF,var1});
This will create a button as a child object in figure f at the designated position in f with a callback function "ButtonCBF". Any time the button is pushed, it will call ButtonCBF as follows:
ButtonCBF(hObject,event,var1)
Where hObject is the button handle, event is empty, and your specified variable var1 is passed as the next parameter. In the callback, you can specify what you want the button to do in terms of code.
Updating the GUI:
I would strongly suggest not using a while loop. Use timers or a listening function to check the COM for data and update the GUI window. First thing, the pause function is blocking meaning you can't do anything else while paused. Second, pause is highly inaccurate at small time values and can't really time anything less than 0.01 seconds. Even at 0.01, I often get close to 0.02 seconds as the time actually elapsed during the pause.
Serial communication:
I would make a listener function for your serial connection that automatically receives and stores the data sent by the device. In fact, you should probably have the listener function update your GUI for you as well. You'll either need a global variable for it to check whether or not its supposed to update the GUI or instead of a Start and Stop pushbutton use a checkbox and check its value in the listener function.
You could use something like this:
cb = uicontrol(f,'Style','Checkbox','Position',[x,y,w,h],'Tag','MyCB');
function myListener(hObject,~)
input = [];
while hObject.BytesAvailable > 0
temp = fscanf(hObject);
input = [input,temp];
end
if get(findall(0,'Tag','MyCB'),'Value') == 1
% Update the GUI
end
Of course, you'll need to make a closing function for your figure so that it deletes the com object when you close the window or you'll have to do it manually.
When programming GUIs, you should design them so that most of the functionality is handled by listeners and callbacks. The function that creates the GUI should return once the figure is created and all uicontrols are setup.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!

Translated by