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

时间:2016-05-01 13:13:47

标签: multithreading matlab callback matlab-guide

存在两个按钮的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)

2 个答案:

答案 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循环因为它无法在端口连续读取数据。