Multithreading 如何独立运行回调函数指导matlab

Multithreading 如何独立运行回调函数指导matlab,multithreading,matlab,callback,matlab-guide,Multithreading,Matlab,Callback,Matlab Guide,有两个按钮的MatlabGUI。每个按钮开始执行从Com端口读取串行数据的无限循环(不同)。当我按下一个按钮时,循环读取串行端口,但当我按下下一个按钮时,端口1停止,然后端口2开始读取,当我停止端口2时,端口1恢复。因此,我的问题是,所有带while循环的回调函数如何能独立和同时工作 function samplegui_OpeningFcn(hObject, ~, handles, varargin) handles.output = hObject; handles.vec_A=[];

有两个按钮的MatlabGUI。每个按钮开始执行从Com端口读取串行数据的无限循环(不同)。当我按下一个按钮时,循环读取串行端口,但当我按下下一个按钮时,端口1停止,然后端口2开始读取,当我停止端口2时,端口1恢复。因此,我的问题是,所有带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)

在MATLAB中无法执行此操作,因为一次只能执行一个任务。解决这一问题的方法是使用一个以给定间隔侦听每个串行端口的接口,并使用按钮启动/停止该计时器。在这种情况下,您不需要使用带有暂停的
循环
。您只需要一个函数,该函数从串行端口获取一次数据,并在每次定时器触发时调用该函数

%// 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
更新

如注释中所述,您还可以设置串行连接的
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);

在MATLAB中无法执行此操作,因为一次只能执行一个任务。解决这一问题的方法是使用一个以给定间隔侦听每个串行端口的接口,并使用按钮启动/停止该计时器。在这种情况下,您不需要使用带有暂停的
循环
。您只需要一个函数,该函数从串行端口获取一次数据,并在每次定时器触发时调用该函数

%// 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
更新

如注释中所述,您还可以设置串行连接的
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);
这与您给出的代码类似。。添加了while循环,因为它无法在端口连续读取数据


这与您给出的代码类似。。添加了while循环,因为它无法在端口连续读取数据

如果预期的数据量很大,我也倾向于使用计时器,但您也可以提到串行端口的内置回调
byteavailableFcn
,它也会静默地侦听数据并在数据到达串行端口时触发。@Suever是否可以分别保存和打印端口中的数据@MaK您可以为每个串行端口设置一个单独的回调函数,并在回调函数中进行自定义打印。@Suever我为串行端口编写了三个单独的函数,get _data1,get _data2,get data3。以及使用相应的按钮调用计时器功能。但我还是不能平行地阅读端口。@MaK正如我在开始时所说,它永远不会是真正平行的。如果您发布一些您所拥有的代码,我可以帮助您找出哪里出了问题。如果预期的数据量很大,我也倾向于使用计时器,但是您也可以提到串行端口的内置回调
byteavailableFcn
,当数据到达串行端口时,它也会静默地侦听并触发。@不管怎样,都可以分别保存和打印端口中的数据@MaK您可以为每个串行端口设置一个单独的回调函数,并在回调函数中进行自定义打印。@Suever我为串行端口编写了三个单独的函数,get _data1,get _data2,get data3。以及使用相应的按钮调用计时器功能。但我还是不能平行地阅读端口。@MaK正如我在开始时所说,它永远不会是真正平行的。如果你发布一些你所拥有的代码,我可以帮助你找出哪里出了问题。我已经更新了你的帖子,使其真正可读。还修复了一些错误。发布时不应该有任何问题。如果有,发布准确的错误消息。我已经更新了你的帖子,使其真正可读。还修复了一些错误。发布时不应该有任何问题。如果有,请发布准确的错误消息。