QextSerialPort (QIODevice) 的 readyRead() 信号调用速度不够快 [英] readyRead() signal of QextSerialPort (QIODevice) is not being called fast enough

查看:61
本文介绍了QextSerialPort (QIODevice) 的 readyRead() 信号调用速度不够快的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using qextserialport on a Raspberry Pi to communicate with an PanStamp (Arduino compatible device).

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

This PanStamp connected to the Pi executes two functions:

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

我的架构是:

  • 集线器:PanStamp + Raspberry Pi;
  • 卫星:PanStamp + 几个传感器.
  • Hub: PanStamp + Raspberry Pi;
  • Satellite: PanStamp + a few sensors.

有两种情况:

  • 卫星将数据无线发送到集线器.在这种情况下,树莓派每秒通过其串行端口接收大量数据;
  • 关闭卫星,树莓派每秒通过串口接收大约 12 个字节.

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

When the satellite is off the readyRead() signal is not generated every time a byte arrives and it drives my program to a "out of sync" condition where to each data packet read one or more stays in the buffer (that keeps growing).

然而,当我打开卫星并且 Pi 开始接收大量数据时,这种不同步"的情况消失了,有数据突发(缓冲区增长更快,之后被清空),我的程序开始实时"工作.

However when I turn the satellite on and the Pi starts to receive lots of data this "out of sync" condition disappear, there are a burst of data (the buffer grows faster and after is empted) and the my program starts to work "in real time".

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

Here is a example of my program's output: www.tiago.eti.br/storage/iSEDE.log

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

As you can see in the log the bytes available keeps growing and the data send every second (line starting with HUB: is not being processed every second. there is a time stamp at the beginning). After a while there is a burst (satellite has been turned on) and there is lots of data being processed every second, the satellite's data start to be processed (lines starting with an 8), the buffer is emptied and my program starts processing data in "real time".

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

So what can I do to avoid the buffer from growing too much and do not lose data? I tried to call the function that is connected to readyRead() when the buffer gets bigger than 100 bytes but it created a mess and I started to lose some packets.

推荐答案

您的问题是人们在使用 QIODevice 时最常犯的错误.像那样工作.想法是,每次您收到 readyRead 时,都会从设备读取一些 ..它可以是 1 字节、10 字节、1k 等等.简单地说,它这样做是为了最小化在块传输的情况下的 CPU 负载以及在硬件上以块而不是字节读取数据.

Your problem is in most common mistake people do with QIODevice.. you wrongly assume that readyRead is called on every byte, saying more it would be completely wrong if it works like that. Idea is that every time you receive a readyRead there is SOMETHING to read from the device.. it can be 1 byte, 10 bytes, 1k.. etc.. In simple words its done like that to minimise CPU loading in case of block transfers as well as on a hardware to read data in blocks rather then in bytes.

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

So what you should do is to call readAll() to get all available data which arrived and process them in a way you like.

您可能想查看此处...

这篇关于QextSerialPort (QIODevice) 的 readyRead() 信号调用速度不够快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆