摘要:相较于传统仪器, 虚拟仪器功能更强、性价比更高、可扩展性更好, 目前已被广泛应用于各个测量、测试行业。论文完成了一种对通电线圈的电磁辐射信号显示分析, 为某型鱼雷的调试检查提供可视化定量分析工具。软件采用面向对象的设计思想来编写, 按照功能划分为5个模块:数据采集模块、数据存储模块、界面控制及显示模块、波形回放模块、波形测量模块, 使用VC++基于对话框的应用程序框架完成了这5个模块的详细设计和实现;通过实际调试, 该虚拟示波器操作简单、测量准确, 能满足使用要求, 同时该示波器具有良好的可扩展性, 完全可根据用户需求实现自定义仪器功能。
关键词:虚拟示波器; VC++; 傅里叶变换; MFC;
Abstract:Compared with traditional instruments, virtual instrument is more powerful, more cost-effective and more scalable.It has been widely used in various measurement and testing fields. A virtual oscilloscope is designed to display and analysis the elec-trified-coils electromagnetic radiation signal in the paper. The virtual oscilloscope is used in a visual quantitative analysis toolwhich can debug and check of a torpedo. Object-oriented design ideas is used to write the system software programs, The system isdivided into five modules:data collection module, data storage module, interface control and display module, waveform playbackmodule, waveform measurement module. The system based on VC++ dialog application framework to complete the detailed design ofthe 5 modules. According to debug, the virtual oscilloscope is easy to operate, accurate to measure, satisfies users requirement. Atthe same time, the oscilloscopes function can be fully realized according to the users requirement, It shows that the instrument hasgood extensibility.
Keyword:virtual oscilloscope; VC++; Fourier transform; MFC;
1、引言
20世纪80年代提出了虚拟仪器的概念, 虚拟仪器以其功能强大、价格低廉、用户可自定义仪器功能等优势得到了迅速发展[1]。虚拟示波器是虚拟仪器的典型应用, 是一种图形显示设备, 通常将外部采集到的数据显示出对应波形, 并对波形进行存储和分析。具体功能可根据用户需求通过安装在上位机上的开发环境自行编写内部源程序、搭建UI界面从而形成完整的软件系统。
本文针对某型鱼雷产品软件调试台的需求, 结合VC++良好的面向对象特性, 基于VS 2010平台下的MFC对话框应用程序开发设计了一个虚拟示波器, 完成了将采集到的数据实时显示、存储、波形回放, 数据分析等功能, 充分利用了虚拟仪器用户可自定义仪器功能的特点, 实现了对某型鱼雷产品的控制和调试。
2、软件设计概要
通过需求分析, 如图1所示, 本软件主要由5个模块构成:数据采集、数据存储、界面控制及显示、波形回放、波形测量。各模块分别完成如下功能:
1) 数据采集模块:将外部采集卡采集的被测信号通过以太网 (UDP协议) 传输至上位机。
2) 数据存储模块:将传输至上位机的数据进行保存, 便于回放和查看。
3) 界面控制及显示模块:根据用户需求设计人机界面, 控制程序执行步骤, 同时完成波形显示功能。
4) 波形回放模块:实现数据的回放, 波形的显示、放大、缩小功能。
5) 波形测量模块:完成波形上感兴趣点的幅值测量、频谱分析。
图1 虚拟示波器模块划分
3、软件各模块设计与实现
3.1、数据采集模块
数据采集卡以10K的采样率采集3个通道的数据, 采集卡每帧保存300个数据点, 将采集到的点通过UDP协议传至上位机, 上位机采用多线程监听的方式进行数据监听, 将每次监听到的数据进行10次拼接后得到单通道1000个点后进行波形绘制。具体实现方式如下:
首先定义计数器变量:UDPAccept Data Count, 并将其初始化为0, 以后每接收到1帧数据时该变量加1, 直至该变量加至10时, 单屏显示数据拼接完毕, 同时将该变量恢复为0, 最后将拼接好的数据传至WM_PAINT消息进行波形绘制。
3.2、数据存储模块
多线程技术是指当一个线程等待I/O完成或需要大量运算时, 另一个线程可以继续其他处理, 使得进程总处于运行状态, 随时进行响应, 从而提高系统的响应效率[2]。本软件利用多线程技术将程序控制和数据存储进行分离, 线程间利用自定义消息进行通讯, 主线程运行的同时, 利用线程监听UDP传输的数据, 进而将接收到的数据写入文件。具体实现过程如下:
首先定义一个数组recv Buf[]用于存储UDP上传的数据, 每接收到1帧数据后发送消息::PostMessage (hwnd, WM_RECVDATA, 0, (LPARAM) recv Buf) 至WM_RECVDATA () 函数进行响应, 在WM_RECVDATA () 函数中利用fopen打开文件后, 利用fwrite函数向文件写入数据完成数据存储。
3.3 界面控制及波形显示模块
如图2所示为显控界面, 该界面主要由三大区域组成:左半部分为波形显示区域、右半部分为信息显示区域、底部为按钮控制区域。其中波形显示区域又分为原始波形显示区域和频谱显示区域;信息显示区域包括通道选择、纵轴最值、调试流程信息、日志回放信息;底部按钮控制区域共7个按钮共同完成软件的控制和调试。
图2 显控界面
3.4、波形回放模块
1) 数据读取
将采样率、通道数等基本参数设定后, 利用fread () 函数进行数据的读取, 读取数据时需解决以下两个问题:
(1) 采样率、通道数、帧数等参数在源程序中多处使用, 当这些参数发生变化时, 如何快速完成在整个程序中的修改;
(2) 当读取的数据文件较大时, 如何实现波形快速、完整的绘制。
针对问题1, 本文采用配置文件 (INI:Initialization File) 来解决。INI文件是Windows的系统配置文件所采用的存储格式, 统管Windows的各项配置, 一般用户就用Windows提供的各项图形化管理界面就可实现相同的配置了[3]。在程序设计过程中经常需要对一些参数进行配置, 且配置完成后需下次启动时仍然有效, 这时INI文件就是一个有效可行的办法, 也就是在Windows初始化文件中保存一些我们的设置, 然后在程序启动时从INI文件中读取相关配置。
INI文件由节、键、值组成。图3为本软件的INI文件, 其中中括号[]内为节, 节下由键和值构成。设置完配置文件后在初始化函数中读取INI文件:
图3 INI文件
针对问题2, 当读取的数据文件较大时 (如Gbit以上) , 直接读取会占用很大的内存, 造成波形绘制缓慢, 这时可人为将信号分帧显示, 例如前1帧显示信号前一万个点, 下一帧显示后一万个点, 以此类推将信号分为不同帧数进行显示。分帧显示可有效解决波形绘制缓慢的问题, 但也引入新的问题:单屏只能显示1帧, 无法看清数据全貌, 导致很难找到信号所在帧。为了能快速、完整地回放波形, 考虑到采集卡采样率较高而波形显示区域仅有900*280像素, 当回放数据量较大的文件时, 多个数据点落在了屏幕上的同一像素点上, 因此可采用抽点降采样的方式绘制波形, 这样不仅能看到波形全貌, 还能实现快速绘制。本文降采样的策略如下:首先使用fread () 函数读出文件长度File_Len, 然后计算出单通道点数:Point_Num=File_Len (文件长度) /Data Channel Num (通道数) ;最后根据单通道点数Point_Num与波形显示区域宽度的比值R决定降采样率:
程序根据文件大小自动选择降采样率后, 将读取的数据传至WM_PAINT消息绘制波形, 从而实现了任何数据大小的文件均可快速、完整地绘制波形。
2) 坐标轴的智能绘制
坐标轴的智能绘制实际上是实现坐标轴根据读取不同文件自动调整横纵坐标最值。以图4 (a) 原始数据波形显示区域横轴为例:首选根据波形显示区域的大小 (本文设定为900*280像素) , 在头文件中定义横轴最大、最小像素值、等分数, 然后将对应等分点所在的屏幕像素在On Paint () 函数中显示出来。具体实现如下:
以相同的方式将纵坐标绘制完成后便实现了坐标轴根据读取文件的不同自动调整幅值、智能绘制。
3) 波形绘制
示波器最基本的功能是实现波形的绘制, 即实现数据的图形化输出[4]。在实现波形快速、完整绘制的基础上, 为方便观测局部波形, 波形的缩放功能必不可少, 在实现波形缩放功能前, 需先了解VC++绘图的原理。
VC++的绘图原理是基于像素点的绘图方式[12], 例如一组数据data[N-1]共N个元素, 最大值为Y_Max Value;欲将这组数据显示在起点为 (5, 10) 、大小为100*50像素的矩形框内, 其实现过程是将数据点对应到显示区域的像素值上, 然后利用MFC的CCient DC类的Move To () 、Line To () 函数实现画线功能。具体实现如下:
如图4 (a) 为应用上述方法绘制的一段时长38.63s的原始数据波形图。
(1) 横轴放大
图4 (a) 中, 在[0, 6.44]和[25.75, 32.19]两个时间段内检测到了有效信号, 但想了解信号的具体细节则需对信号进行局部放大, 即实现波形横轴放大功能。
本文实现横轴放大的方式是:使用鼠标拖动选定放大区域。根据鼠标按下和弹起时的像素点找到对应波形数据起始点和结束点的索引值, 根据索引值重绘波形实现波形的局部放大。局部放大的关键点是找准起始点和结束点的索引值, 寻找索引值时需要根据读取的数据文件长度Len与波形显示区域横轴最大值X_Pixel Max的比值Zoom In_Ratio分情况处理:
Zoom In_Ratio?1表明数据点数不小于绘图区域像素, 绘制时会有多个数据点落在同一像素上;小于1则说明数据点数少于绘图区域像素, 绘制时某些像素上没有像素点。
当Zoom In_Ratio?1时, 多个点落在同一像素上, 拖动鼠标放大时无法确定该像素点所对应的准确点, 为解决上述问题, 本文定义了两个与绘图区域横轴最大像素值X_Pixel Max同样大的数组, 一个用于存放某一像素上首次出现的数据点, 一个用于存放该像素上最后出现的数据点。这样, 当拖动鼠标时, 将鼠标按下On LButton Down () 函数获取像素点对应到数组中首次出现的数据点作为起始点索引值, 将鼠标弹起On LButton Up () 函数获取像素点对应到数组中最后一次出现的数据点作为结束点索引值, 然后根据找到的索引值对应到原始数据文件中重绘波形实现波形的局部放大。
当Zoom In_Ratio<1时, 某些像素点上没有数据点, 拖动鼠标放大时存在该像素点无法找到对应数据点的问题, 为解决上述问题, 本文采用插空补点方式解决。具体实现方式是:计算出某一数据点对应的像素值后, 比较该点对应的像素值与上一个点对应的像素值是否一样, 若不一样, 用该点对应的像素值减去上一点对应的像素值求出中间空出的点数, 然后用该点补全空出点数。
如图4 (b) 所示为图4 (a) 原始数据的局部放大图, 由图可知上述方法实现了将[0, 6.44]时间段内第一次出现信号值的波形进行局部放大, 局部放大后的波形能清晰地知道信号类型、幅值、频率等详细信息。
(2) 纵轴缩放
纵轴的缩放相较于横轴要简单的多, 具体实现只需利用Update Data () 函数将用户输入纵轴编辑框的值赋给波形最大值Y_Max Value即可。当输入值小于Y_Max Value时, Y_Max Value默认不变;当输入值大于Y_Max Value时, 按照输入值更新Y_Max Value后重绘波形即可。如图4 (c) 所示为用户在纵轴编辑框内输入8000.00后对图4 (a) 的缩放结果。
3.5、波形测量模块
根据用户需求, 调试台所需测量的信息包括:信号强度、持续时间、信号频率。本文中通过双击鼠标左键可测出双击处波形的横纵坐标, 纵坐标即为信号的强度;信号持续时间通过双击信号起始和结束处的横坐标之差得到信号持续时间;信号频率通过将信号傅里叶变换后求出频谱, 如图2中左下即为信号的频谱图。
通过鼠标左键双击波形区域得到波形坐标的实现方法如下:首先通过WM_LBUTTONDBLCLK消息捕获双击处的像素值, 然后找到该像素值对应的原始数据中的点, 将其显示出来即可。如图2波形显示区域中深色竖线为根据用户双击处绘制的竖线, 竖线右侧括号内为对应波形上的坐标值, 这样用户想知道波形某点坐标值只需双击该处即可得到对应坐标。
图4 波形绘制
4、结语
本文设计了一个基于VC++的虚拟示波器软件, 该软件可用于某型鱼雷产品调试检查控制, 用于线圈辐射信号显示及分析波形参数。本文采用面向对象的方法对软件功能进行了划分及模块化设计, 经调试表明该虚拟示波器操作简单、运行良好, 实现了数据采集、数据存储、波形显示、参数测量等功能, 同时该软件功能扩展性良好, 用户可根据需求自定义仪器功能, 具有广泛的应用前景。
参考文献
[1]李同立.基于VC++的虚拟示波器软件设计[J].软件导刊, 2013, 11:024.
[2]郑国章, 王盛学, 郝铁生.基于多线程的测控平台虚拟示波器设计[J].机械管理开发, 2007 (5) :68-69.
[3]孙鑫.VC++深入详解[M].北京:电子工业出版社, 2012:1-767
[4]赵雷廷, 吴佐民, 全恒立等.基于以太网的虚拟示波器设计[J].电子设计工程, 2010 (11) :4-7.
[5]邱文涛.虚拟示波器的设计与实现[D].南昌:南昌航空大学, 2015:1-76.
[6]陶登攀.虚拟示波器的设计与实现[D].重庆:重庆大学, 2013:1-57
[7]蔡小伟, 康宝泉, 张开灿.便携式Wi Fi虚拟示波器设计[J].赤峰学院学报:自然科学版, 2016, 32 (11) :29-31.
[8]陈冬冬.浅析虚拟示波器的设计与实现[J].数字技术与应用, 2016 (2) :198.
[9]张逸成, 梁海泉, 等.一种虚拟示波器的设计[J].电子测量与仪器学报, 2007, 2 (2) :104.
[10]王秀芳, 郝建勋.虚拟示波器的设计与实现[J].仪器仪表学报, 2005, 26 (8) :253-254.
[11]冯静亚, 于强, 吕朝晖, 等.虚拟示波器的软件设计与应用[J].计算机工程与设计, 2007, 28 (1) :211-213.
[12]安金鑫, 王军.基于VC++和Lab Windows/CVI的多通道虚拟示波器设计[J].南开大学学报:自然科学版, 2013 (1) :6-11.
[13]张燕霞, 田裕鹏.基于VC和Lab VIEW控件的虚拟仪器设计[J].仪器仪表与分析监测, 2004 (4) :15-17.