QSerialPort 单独读取十六进制值

QSerialPort reads hex values sepereatly

本文关键字:十六进制 读取 单独 QSerialPort      更新时间:2023-10-16

我正在使用Qt的QSerialPort库与RS232通信。我将 ReadyRead 信号连接到我的 readData() 插槽;

connect(comms,SIGNAL(readyRead()),this,SLOT(readData()));

当我发送类似"Hello World!我可以使用comms.readAll()读取所有数据,comms.bytesAvailable()返回12。

但是当我发送"Hello World!\r"时,它分别显示"Hello World!"和"\r"部分,comms.bytesAvailable()首先返回12,然后返回2。

当我发送十六进制字节时,情况变得更糟(没有空格)

0x0F 0x00 0x43 0x11 0x00 0x04 0x11 0x00 0x02 0x70

它正确读取值,但一次读取 1 或 2 个字节。我尝试了等待读取(),但这没有帮助。

如何一次读取所有传入字节,即使它不是标准字母?

尝试在字节可用时从端口读取:

if (f_port->bytesAvailable()) {   // If there are bytes available  
    QByteArray f_data; // data container
    f_data.clear();
    if (f_port->open(QIODevice::ReadWrite)) { // Try to open the port
        while(f_port->bytesAvailable()) { // Reading loop
            f_data.append(f_port->readAll());
        }
        f_port->flush();
        f_port->close();
    }
    qDebug() << f_data; // Check the result
}
不幸的是,

您无法确定已读取所有数据。

您必须在某个中间缓冲区中收集传入数据,并分析它以查找符合协议定义的命令。也就是说,必须满足某些要求,例如固定长度或特定的起始字节(例如0x02)或结束字节(想到\r)或这些要求的组合。

一种方法是用您获得的字节累积缓冲区。然后验证它是否是正确的命令(这取决于您决定什么是正确的)并触发您想要执行的命令。此外,您还应该有一个计时器来从缓冲区中删除垃圾。

让我们用一个小的伪代码看看

    static QByteArrray s_vBuffer;
    readData()
    {
      s_vBuffer.append(....);
      bool bValidCommand=VerifyCommand(s_vBuffer);
      if(bValidCommand)
      {
          QByteArray vCommand=ExtractCommand(s_vBuffer);//also removing the part of the command
          ExecuteCommand(vCommand);      
      }
    else 
    {
       //if timeout clear s_vBuffer
    }
 }

其他技术涉及命令末尾的校验和,CRC等