当前位置:网站首页>QT串口动态实时显示大量数据波形曲线(五)========“最终完美解决版”
QT串口动态实时显示大量数据波形曲线(五)========“最终完美解决版”
2022-07-30 05:45:00 【透明的光】
前言
最近忙着学习linux的嵌入式开发,QT的开发暂时告一段落,所以完美解决的程序也没有编写,现在抽出时间对前面的QT串口动态实时显示大量数据波形程序又加工了下,希望能帮助从事单片机而又不熟悉QT的小伙伴。
先总结下QT的最终感受:
(1)能用别人编写好的模板就用模板,能省下来不少时间;
(2)能用全局变量就用变量,方便。最重要的是能看这篇文章的大部分都是搞单片机的,不是搞嵌入式显示的,所以思维逻辑一时半会也改不过来,按照以前的思维方式比较舒服;
(3)想快速出东西,不用知道具体代码什么意思,知道怎么用就行。QT和while(1)的程序不一样,都是一块一块的,知道一个功能,改吧改吧就行,能输出自己想要的就行。
第一章:程序思路介绍
串口接收程序
此部分分为两部分,(1)数据接收,(2)数据处理。
先说数据接收:20ms接收一次,不管接收多少东西,只要在20ms的特定波特率能接收的最大数据之内就好,也就是能接收到全部数据。直接上程序:
void MainWindow::receive_20ms()
{
int nRxAllLength;
QByteArray recvData;
recvData.resize(256);
uint8_t gnReceiveData[256];
nRxAllLength = m_serial->bytesAvailable();
recvData = m_serial->readAll();
for(int i=0; i<nRxAllLength; i++)
{
gnReceiveData[i] = recvData[i];
}
for(int i=0; i<nRxAllLength; i++)
{
nUartRxBuffer[nUartRxBufHead] = gnReceiveData[i];
nUartRxBufHead++;
if(nUartRxBufHead>=UART_RX_BUF_SIZE) nUartRxBufHead=0;
if(nUartRxBufHead==nUartRxBufTail)
{
nUartRxBufTail++;
if(nUartRxBufTail>=UART_RX_BUF_SIZE) nUartRxBufTail=0;
}
}
}代码功能:接收数据,并且放到一个fifo里面,接收多少,把fifo开大点,接收一个别覆盖原来的数据就行,反正电脑上运行,随便开。如果需要精简内存,那没办法,需要自己算算开多大合适。
再说处理程序:1ms处理一次。为啥1ms,2ms也是可以的,只要比20ms小就行,最好越快处理越好,但是不能处理不过来。
存在问题:1ms在嵌入式里面不是不能正确定时么?差不多就行,1ms左右就行,只要能在短时间内执行就行。不用特别精确的时间,这个自己估量就行。反正线程处理的时间都是大概的时间,不用太在意这个。除非你要非常精确的时间输出或者输入,那没办法。还是直接上程序:
void MainWindow::dealdata_1ms()
{
nUartRxLengthTemp = nUartRxBufHead - nUartRxBufTail;
if( nUartRxLengthTemp < 0 )
{
nUartRxLengthTemp = nUartRxLengthTemp+ UART_RX_BUF_SIZE;
}
switch( nUartRxCtrlMode )
{
case MODE_UARTRXCMD_WAIT:
if(nUartRxLengthTemp >= 2)//报头为两个byte,先检测报头
{
nUartRxHeadCheck = UartRdCharRxBuff();
if(nUartRxHeadCheck == 0x5A) //保证解析的前两个字节时5AA5
{
nUartRxHeadCheck = UartRdCharRxBuff();
if(nUartRxHeadCheck == 0xA5)
{
nUartRxCtrlMode = MODE_UARTRXCMD_FRAME;
}
}
}
break;
case MODE_UARTRXCMD_FRAME:
if(nUartRxLengthTemp >= 14)//数据帧14个字节,根据自己需要变化
{
for (int i=0;i<14;i++)
{
gnUartRxDataBuffer[i] = UartRdCharRxBuff();
}
数据处理程序代码;
gnLatchCnt++;
if(gnLatchCnt == 8)//8个点存储一次,根据需要多少个点显示存储多少次
{
gnUartRxRecDoneFlag = 1;
}
nUartRxCtrlMode = MODE_UARTRXCMD_WAIT;
}
break;
default:
nUartRxCtrlMode = MODE_UARTRXCMD_WAIT;
break;
}
}代码功能:(1)从接收的数据里面寻找报头5AA5,这个根据自己的数据定,只要能找到就行,找不到就抛掉,知道找到开始的5AA5。(2)找到后处理剩余14数据,14是我自己的剩余数据,也就是说每帧数据一共16个字节,前两个是报头,后面的数据是自己需要显示的数据。
注意:这里需要说一个习惯,每次处理数据最好用buffer缓存下,第一个功能防止被覆盖,第二个是可以随时加入其它程序,变换一步最好放入一个新的数组里。
缓存8帧数据(8个点)之后,出来一个flag,用来显示数据标志。这个看你自己想要多少个点显示一次,因为是用串口助手发的数据,所以8个点差不多了,如果用单片机的数据,这个随便改。
波形处理程序
波形处理程序就比较简单了,直接上代码:
void ampshow::dealdata_5ms()
{
if(gnUartRxRecDoneFlag == 1)
{
ui->PLOTVAMP->graph(0)->setData(gvUTCms,gvVsuAmp);
ui->PLOTVAMP->graph(1)->setData(gvUTCms,gvVsvAmp);
ui->PLOTVAMP->graph(2)->setData(gvUTCms,gvVswAmp);
ui->PLOTIAMP->graph(0)->setData(gvUTCms,gvIsuAmp);
ui->PLOTIAMP->graph(1)->setData(gvUTCms,gvIsvAmp);
ui->PLOTIAMP->graph(2)->setData(gvUTCms,gvIswAmp);
ui->PLOTVAMP->replot();
ui->PLOTIAMP->replot();
gnUartRxRecDoneFlag = 0;
}
}
接收里面1ms处理一次,这个5ms更新一次,当flag变化后,这边开始描点,就可以正确显示了。
第二章:效果
先上报文:随便发,5AA5是报头,0001到0008变化是时间,一共8次。后面是显示数据。根据自己的需要自己变化。
5AA50001000100020003000400050006
5AA50002000100020003000400050006
5AA50003000100020003000400050006
5AA50004000100020003000400050006
5AA50005000100020003000400050006
5AA50006000100020003000400050006
5AA50007000100020003000400050006
5AA50008000100020003000400050006效果图:

第三章:测试
用串口助手测试接收数据,试过每次发100个数据,每10ms发一次,串口都可以正确接收。并且可以正确显示。
第四章:写在最后
需要代码的小伙伴可以加公众号,完整代码将放在百度网盘中,可自行下载,如有问题可在公众号中私信,届时会一一解答。

边栏推荐
- 点云统计滤波理解
- 边境的悍匪—机器学习实战:第四章 训练模型
- Based on R language geographic weighted regression, principal component analysis, discriminant analysis and other spatial heterogeneity data analysis
- Arthas 命令解析(jvm/thread/stack/heapdump)
- 标准化(Normalization)知识点总结
- Arthas command parsing (watch/tt/sc)
- Detailed explanation of regular expression syntax and practical examples
- 2021-09-19 集成学习TASK2
- 边境的悍匪—机器学习实战:第二章 端到端的机器学习项目
- DeepLearing4j深度学习之Yolo Tiny实现目标检测
猜你喜欢

配置MMdetection环境并训练

常用损失函数(一):Focal Loss

Simulation of Future Air Pollution Changes Based on Global Model Comparison Program CMIP6 and Regional Climate-Chemistry Coupling Model WRF-Chem

MySQL 5.7 installation tutorial (all steps, nanny tutorials)

Pytorch(一):动态图机制以及框架结构

Rsync realizes folder or data synchronization between Win systems

学生成绩管理系统(C语言版)

MySQL 索引的数据结构及类型

十一、Kotlin进阶学习:1、集合;2、List操作;3、可变集合——MutableList;4、Set;5、Map;6、MutableMap;

Reasons and solutions for Invalid bound statement (not found)
随机推荐
21. Kotlin Advanced Learning: Implementing Simple Network Access Encapsulation
Bubble sort, selection sort, insertion sort, quick sort
【零基础搞定C语言——导航汇总篇】
OpenCV中(rows,cols)与图像(x,y)
边境的悍匪—机器学习实战:第十五章 使用CNN和RNN处理序列
Trust anchor for certification path not found. Exception solution.
Basic application of XMLBean
海量遥感数据处理与GEE云计算技术应用【基础、进阶】
基于全球模式比较计划CMIP6与区域气候-化学耦合模式 WRF-Chem 的未来大气污染变化模拟
Based on R language geographic weighted regression, principal component analysis, discriminant analysis and other spatial heterogeneity data analysis
十八、Kotlin进阶学习:1、挂起函数执行的顺序;2、使用 async 和 await 异步执行挂起函数;3、协程的调度器;4、父子协程;
用户密码加密编码使用 Bcrypt 代替 MD5,SHA1和SHA256
Go简单实现协程池
MySQL data types and footprint
Receive emails from gmail with pop3
第一个WebAssembly程序
生产力工具分享——简洁而不简单
1.03 original Acegi security mechanism
新导则下 防洪评价报告编制方法及洪水建模(HEC-RAS)
【总结】工业检测项目中如何选择合适的损失函数