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

How to run callback functions independently guide matlab

存在带有两个按钮的 MATLAB GUI。每个按钮开始执行从 Com 端口(不同)读取串行数据的无限循环。当我按下一个按钮时,while 循环读取串行端口,但是当我按下下一个按钮时,port1 停止,然后 port2 开始阅读,当我停止 port2port1 resuming.So 时,我的问题是,所有带有 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 中执行此操作,因为它一次只能执行一个任务。解决这个问题的方法是让 timer 以给定的时间间隔侦听每个串行端口,并按下按钮 start/stop 这个计时器。在这种情况下,您不需要带有 pausewhile 循环,您只需要一个从串行端口获取数据一次并在每次计时器触发时调用此函数的函数。

%// 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);
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循环,因为它无法在端口连续读取数据。