解决QT接受串口数据时数据更新不及时,串口数据太多导致程序界面崩溃,串口接收数据过快等问题
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接受串口数据时数据更新不及时,串口数据太多导致程序界面崩溃,串口接收数据过快等问题相关推荐
- 解决 QT 发送 HTTP 请求时遇到 qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed 问题
解决 QT 发送 HTTP 请求时遇到 qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initilization failed 问题 ...
- 解决电脑频繁跳出 “已停止工作,出现了一个问题,导致程序停止正常工作,请关闭该程序“
解决电脑频繁跳出 "已停止工作,出现了一个问题,导致程序停止正常工作,请关闭该程序" 参考文章: (1)解决电脑频繁跳出 "已停止工作,出现了一个问题,导致程序停止正常工 ...
- SQL导入Excel数据时,数字中混有字符将导致数据丢失的解决办法
将EXCEL数据导出的时候如果同一列数据中既有文字,又有数字!读取时一列中要么文字丢失只剩下数字,要么数字丢失,只剩下文字,这是由第一行的数据类型决定的.出现这种问题是由于数据类型不统一造成的. 原来 ...
- TCP程序中发送和接收数据
这里我们来探讨一下在网络编程过程中,有关read/write 或者send/recv的使用细节.这里有关常用的阻塞/非阻塞的解释在网上有很多很好的例子,这里就不说了,还有errno ==EAGAIN ...
- Inno Setup 打包发布exe程序的步骤及注意事项及解决发布后的exe解压后文件都在主目录下导致程序无法正常运行的问题
目录 一.链接.exe文件的.dll动态链接库 1.1.可以利用QT官网提供的工具windeployqt 生成方式见如下: 1.2.使用脚本文件 二.使用绿色汉化版打包小程序inno setup5.5 ...
- java怎么确定数据在区间内_处理数据时,单元格内内容太多无法计数怎么破?...
在职场办公中,处理数据时有时会遇到古里古怪的数据源,比如从系统导出来的或是表哥表弟们录入数据的不规范.从而使得后续处理起来比较棘手.规范数据源很重要! 话不多说,先来看看今天要分享的案例:每个订单下有 ...
- 解决xhtmlrenderer flying-saucer-pdf-itext5 生成pdf时html中table分页内容太多挤到第二页问题。
使用 flying-saucer-pdf-itext5 生成pdf时html中table的行如果太高的话会被挤到第二页展示,导致第一页中空白一大块. 解决办法: 修改org.xhtmlrenderer ...
- 解决远程控制软件在连接时无法正常显示浏览器、视频播放器等软件界面的问题
问题描述 在使用一些远程控制软件(如TeamViewer或者向日葵等)进行远程连接时无法正常显示浏览器.视频播放器.VS等软件的界面,会变成一个白屏或黑屏怎么办? 原因剖析 原因一:笔记本合上盖子关闭 ...
- android代码混淆时,如何防止第三方jar包被混淆导致程序出错
代码混淆是给其他人破解自己的程序带来更多困难,但混淆不能影响我们程序的正常运行.最近在代码混淆时出现一个问题:就是第三方jar被混淆时出现程序错误,错误主要是说找不到相关的类. 这个问题也不奇怪,我们 ...
最新文章
- 开源wkhtmltopdf使用心得 (二)
- ant design vue input change_vue 表单
- IOS - No provisioning profiles with a valid signing identity 一种解决方法
- python教程是用什么博客写的-Python 有哪些好的学习资料或者博客?
- django 快速实现session的操作
- ASP.NET 配置log4net日志功能
- haproxy Consistent Hash浅析
- oracle数据表管理
- Boost enable_if库的测试程序
- 如何做带宽估计和丢包策略
- jquery解析php json,使用jQuery解析PHP Json对象.
- 给函数传递不定关键字的参数 和
- 操作日志和系统日志分类记录
- 可扩展多线程异步Socket服务器框架EMTASS 2.0 续
- 互联网带来的颠覆,改变了传统的营销套路
- linux avi 转mp4,LINUX下有没有像格式工厂一样的媒体转换软件?比如RMVB转AVI 转MP4...
- Mac下如何将 GBK 编码的文档转成 UTF-8 编码的?
- 嵌入式软件算法之卡尔曼滤波基本原理浅析
- 【算法专题】卡特兰数
- MySql数据库记录相差14小时排错,使用Java访问Mysql数据库时出现时区异常的解决方案
热门文章
- 2016年最经典的高仿系列源码打包下载4.84G
- redis指定配置文件启动不生效_Windows Redis默认配置文件,Redis配置不生效解决方案...
- 点、线、三角形(C++)
- TP-LINK路由器如何设置上网
- 19-图片标签注意点
- Ubuntu18.04配置YCM
- Unity 2D光照(2D Light)和阴影(Shadow Caster 2D)
- java计算机毕业设计校友社交系统源代码+数据库+系统+lw文档
- 微信小程序开发的适合领域
- mysql 1213