我在树莓派上使用qextserialport与PanStamp(与Arduino兼容的设备)通信。
这个连接到Pi的PanStamp执行两个功能:
- 每秒发送一些传感器的读数(约12字节)
- 通过无线链路发送它接收到的所有数据(大约60字节,每秒大约6次)
我的架构是:
- 集线器:PanStamp+Raspberry Pi
- 卫星:PanStamp+一些传感器
有两种情况:
- 卫星正在向集线器无线发送数据。在这种情况下,圆周率每秒通过其串行端口接收大量数据
- 卫星关闭后,Pi每秒通过串行端口接收大约12个字节
当卫星关闭时,readyRead()
信号不会在每次字节到达时生成,它会将我的程序驱动到"不同步"状态,在这种状态下,读取的每个数据包都有一个或多个停留在缓冲区中(不断增长)。
然而,当我打开卫星,Pi开始接收大量数据时,这种"不同步"的情况消失了,出现了数据突发(缓冲区增长更快,之后被清空),我的程序开始"实时"工作。
以下是我的程序输出示例:www.tiago.eti.br/storage/iSDE.log
正如您在日志中看到的,可用的字节数不断增长,数据每秒发送一次(以HUB:
开头的行不是每秒处理一次的。开头有一个时间戳)。过了一段时间,出现了一个突发(卫星已经打开),每秒都有大量数据被处理,卫星的数据开始被处理(以8
开头的行),缓冲区被清空,我的程序开始"实时"处理数据。
那么,我该怎么做才能避免缓冲区增长过多,并且不会丢失数据呢?当缓冲区大于100字节时,我试图调用连接到readyRead()
的函数,但它造成了混乱,我开始丢失一些数据包。
你的问题是人们使用QIODevice。。你错误地认为readyRead是对每个字节调用的,说得更多的是,如果它这样工作,那就完全错误了。想法是,每次你收到readyRead时,都有东西要从设备中读取。。它可以是1字节、10字节、1k。。简单地说,它这样做是为了在块传输的情况下最小化CPU负载,以及在硬件上以块而不是以字节读取数据。
因此,您应该调用readAll()来获取所有到达的可用数据,并以您喜欢的方式对其进行处理。
你可能想看看这里。。