Qt5下串口对高频率自发性数据的接收及处理方法

       在项目中需要用Qt5.9采集仪表中的数据,仪表是以200Hz的频率主动向外连续发送数据,发送频率很高,而且主动发送,不需要软件发送一次,再读取一次,而是软件直接读取。这种直接连续读取,有两个关键点:1)如何从接收buffer里面查找出所需的数据帧;2)每次接收的数据buffer里面会有很多帧,如何存起来,每一帧的去解析,处理。

       整个程序分为:1)主程序下串口接收信号与串口接收函数connect部分;2)串口定时器启动函数serial_timerstart();3)串口读取函数部分;

一、主程序下串口接收信号与串口接收函数connect部分

 timer = new QTimer();
 QObject::connect(&serial,&QSerialPort::readyRead,this,&Trajectory::serial_timerstart);
 QObject::connect(timer,&QTimer::timeout,this,&Trajectory::serial_readyRead);
采用定时器,周期性读取串口数据。

二、串口定时器启动函数serial_timerstart();

void Trajectory::serial_timerstart()
{
   timer->start(3);//启动定时器,接收3毫秒数据(根据情况设定)
   buffer.append(serial.readAll());
  
}

三、串口读取函数部分;

void Trajectory::serial_readyRead()
{

    unsigned  char recvdata[255];
    int recvnum=0;

    timer->stop();//停止定时器,

   qDebug() << "receive(buffer.toHex()):= " <vect1;
      //从开头搜索"55aa"
       while((index = buffer.toHex().indexOf(buffer0,index))

四、调试记录如下:

receive(buffer.toHex()):="036fffff7d210000a97afd55aa2413740f00d9060000d00f00001cfcffffbc9afdffc748010043a795009a12b01100000000dc55aa2418740f009cf0ffffdcd1ffff39c1ffff2a7cfdff7e400100ea7d95009a12b01100000000b655aa241d740f00c91100004fecffff1ef5fffffb77fdff6d4d0100766595009a12b01100000000ee55aa2422740f0004a2ffff036fffff7d210000a97afdff2e4301006e7795009a12b01100000000f355aa2427740f00f310000063f5ffffd8dbffffeba4fdff15400100c03395009a12b01100000000ae55aa242c740f00649dffff35b6ffff6fe5ffff249afdff06500100ad2895009a12b01100000000f555aa2431740f006968000051060000bb020000879efdff3e5901007d3f95009a12b011000000003455aa2436740f00840b0000fcf0ffffcc8c00008081fdffbc2b0100626795009a12b011000000005e55aa243b740f0090ecffffd9ddffffc90a00004890fdff97440100fb5e95009a12b01100000000ee55aa2440740f00a4ddffff6afcffffa2e6ffff3f99fdffe52e0100316395009a12b01100000000ce55aa2445740f00ce8bffff7cbcffff9bd3ffff267dfdff38480100215c95009a12b011000000008455aa244a740f0033d9ffff4fe8ffff0e530000c48dfdff70460100f95095009a12b01100000000e055aa244f740f0086f1ffff935d0000a50e00002573fdffae470100af3995009a12b011000000008255aa2454740f00e76900009e8affff2ff1ffffe286fdff7b4201004a4195009a12b011000000003e55aa2459740f0030d5ffff7d4100006c080000b69dfdfff34601004f3e95009a12b011000000004d55aa245e740f002fd1ffffc43e000048170000bd93fdffd14d0100a43c95009a12b01100000000b155aa2463740f0033390000db2000008f0e0000bf79fdff34610100b45d95009a12b01100000000eb55aa2468740f0073cfffff2a6d0000be3d0000e0a5fdff4a3801006b7b95009a12b01100000000cd55aa246d740f00b82600007f28000036e9ffff69a8fdff3c3901006d7595009a12b011000000001d55aa2431740f006968"

receive(buffer.toHex().size()):= 25102
receive(buffer1):= "55aa2413740f00d9060000d00f00001cfcffffbc9afdffc748010043a795009a12b01100000000dc"
receive(buffer1):= "55aa2418740f009cf0ffffdcd1ffff39c1ffff2a7cfdff7e400100ea7d95009a12b01100000000b6"
receive(buffer1):= "55aa241d740f00c91100004fecffff1ef5fffffb77fdff6d4d0100766595009a12b01100000000ee"
receive(buffer1):= "55aa2422740f0004a2ffff036fffff7d210000a97afdff2e4301006e7795009a12b01100000000f3"
receive(buffer1):= "55aa2427740f00f310000063f5ffffd8dbffffeba4fdff15400100c03395009a12b01100000000ae"
receive(buffer1):= "55aa242c740f00649dffff35b6ffff6fe5ffff249afdff06500100ad2895009a12b01100000000f5"
receive(buffer1):= "55aa2431740f006968000051060000bb020000879efdff3e5901007d3f95009a12b0110000000034"
receive(buffer1):= "55aa2436740f00840b0000fcf0ffffcc8c00008081fdffbc2b0100626795009a12b011000000005e"
receive(buffer1):= "55aa243b740f0090ecffffd9ddffffc90a00004890fdff97440100fb5e95009a12b01100000000ee"
receive(buffer1):= "55aa2440740f00a4ddffff6afcffffa2e6ffff3f99fdffe52e0100316395009a12b01100000000ce"
receive(buffer1):= "55aa2445740f00ce8bffff7cbcffff9bd3ffff267dfdff38480100215c95009a12b0110000000084"
receive(buffer1):= "55aa244a740f0033d9ffff4fe8ffff0e530000c48dfdff70460100f95095009a12b01100000000e0"
receive(buffer1):= "55aa244f740f0086f1ffff935d0000a50e00002573fdffae470100af3995009a12b0110000000082"
receive(buffer1):= "55aa2454740f00e76900009e8affff2ff1ffffe286fdff7b4201004a4195009a12b011000000003e"
receive(buffer1):= "55aa2459740f0030d5ffff7d4100006c080000b69dfdfff34601004f3e95009a12b011000000004d"
receive(buffer1):= "55aa245e740f002fd1ffffc43e000048170000bd93fdffd14d0100a43c95009a12b01100000000b1"
receive(buffer1):= "55aa2463740f0033390000db2000008f0e0000bf79fdff34610100b45d95009a12b01100000000eb"
receive(buffer1):= "55aa2468740f0073cfffff2a6d0000be3d0000e0a5fdff4a3801006b7b95009a12b01100000000cd"
receive(buffer1):= "55aa246d740f00b82600007f28000036e9ffff69a8fdff3c3901006d7595009a12b011000000001d"
receive(buffer1):= "55aa2472740f006eebffff2bedffff74260000287cfdffe04d03901006d765009a11b014000000004d"

五、程序分析:

1)第一步,将接收的buffer转成hex,buffer.toHex(),见上面调试记录的第一组数据

2)通过while循环从接受的缓冲区中搜索所有的以”55aa“开始的数据帧,搜索到之后,将索引号开始的数据帧,后面的80个字符存入buffer1,并且判断buffer1的大小是否为80,用来排除接收的buffer.toHex()中最后搜索到不足一帧的数据(调试记录中"55aa2431740f006968")。

3)将满足80个字符位的数据buffer1存入容器vect1,其中vect1定义:QVectorvect1,连续将所有搜索到的每一帧数据存入容器vect1,并且搜索索引号变更(自加80),从下一帧开始搜索。

  while((index = buffer.toHex().indexOf(buffer0,index))            }
          for(int i=0;i           {
              recvdata[recvnum]=recvdata[i]*16+recvdata[i+1];
             qDebug() << "recvdata:= " <               recvnum++;
           }

....

}

六、小结

1)利用indexOf()从字符串的开始搜索特定的字符串,并通过索引号搜索到完整的数据帧

2)利用容器vect,存放搜索的数据帧

 

 

 

 

你可能感兴趣的:(工业控制,串口通信,qt5)