简体   繁体   English

QextSerialPort(QIODevice)的readyRead()信号调用得不够快

[英]readyRead() signal of QextSerialPort (QIODevice) is not being called fast enough

I am using qextserialport on a Raspberry Pi to communicate with an PanStamp (Arduino compatible device). 我在Raspberry Pi上使用qextserialport与PanStamp(与Arduino兼容的设备)进行通信。

This PanStamp connected to the Pi executes two functions: 连接到Pi的PanStamp执行两个功能:

  • Send some sensor's readings each second (about 12 bytes); 每秒发送一些传感器的读数(大约12个字节);
  • Send all data it receives through a wireless link (about 60 bytes about 6 times per second). 通过无线链路发送接收到的所有数据(约60字节,每秒约6次)。

My architecture is: 我的架构是:

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

There are two situations: 有两种情况:

  • Satellite on sending data wirelessy to the Hub. 卫星将数据无线发送到集线器。 I this situation the Pi receives lots of data through it's serial port every second; 在这种情况下,Pi每秒都会通过其串行端口接收大量数据;
  • Satellite off, the Pi receives about 12 bytes each second through serial port. 卫星关闭后,Pi每秒通过串行端口接收大约12个字节。

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). 当卫星关闭时,不会在每次到达一个字节时都生成readyRead()信号,它会将我的程序驱动到“不同步”状态,在该状态下,每个数据包读取的一个或多个数据都保留在缓冲区中(并保持增长)。

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". 但是,当我打开卫星并且Pi开始接收大量数据时,这种“不同步”状态消失了,出现了数据突发(缓冲区增长得更快,之后被清空),并且我的程序开始在即时的”。

Here is a example of my program's output: www.tiago.eti.br/storage/iSEDE.log 这是程序输出的一个示例: www.tiago.eti.br/storage/iSEDE.log

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). 正如您在日志中看到的那样,可用字节不断增加,并且数据每秒发送一次(以HUB:开头的行HUB:每秒未处理。开头有一个时间戳)。 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". 有一阵子后(卫星已打开)并且每秒处理大量数据,开始处理卫星数据(以8开头的行),清空缓冲区,我的程序开始处理数据实时”。

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. 我试图在缓冲区大于100字节时调用连接到readyRead()的函数,但它造成了混乱,并且我开始丢失一些数据包。

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. 您的问题是人们使用QIODevice时常犯的最常见错误。您错误地假定在每个字节上调用readyRead,并说如果这样做就完全是错误的。 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. 想法是,每次接收readyRead也有一些是从所述设备读取时间..它可以是1个字节,10个字节,每千..等。在简单的话对其做像那样在数据块传输的情况下,最小化CPU负载以及在硬件上以块而不是字节为单位读取数据。

So what you should do is to call readAll() to get all available data which arrived and process them in a way you like. 因此,您应该做的是调用readAll()以获取所有到达的可用数据,并以您喜欢的方式对其进行处理。

you might want to have a look in here .. 您可能想在这里看看..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM