Qt串口接收数据不全

运行环境

版本:Qt5.14

IDE:QtCreator

问题描述

我使用的是readyRead()信号触发接收函数,使用serial->readAll()进行数据读取。在一台电脑上使用虚拟串口工具生成串口,使用串口助手每10ms发送一个262个字符的数据,不会发生接收数据不全的问题。

接着使用两台电脑,两个串口模块连接进行测试,同样速率和数据,接收到的数据会一段一段的到达。

处理方法

  1. 如果数据有帧头和帧尾,使用全局缓冲区,将接收到的数据放进缓冲区,判断是否满足整包,满足再进行包处理,不满足一直接数据

QByteArray Port_buffer;//需要定义在.h类里作为全局变量,不能放函数里

//下面是.cpp里
QByteArray data = serial->readAll();
Port_buffer.append(data);
if(Port_str.startsWith("FFFAFFFA")&&Port_str.contains("ED\r\n"))//帧头FFFAFFFA,帧尾ED
{
    //缓冲区里数据以FFFAFFFA开头,并且包含一个ED\r\n,表明至少有一个完整包
    index_ED = Port_buffer.indexOf("ED\r\n");//定位到帧尾的位置
    QByteArray pack = Port_buffer.left(index_ED+4);//取一个包的数据
    Port_buffer.remove(0,index_ED+4);
    //去空格、检查数据包
    //数据处理
}else if(!Port_str.startsWith("FFFAFFFA")&&Port_buffer.contains("FFFAFFFA"))
    {
        //不以FFFAFFFA开头,说明数据不完整,如果里面包含数据头,则直接删除到数据头的位置
        Port_buffer.remove(0,Port_buffer.indexOf("FFFAFFFA"));
    }

上面方式存在一个问题:使用虚拟串口本地测,不会发生数据分段接收,每次都是一个完整的数据进来,上面代码每次只允许一次,会发生Port_buffer里一直存数据包,时间长了就蹦了,处理方法:可以把接收改成定时处理。但是虚拟串口也只是理想情况,我的软件肯定是通过串口线连接到另外一台设备,所以这样应该也是可以的

Qt串口接收数据不全_第1张图片

上图data是从串口中取出的数据,直到存满完整数据才进行数据处理

Qt串口接收数据不全_第2张图片

上图使用虚拟串口,每次触发readyread都至少有一整个数据包(可能因为界面还在刷新数据等原因导致串口里滞留多个数据包),但是只触发一次读取数据,导致缓冲区里数据处理不完,这里可以用定时处理方式解决。

2.如果没有帧头帧尾,可以判断是否以\r\n结尾,判断是否收到一个完整数据包

if(Port_str.endsWith("\r\n"))//修改成endsWith("\r\n")就可以判断是否结束
{

}

其他

考虑过增加串口接收线程,但是代码会很复杂,上图里每2ms就能触发一次读数据,说明绰绰有余。我的界面刷新数据也是每次接收都刷新,还画个曲线图,再加上每10ms发个包,都能接收的过来。

建议:除非需要多个串口同时接数据,需要使用到多线程。如果只有一个串口接数据,就别折腾多线程了。

你可能感兴趣的:(Qt,qt,qt5)