QSerialPort严格地读取十六进制值

时间:2016-03-04 08:54:21

标签: c++ qt serial-port

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

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

当我发送像“Hello World!”这样的字符串时我可以使用comms.readAll()和comms.bytesAvailable()返回12来读取所有数据。

但是当我发送“Hello World!\ n \ r”时,它会显示“Hello World!”和“\ n \ r”部分完全相同,comms.bytesAvailable()首先返回12,然后是2。

当我发送十六进制字节(没有空格)

时,情况会越来越严重
0x0F 0x00 0x43 0x11 0x00 0x04 0x11 0x00 0x02 0x70

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

我怎样才能一次读取所有传入的字节,即使它不是标准字母?

3 个答案:

答案 0 :(得分:1)

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

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
}

答案 1 :(得分:0)

很遗憾,您无法确定已阅读所有数据。

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

答案 2 :(得分:0)

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

让我们看一下小伪码

    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
    }
 }

其他技术涉及command.etc

末尾的校验和,CRC等