1、问题背景

最近在使用上位机测试传感器接受数据是否正常,发现了很多问题,由于没有系统的学过Qt,用到什么库就学什么库,导致库中的函数很多不清晰,产生了标题中的一系列问题,经过不断的尝试,终于解决上述问题。

之前在做电机测试的时候,由于数据接受不完整,便在将存储数据的语句放在的循环里,在100ms内只要串口有数据就将数据缓存到内存中,解决了此问题。

while(globalPort.waitForReadyread(100))buffer.append(globalPort.readall())
// 数据处理 略写

在测试距离传感器的时候,数据是ASCII类型的,不是16进制类型的,需要的数据在一长串字符串里,从网上查看相关字符串资料,使用字符串的正则表达式将数据提取出来,其他的没多大问题。

// 如果缓冲区有数据,继续读取,没有数据时执行下部操作while (portDist.waitForReadyRead(100))buffer.append(portDist.readAll());// 处理数据if (buffer!=""){data = buffer.trimmed().simplified();QRegularExpression rx("\\d+");                          // 正则表达式QRegularExpressionMatch distance = rx.match(data, 24); // 正则表达式,从第几个字符串开始匹配if(distance.hasMatch())dist = distance.captured(0);                     // 取数据}buffer.clear();

以为这就完了,前面的只是热身,也是由于前面的这些测试,使得在测试角度传感器时产生了诸如标题列出的这些问题,浪费了我大好的时间。

2、软硬件条件

系统:windows10 x64 系统版本:21H1
QT版本:6.1.2
涉及串口的类:QtSerialPort/QSerialPort、QtSerialPort/QSerialPortInfo
传感器:六轴角度传感器
串口参数:9600(20Hz) 一次回传33个字节

3、解决方案

1)串口数据太多导致程序界面崩溃

原因:
当时还仔细算了一下,一次接受大约需要50ms,所以设置了50ms的阻塞等待,可是传感器串口一直有数据,导致程序一直在运行,界面显示也没有数据,串口也不能拖动,自已运行一会后,程序崩溃。尝试过将数据处理的函数放在循环内,可以正常运行,程序输出也有数据,数据也正常,窗口也不能拖动,直到程序运行崩溃。

while (portDist.waitForReadyRead(50))buffer.append(portDist.readAll());

解决:
删除循环就好

2)数据头不正确

第一个问题解决后,还有新的问题。每次接收数据时,数据头不是固定的数据头,正确的应该是传感器的地址,而不是随机的,有的时候需要重复好几次打开关闭串口操作,才能获取到正确的数据。因此需要对报文进行判断,符合要求的报文头,也就是传感器地址,直接进行后续动作,不符合要求的就将第一个报文头剔除掉,一直循环直到报文头正确为止:

buffer.append(portAngle.readAll());
while(!buffer.isEmpty() and buffer.at(0)!=0x55){// 对错误数据进行处理,直到满足要求buffer.remove(0,1);}

3)串口数据更新不及时

原因:使用readAll一次只能读取32字节,通过阅读官方资料查到还有可以读取固定字节的函数read(字节数),因为一个报文段33个字节,每11个字节表示新的数据内容(具体的需要根据传感器的通讯协议),但是经过数据更正后,第一个字段数据的长度就不符合要求,于是代码修改为:

buffer.append(portAngle.read(11)); // 改的行
if(buffer.at(0)==0x55){// 保证数据字段长度if (buffer.size()!=11)buffer.append(portAngle.read(11-buffer.size()));
//        qDebug()<<"缓存:"<<buffer<<"缓存大小:"<<buffer.size();ucRxBuffer = reinterpret_cast<unsigned char *>(buffer.data());   // 不转换使用qbytearray类型也可以angleHandle(ucRxBuffer); // 数据处理// 清空缓冲区buffer.clear();}

经过修改后,数据,显示都没有太大问题了,唯一的问题就是数据显示有延时,需要5-6s中之后才会更新数据,找了很多资料,都不能解决,最后试了试,将接受的字节数改为33(传感器一次回传的字节数),数据就不延迟了,因此推断,之前取11个字节时,由于读的速度等于串口回传的速度(第一次回传33,取11,剩22;第二次回传33,取第一次之后的11个字节,剩44),导致大量的数据存储在内存中,而数据又不会突然消失,最终导致数据显示延迟。

修改代买码:
将上述代码中的11改为33

4) 运行错误,报错

上述解决完后,又发现一个新的问题,也不知道时软件的缘故还是程序不对,read和readAll函数一次能够接受的最大数据为32个字节。尝试使用64位编译器,在程序中再加一个读串口的程序都没有作用,加的第二次读串口的程序根本就没有进去。由于每次接受32个字节,每次都是循环到需要的报文处截止,这就导致有效的数据可能出现在第二次接受的数据中,但是由于不是报文头,程序给剔除掉了。导致每次输出的数据越来越少,到最后程序报错:

于是查阅可不可以读取串口的时候读取两次,结果又发现了一个很神奇的函数bytesAvailable(),通过这个函数,我们为您可以在缓存中的数据达到大于等于33字节的时候再进行读取操作,同时保留补充的字节的语句,终于大功告成了!代码如下:

   if(portAngle.bytesAvailable()>=33){  // 等数据达到要求再进行读取操作buffer.append(portAngle.read(33));while(!buffer.isEmpty() and !(buffer[0]==0x55 and buffer[1]==0x53)){// 对错误数据进行处理,直到满足要求buffer.remove(0,1);}if (buffer!=""){buffer.append(portAngle.read(11-buffer.size())); //补充数据,保证所需字段数据完整ucRxBuffer = reinterpret_cast<unsigned char *>(buffer.data());angleHandle(ucRxBuffer);// 清空缓冲区buffer.clear();}}

后续遇到问题,在更新······

解决QT接受串口数据时数据更新不及时,串口数据太多导致程序界面崩溃,串口接收数据过快等问题相关推荐

  1. 解决 QT 发送 HTTP 请求时遇到 qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed 问题

    解决 QT 发送 HTTP 请求时遇到 qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initilization failed 问题 ...

  2. 解决电脑频繁跳出 “已停止工作,出现了一个问题,导致程序停止正常工作,请关闭该程序“

    解决电脑频繁跳出 "已停止工作,出现了一个问题,导致程序停止正常工作,请关闭该程序" 参考文章: (1)解决电脑频繁跳出 "已停止工作,出现了一个问题,导致程序停止正常工 ...

  3. SQL导入Excel数据时,数字中混有字符将导致数据丢失的解决办法

    将EXCEL数据导出的时候如果同一列数据中既有文字,又有数字!读取时一列中要么文字丢失只剩下数字,要么数字丢失,只剩下文字,这是由第一行的数据类型决定的.出现这种问题是由于数据类型不统一造成的. 原来 ...

  4. TCP程序中发送和接收数据

    这里我们来探讨一下在网络编程过程中,有关read/write 或者send/recv的使用细节.这里有关常用的阻塞/非阻塞的解释在网上有很多很好的例子,这里就不说了,还有errno ==EAGAIN ...

  5. Inno Setup 打包发布exe程序的步骤及注意事项及解决发布后的exe解压后文件都在主目录下导致程序无法正常运行的问题

    目录 一.链接.exe文件的.dll动态链接库 1.1.可以利用QT官网提供的工具windeployqt 生成方式见如下: 1.2.使用脚本文件 二.使用绿色汉化版打包小程序inno setup5.5 ...

  6. java怎么确定数据在区间内_处理数据时,单元格内内容太多无法计数怎么破?...

    在职场办公中,处理数据时有时会遇到古里古怪的数据源,比如从系统导出来的或是表哥表弟们录入数据的不规范.从而使得后续处理起来比较棘手.规范数据源很重要! 话不多说,先来看看今天要分享的案例:每个订单下有 ...

  7. 解决xhtmlrenderer flying-saucer-pdf-itext5 生成pdf时html中table分页内容太多挤到第二页问题。

    使用 flying-saucer-pdf-itext5 生成pdf时html中table的行如果太高的话会被挤到第二页展示,导致第一页中空白一大块. 解决办法: 修改org.xhtmlrenderer ...

  8. 解决远程控制软件在连接时无法正常显示浏览器、视频播放器等软件界面的问题

    问题描述 在使用一些远程控制软件(如TeamViewer或者向日葵等)进行远程连接时无法正常显示浏览器.视频播放器.VS等软件的界面,会变成一个白屏或黑屏怎么办? 原因剖析 原因一:笔记本合上盖子关闭 ...

  9. android代码混淆时,如何防止第三方jar包被混淆导致程序出错

    代码混淆是给其他人破解自己的程序带来更多困难,但混淆不能影响我们程序的正常运行.最近在代码混淆时出现一个问题:就是第三方jar被混淆时出现程序错误,错误主要是说找不到相关的类. 这个问题也不奇怪,我们 ...

最新文章

  1. 开源wkhtmltopdf使用心得 (二)
  2. ant design vue input change_vue 表单
  3. IOS - No provisioning profiles with a valid signing identity 一种解决方法
  4. python教程是用什么博客写的-Python 有哪些好的学习资料或者博客?
  5. django 快速实现session的操作
  6. ASP.NET 配置log4net日志功能
  7. haproxy Consistent Hash浅析
  8. oracle数据表管理
  9. Boost enable_if库的测试程序
  10. 如何做带宽估计和丢包策略
  11. jquery解析php json,使用jQuery解析PHP Json对象.
  12. 给函数传递不定关键字的参数 和
  13. 操作日志和系统日志分类记录
  14. 可扩展多线程异步Socket服务器框架EMTASS 2.0 续
  15. 互联网带来的颠覆,改变了传统的营销套路
  16. linux avi 转mp4,LINUX下有没有像格式工厂一样的媒体转换软件?比如RMVB转AVI 转MP4...
  17. Mac下如何将 GBK 编码的文档转成 UTF-8 编码的?
  18. 嵌入式软件算法之卡尔曼滤波基本原理浅析
  19. 【算法专题】卡特兰数
  20. MySql数据库记录相差14小时排错,使用Java访问Mysql数据库时出现时区异常的解决方案

热门文章

  1. 2016年最经典的高仿系列源码打包下载4.84G
  2. redis指定配置文件启动不生效_Windows Redis默认配置文件,Redis配置不生效解决方案...
  3. 点、线、三角形(C++)
  4. TP-LINK路由器如何设置上网
  5. 19-图片标签注意点
  6. Ubuntu18.04配置YCM
  7. Unity 2D光照(2D Light)和阴影(Shadow Caster 2D)
  8. java计算机毕业设计校友社交系统源代码+数据库+系统+lw文档
  9. 微信小程序开发的适合领域
  10. mysql 1213