【问题标题】:Running infinite loop to receive and send data in GUI | MATLAB运行无限循环以在 GUI 中接收和发送数据 | MATLAB
【发布时间】:2026-01-31 15:30:02
【问题描述】:

我正在做一个项目,通过XBees 将数据从一台笔记本电脑传输到另一台笔记本电脑。我已经完成了GUI界面,但是接收部分有问题。由于接收方不知道接收文件的确切时间,我编写了一个无限循环,即:

    recv=[];
    while (1)

        while s.BytesAvailable==0
        end

        a=fscanf(s);
        recv=[recv a]

    end

我怎样才能一直运行这个for循环,从程序一开始直到用户关闭程序,用户仍然可以选择不同的数据来传输它?

换句话说;将任务分为两部分,接收部分始终运行;而传输部分仅在用户想要传输数据时才起作用...

【问题讨论】:

标签: matlab user-interface parallel-processing matlab-guide xbee


【解决方案1】:

Matlab 支持异步读操作,当端口接收到数据时触发。触发器可以是最小字节数,也可以是特殊字符。

您必须使用BytesAvailableFcn 回调属性。

您可以使用setappdatagetappdata 来存储太大而无法放入端口输入缓冲区的数组。 假设你将主图的句柄保存到一个名为hfig的变量中:

在主 gui 代码中:

s.BytesAvailableFcnCount = 1 ;                           %// number of byte to receive before the callback is triggered
s.BytesAvailableFcnMode = 'byte' ;
s.BytesAvailableFcn = {@myCustomReceiveFunction,hfig} ;  %// function to execute when the 'ByteAvailable' event is triggered.

recv = [] ;                                              %// initialize the variable
setappdata( hfig , 'LargeReceivedPacket' , recv )        %// store it into APPDATA

作为一个单独的函数:

function myCustomReceiveFunction(hobj,evt,hfig)
    %// retrieve the variable in case you want to keep history data 
    %// (otherwise just initialize that to recv = [])
    recv = getappdata( hfig , 'LargeReceivedPacket' )

    %// now read all the input buffer until empty
    while hobj.BytesAvailable>0
        a=fscanf(hobj);
        recv=[recv a]
    end
    %// now do what you want with your received data
    %// this function will execute and return control to the main gui
    %// when terminated (when the input buffer is all read).
    %// it will be executed again each time the 'ByteAvailable' event is fired.
    %//
    %// if you did something with "recv" and want to save it, use setappdata again:
    setappdata( hfig , 'LargeReceivedPacket' , recv )        %// store it into APPDATA

【讨论】:

  • 这可能在您处理少量数据时起作用。但就我而言,因此我正在为 Aloha 协议进行模拟;我实际上正在处理数千个字节。连 InputBufferSize 和 OutputBufferSize 都拿不到这些数据……所以我得先把它码垛好再开始传输。
  • @AbdulmalekNaes,您可以调整输入和输出缓冲区大小,也可以调整在触发BytesAvailable 事件之前要接收的字节数(或特殊字符)。当然,如果流很长(或永久),您将不得不处理不止一次。我不确定我是否理解您的“码垛”概念。
  • 谢谢...我的意思是“打包”;将例如 900 万字节分成数据包。每个都有 50 千字节...是的,我知道我可以调整缓冲区大小,但是你放的越多,出现的错误和超时就会越多。
  • 如果您的输入约为 9Mb,您可以分块阅读,我更新了代码以向您展示如何操作。
  • Hoki...我不知道如何感谢您..但我有疑问; s.BytesAvailableFcn = {@myCustomReceiveFunction,hfig} 中的“hfig”是什么意思??
【解决方案2】:

我不熟悉 MATLAB,但在大多数编程环境中,您会使用无限循环检查串行端口上的输入,然后处理来自 GUI 的任何事件。如果你改变你的内部while循环,你可以在while(1)里面做其他事情:

recv=[];
while (1)
    while s.BytesAvailable>0
        a=fscanf(s);
        recv=[recv a]
    end

    ; Check for GUI events
end

【讨论】: