周末撸了一个串口虚拟示波器,之前用别人开发的经常有bug,而且也不灵活,没有源码什么都改不了,所以决定用一个周末自己开发一个来玩玩,在这个博客里记录一下开发过程,由于之前没玩过QT,写的有些不当的地方烦请指出。
一、需求分析
- 通过串口接收数据,要能同时传输10个通道的数据;
- 10个通道的数据都能实时显示波形曲线,可以打开或关闭任意通道;
- 软件启动后,会自动搜索可用的串口;波特率至少要能满足9600bps、115200bps;默认数据位为8,.无校验位,停止位为1;
- 示波器可以通过暂停键来停止波形的更新;
- 示波器Y轴可以自动缩放,也可以关闭自动缩放功能;
- 可以通过鼠标左键上下左右拖动波形,可以通过鼠标滚轮放大缩小波形,也可以通过右键框选波形进行局部放大;
- 可以选择X轴每页显示的点数,即选择波形移动的速度;
- 在软件界面的选择和配置在关闭软件时可以保存,下次打开软件自动加载这些配置;
- 波形数据可以保存,可以分别保存成图片格式或数据保存到文本文件中;
二、方案设计
软件运行平台主要是windows10,所以刚开始考虑使用C#或者QT,C#相关的图形库比较少,也不能跨平台,所以选择QT。看了几篇帖子,发现QCustomPlot这个QT的开源图形库,小巧简洁,开发起来比较容易,于是去官网下载了QCustomPlot.tar.gz这个包,安装了Qt5.12.11,用Qt Creator作为开发环境。在QCustomPlot.tar.gz压缩包中有几个例子,每个例子都运行看了一下发现有个动态实时数据Plot的例程(如下图),就决定基于这个例程进行修改。
三、开发过程
1. 串口收发数据
首先写一个简单界面(如下图)实现串口收发数据,这个时候需要写一个串口接收界面,互相收发,后面测试也可以用到。串口收发数据很容易,网上教程也很多,比较难搞的是触发ReadData()的信号槽并不是一帧数据触发一次,而是一有数据就会触发,这就导致每次调用readAll()函数读到的数据长度是变化的,这就导致解析通信协议的时候需要做更多的逻辑处理。
2. 动态曲线
利用QCustomPlot提供的接口实现动态曲线的绘制。去官网下载qcustomplot压缩包,解压后有个examples文件夹,打开后提供了5个例程,打开plots例程,plots例程里面提供了21个demo(如下图),其中就包括动态曲线绘制,将setupDemo(10)函数的参数改成10就可以看到动态曲线的效果。
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setGeometry(400, 250, 542, 390);
setupDemo(10);
}
将这个demo的核心代码copy下来就可以实现动态曲线。先用正弦产生曲线数据(如下图),在绘图区动态画出曲线波形。实现了动态曲线,接下来就需要将串口接收到的10个通道数据都画出来。
3. 通信协议
接下来需要制定通讯协议,并进行解析。软件与下位机(嵌入式系统)之间通过串口进行通信,需要一个协议(如下图),包括最多10个float型数据,帧头、帧尾一定有,但是中间的数据个数是不定的,最少一个数据,最多10个,所以通信协议长度是可变的。正是因为长度可变,而且帧尾不是固定的,又因为QT串口库的readAll()不能读取一帧数据,所以需要比较复杂的逻辑处理才能比较稳定的解析这个协议,这里不详细写了。
下位机的协议写成了serial_scope.c和serial_scope.h文件,下位机只需要在工程中加入这两个文件,按照如下方式调用即可:
DataScope_Get_Channel_Data(data1, 1);
DataScope_Get_Channel_Data(data2, 2);
DataScope_Get_Channel_Data(data3, 3);
DataScope_Get_Channel_Data(data4, 4);
DataScope_Get_Channel_Data(data5, 5);
DataScope_Get_Channel_Data(data6, 6);
DataScope_Get_Channel_Data(data7, 7);
DataScope_Get_Channel_Data(data8, 8);
DataScope_Get_Channel_Data(data9, 9);
DataScope_Get_Channel_Data(data10, 10);
int Send_Count = DataScope_Data_Generate(10);
uart1_send_data(DataScope_OutPut_Buffer, Send_Count);
4. 动态绘制通信数据
最后结合上述三个方面:串口收发数据、动态曲线绘制、通讯协议解析,将串口接收的数据绘制成动态曲线(如下图)就基本实现了软件最主要的功能。
5. 帮助文档
还有一些细节功能,比如保存数据、关闭时保存配置、量程自动缩放、拖动曲线和框选放大等,就不一一赘述了。
四、软件发布
- QT Creater中的Debug改成release,再run一遍;
- 在新生成的release文件夹中将.exe文件复制到一个新建的单独的文件夹:release;
- 打开QT命令行,注意如果电脑上装了好几个QT编译环境,那么就需要运行Configure Project里面配置的命令行;
- 在QT命令行中,先用cd命令进入新建的单独的文件夹release的路径,再用命令:windeployqt serial_scope.exe,就发布成功了,所有依赖的动态库都打包到release文件夹了。
版本记录:
在“帮助”里面可以查看软件的当前版本。
v1.0.0 —— 第一次发布的版本
下载链接:https://download.csdn.net/download/u014170067/85256970