存在两个按钮的MATLAB GUI。每个按钮开始执行从Com-Port(不同)读取串行数据的无限循环。当我按下按钮时,while循环读取串口,但是当我按下下一个按钮时, port1 停止,然后 port2 开始读取,当我停止时 port2 , port1 正在恢复。所以我的问题是,所有带有while循环的回调函数如何能够独立地同时工作..
function samplegui_OpeningFcn(hObject, ~, handles, varargin)
handles.output = hObject;
handles.vec_A=[];
handles.vec_B=[];
handles.vec_C=[];
handles.vec_A_1=[];
handles.vec_B_1=[];
handles.vec_C_1=[];
guidata(hObject, handles);
function open_Callback(hObject, eventdata, handles) % push button1 to receive serial data.
cnt=0;
while 1
% Getting data from Serial Port
get_lines=fgets(handles.se) % getting data from serial port
if~isempty(get_lines)
cnt=cnt+1;
if strfind(get_lines,'T') %Parsing data
handles.vec_A=[handles.vec_A;[timet newword]];
plot(handles.vec_A(:,1),handles.vec_A(:,2:end),'r'); % plotting
% Same follows for parsing and plot vec_B and Vec_C
drawnow(); % to update the Plots
end
end
Pause(.05);
end
guidata(hObject, handles);
function open2_Callback(hObject, eventdata, handles) % push button2 to receive serial data.
cnt=0;
while 1
% Getting data from Serial Port
get_lines=fgets(handles.se2) % getting data from serial port2
if~isempty(get_lines)
cnt=cnt+1;
if strfind(get_lines,'T') % Parsing data
handles.vec_A_1=[handles.vec_A;[timet newword]];
plot(handles.vec_A_1(:,1),handles.vec_A_1(:,2:end),'r'); % plotting
% Same follows for parsing and plot vec_B and Vec_C
drawnow(); % to update the Plots
end
end
Pause(.05);
end
guidata(hObject, handles)
答案 0 :(得分:3)
您不能在MATLAB中执行此操作,因为它一次只能执行一个任务。解决这个问题的方法是让timer
以给定的间隔监听每个串口并按下按钮启动/停止此计时器。在这种情况下,您不需要while
循环pause
,您只需要一个从串口获取数据的函数,并在每次定时器触发时调用此函数。
%// Function called each time a timer is fired, gets data from specified serial port
function getData(hObject, handles, serialport)
get_lines = fgets(serialport);
if isempty(get_lines)
return
end
if strfind(get_lines,'T')
handles.vec_A = [handles.vec_A; [timet newword]];
plot(handles.vec_A(:,1),handles.vec_A(:,2:end),'r');
drawnow();
end
guidata(hObject, handles);
end
%// And for your button callbacks that will toggle the timers on/off
function open2_Callback(hObject, eventdata, handles)
if ~isfield(handles, 't2') || ~isvalid(handles.t2) || ~handles.t2.Running
%// Create a timer that checks the serial port twice a second
handles.t2 = timer('ExecutionMode', 'fixedRate', ...
'Period', 0.5, ...
'TimerFcn', @(s,e)getData(hObject, handles, handles.se2));
%// Start the timer
start(handles.t2);
else
%// Stop and destroy the timer
stop(handles.t2);
delete(handles.t2);
end
guidata(hObject, handles);
end
function open_Callback(hObject, eventdata, handles)
if ~isfield(handles, 't1') || ~isvalid(handles.t1) || ~handles.t1.Running
handles.t1 = timer('ExecutionMode', 'fixedRate', ...
'Period', 0.5, ...
'TimerFcn', @(s,e)getData(hObject, handles, handles.se1));
start(handles.t1);
else
stop(handles.t1);
delete(handles.t1);
end
guidata(hObject, handles);
end
<强>更新强>
如评论中@Hoki所述,您还可以设置串行连接的byteAvailableFcn
属性,该属性会在新数据到达时自动触发(有些异步)。这样可以防止您不得不定期轮询串口以获取新数据。
function getData(serialport, hObject, handles)
get_lines = fgets(serialport);
if strfind(get_lines,'T')
handles.vec_A = [handles.vec_A; [timet newword]];
plot(handles.vec_A(:,1),handles.vec_A(:,2:end),'r');
drawnow();
end
guidata(hObject, handles);
end
set([handles.se2, handles.se1], 'BytesAvailableFcn', @(s,e)getData(s, hObject, handles);
答案 1 :(得分:0)
function samplegui_OpeningFcn(hObject, ~, handles, varargin)
handles.output = hObject;
handles.vec_A=[];
handles.vec_B=[];
handles.vec_C=[];
handles.vec_A_1=[];
handles.vec_B_1=[];
handles.vec_C_1=[];
guidata(hObject, handles);
end
function getData_1(hObject, handles, serialport)
get_lines = fgets(handles.se_1);
if isempty(get_lines)
return;
end
if strfind(get_lines,'T')
handles.vec_A = [handles.vec_A; [timet newword]];
plot(handles.axes1,handles.vec_A(:,1),handles.vec_A(:,2:end),'r');
drawnow();
end
guidata(hObject, handles);
end
function getData_2(hObject, handles, serialport)
figure;
hold on;
ax(1)=subplot(3,1,1);
ax(2)=subplot(3,1,2);
ax(3)=subplot(3,1,3);
get_lines = fgets(serialport);
if isempty(get_lines)
return
end
if strfind(get_lines,'T')
handles.vec_A_1 = [handles.vec_A; [timet newword]];
plot(handles.vec_A_1(:,1),handles.vec_A_1(:,2:end),'r');
drawnow();
end
guidata(hObject, handles);
end
function open2_Callback(hObject, eventdata, handles)
if ~isfield(handles, 't2') || ~isvalid(handles.t2) || ~handles.t2.Running
%// Create a timer that checks the serial port twice a second
handles.t2 = timer('ExecutionMode', 'fixedRate', ...
'Period', 0.5, ...
'TimerFcn', @(s,e)getData_2(hObject, handles, handles.se2));
%// Start the timer
start(handles.t2);
else
%// Stop and destroy the timer
stop(handles.t2);
delete(handles.t2);
end
end
function open1_Callback(hObject, eventdata, handles)
if ~isfield(handles, 't1') || ~isvalid(handles.t1) || ~handles.t1.Running
%// Create a timer that checks the serial port twice a second
handles.t2 = timer('ExecutionMode', 'fixedRate', ...
'Period', 0.5, ...
'TimerFcn', @(s,e)getData_2(hObject, handles, handles.se2));
%// Start the timer
start(handles.t2);
else
%// Stop and destroy the timer
stop(handles.t2);
delete(handles.t2);
end
end
这是类似的代码,而你给..添加while循环因为它无法在端口连续读取数据。