当前位置: 首页 > 知识库问答 >
问题:

处理高速数据时避免QSerialPort超时

季俭
2023-03-14

我正在开发一个windows应用程序,它以600Hz的频率从传感器接收数据。在五分之二的情况下,我的IO线程成功地从传感器读取4字节的数据,并将其传递给GUI线程。

问题是五次中有三次,QSerialPort有无法解释的超时,其中QSerialPort的waitForReadyRead()返回false和serial。errorString()有超时错误。在这种情况下,它将永远不会读取数据。如果我在超时错误的情况下从串行端口读取数据,我将在下一个waitForReadyRead读取中读取2000字节的数据,该读取将分块交付,从而使我的应用程序的实时数据接收方面过时。

我尝试使用串行端口的readyRead()信号,但它表现出相同的行为,即:如果出现超时错误,则不会触发readyRead()信号。

更新:我能够用使用非阻塞读取的Qt的终端示例([Qt\u INSTALL\u EXAMPLES]/串行端口/终端)重现问题。这个bug的出现频率要低得多,但它肯定仍然存在。

更新:使用串行端口监视器,我可以看到当它卡住时,Qt终端示例卡在IOCTL_SERIAL_WAIT_ON_MASK,我的示例卡在IOCT_SERIAL_WAIT_ON_MASK后IRP_MJ_WRITEDOWN。其他终端软件从未发生过这种情况,这让我认为问题肯定出在Qt上。

串行端口监视器输出的粘贴箱

void IOThread::run(){

QSerialPort serial;
serial.setPortName(portname)
serial.setBaudRage(QSerialPort::Baud115200);
serial.setStopBits(QSerialPort::OneStop)
serial.setParity(QSerialPort::NoParity);
serial.setDataBits(QSerialPort::Data8);
serial.setFlowControl(QSerialPort::NoFlowControl);

if(!serial.open(QIODevice::ReadWrite)
{
    qDebug() << "Error Opening Port";
    return;
}
else
{
    qDebug() << "Error Message: " << serial.errorString() // prints "Unknown Error"
}

while(true)
{
    if(serial.waitForReadyRead(1000))
    {
        qDebug() << "Normal read";
        reception_buffer = serial.readAll();
    }
    else
    {
        qDebug() << "Timeout";
        /* serial.readAll() here will read nothing but force next read to read huge chunk of data */ 
        continue;
    }
}

// Process data...
}

共有3个答案

施海
2023-03-14

感谢QSerialPort的人员,Qt 5.10.1中的这个bug通过应用以下补丁得以解决:https://codereview.qt-project.org/#/c/225277/

“当数据到达打开中的设备时,QSP可能会忽略所有读取事件。在这种情况下,即使重新打开设备也没有帮助。原因是在调用startAsyncCommunication()之后启用QWinOverlappedOntifier,这可能会导致忽略所有EV\U RXCHAR事件。一种解决方法是在调用任何I/O操作之前启用通知程序。”-Denis Shienkov,QSerialPort维护人员

宇文飞羽
2023-03-14

在IOCTL\u SERIAL\u WAIT\u on\u MASK上卡住

最有可能的问题出在您的硬件或驱动程序中。QSP使用基于WaitCommEvent的异步通知。如果WaitCommEvent卡住了-那么问题出在您的设备或驱动程序中(最有可能)。

宿丰
2023-03-14

如果这有什么不同,请尝试:

while (true) {
    QByteArray reception_buffer;
    if (serial.waitForReadyRead(1000)) {
        reception_buffer = serial.readAll();
        while (serial.waitForReadyRead(10)) {
            reception_buffer += serial.readAll();
        }
        qDebug() << "reception_buffer ready";
    }
    else {
        qDebug() << "Timeout";
    }
}

如果要防止从waitForReadyRead超时,可以设置:

if(serial.waitForReadyRead(-1))

bool QSerialPort::waitForReadyRead(int msecs=30000)将在毫秒后超时;默认超时为30000毫秒。如果msecs为-1,函数将不会超时。

 类似资料:
  • 我正在使用的SMS网关来响应客户传入的短信。 但是,我的处理需要相当长的时间(大约20秒),在此期间,我从Twilio收到一个超时。 我在想一个防止超时的方法。我怎样才能加快处理时间?耗时最长的部分是我上传一些图像。我在想我可以在不同的线程中启动这个过程。我的服务器只有一个核心,那么多线程会有好处吗?

  • 问题内容: 我已经在C中实现了一些排序算法(用于对整数进行排序),并谨慎地用于存储与数据大小有关的任何内容(因此还包括了计数器和填充物),因为该算法也应使用数千兆字节的数据集进行测试整数 这些算法应该很好,并且分配的数据量应该没有问题:数据存储在文件中,并且每次仅加载很少的块,即使将内存中的缓冲区阻塞为任意大小,也可以正常工作。 使用数据集最多4千兆字节(因此16GB数据)的测试可以正常工作(排序

  • 寻找设计我的Kafka消费者的最佳方法。基本上,我想看看什么是避免数据丢失的最佳方法,以防在处理消息期间出现任何异常/错误。 我的用例如下。 a)我使用SERVICE来处理消息的原因是 - 将来我计划编写一个ERROR处理器应用程序,该应用程序将在一天结束时运行,它将尝试再次处理失败的消息(不是所有消息,而是由于任何依赖项(如父级缺失)而失败的消息)。 b)我想确保没有消息丢失,所以我会将消息保存

  • 本文向大家介绍Spark处理数据排序问题如何避免OOM,包括了Spark处理数据排序问题如何避免OOM的使用技巧和注意事项,需要的朋友参考一下 错误思想 举个列子,当我们想要比较 一个 类型为 RDD[(Long, (String, Int))] 的RDD,让它先按Long分组,然后按int的值进行倒序排序,最容易想到的思维就是先分组,然后把Iterable 转换为 list,然后sortby,但

  • 我需要从mongo(v3.2.10)集合(使用Pymongo 3.3.0)中获取大量(例如1亿)文档并迭代它们。迭代需要几天时间,我经常遇到由于游标超时而导致的异常。 在我的例子中,我需要在迭代时睡上不可预知的时间。例如,我可能需要:-获取10个文档-睡眠1秒-获取1000个文档-睡眠4小时-获取1个文档等 我知道我可以: 完全禁用超时,但如果可能的话,我希望避免这种情况,因为如果我的代码完全停止

  • 我试图使用Slack自定义命令,但不太确定如何使用延迟消息,因为Yoda Speak外部API需要超过3秒来响应。 我做了以下工作: 在我的例子中发送了slack命令,并收到了. 使用以下内容以下内容发送到响应URL。 null 我仍然得到相同的错误“该死-那个斜杠命令不起作用(错误消息:)。在slash-command管理命令”