2

我在 Raspberry Pi 上使用 qextserialport 与 PanStamp(Arduino 兼容设备)进行通信。

这个连接到 Pi 的 PanStamp 执行两个功能:

  • 每秒发送一些传感器的读数(大约 12 个字节);
  • 通过无线链路发送它接收到的所有数据(大约 60 字节,大约每秒 6 次)。

我的架构是:

  • 集线器:PanStamp + Raspberry Pi;
  • 卫星:PanStamp + 一些传感器。

有两种情况:

  • 卫星以无线方式向集线器发送数据。在这种情况下,Pi 每秒都会通过其串行端口接收大量数据;
  • 卫星关闭,Pi 通过串行端口每秒接收大约 12 个字节。

当卫星关闭时,readyRead()不会在每次一个字节到达时生成信号,它会将我的程序驱动到“不同步”状态,其中每个数据包读取一个或多个留在缓冲区中(不断增长)。

但是,当我打开卫星并且 Pi 开始接收大量数据时,这种“不同步”情况消失了,出现了一阵数据(缓冲区增长得更快,之后被清空)并且我的程序开始工作“在即时的”。

这是我的程序输出的示例:www.tiago.eti.br/storage/iSEDE.log

正如您在日志中看到的那样,可用字节不断增长,并且每秒发送一次数据(以开头的行HUB:不是每秒都被处理。开头有一个时间戳)。过了一会儿,爆发(卫星已打开)并且每秒处理大量数据,开始处理卫星的数据(以 开头的行8),缓冲区被清空,我的程序开始处理数据“即时的”。

那么我该怎么做才能避免缓冲区增长过多并且不丢失数据呢?我试图readyRead()在缓冲区大于 100 字节时调用连接的函数,但它造成了混乱,我开始丢失一些数据包。

4

1 回答 1

4

您的问题是人们使用 QIODevice 时最常犯的错误。您错误地假设在每个字节上都调用了 readyRead,并说如果它像那样工作,那将是完全错误的。想法是,每次您收到 readyRead 时,都会设备中读取一些内容.. 它可以是 1 字节、10 字节、1k .. 等等。简单来说,这样做是为了在块传输的情况下最大限度地减少 CPU 负载以及在硬件上以块而不是字节读取数据。

所以你应该做的是调用 readAll() 来获取所有到达的可用数据并以你喜欢的方式处理它们。

你可能想看看这里..

于 2013-08-06T19:44:18.393 回答