自动化测试

LabVIEW 设计模式与分析

2020-08-19  本文已影响0人  刘小白DOER

    笔者利用labview做过几个项目,熟悉串口、网口、仪器仪表等硬件开发和Access、Mysql(mariadb)数据库操作,在明确设备协议后可自主快速搭建所需的功能。关于测控方面,搭建起来很也轻松,除非不清楚设备协议。现在拿到一个项目,第一想的是设计模式,毕竟选择好的设计模式可以大大减少工作量,而且后期更改添加也方便有序。现结合自己做的项目,参考天津大学精仪学院陈世利的精讲LabVIEW设计模式来阐述总结LabVIEW 设计模式,分析自己项目设计的不足,简化开发过程。

    本文列举几个笔者用过通用型设计模式,以及有必要说明一下的小众专用设计模式,因为有时候这种设计模式可以让你节省很多代码,逻辑更加清楚。

1、数据流模式Dataflow Model

     最简单常见的设计模式,依据数据依赖关系从左向右流动,简单点说就是程序从左到右执行。笔者第一次做的项目程序就是数据流模式,对于初学者来说,简单方便。目的是读写485串口实现多台威尔逊发电机采集集中监控,协议是Modbus。当时是利用数组存储命令,然后通过FOR循环结构自动索引隧道依次发送命令到各个发电机。程序从发送命令,接收数据、处理数据,显示数据都是从左到右依次执行。但是有个问题,如果我要响应用户开关机操作,怎么办?

    笔者当时是入门学者,选择事件结构来处理,读取数据放在超时分支里面,不断循环读取设备参数,开关机等操作按钮在另外的分支来响应用户点击操作。出现的问题是点击操作要等到超时分支完成后才能排队实现,超时分支里面命令很多,那开关机就要等很久,特别是写读串口延时设置偏长时。

    如果我需紧急停机呢?那这个模式还能用吗。笔者后来用队列实现这个功能,紧急停机是清除队列里面的元素 。

2、状态机模式State Machine Model

    允许不同的状态,按通过编程决定的顺序进行执行。整个结构就是初始化,状态选择,状态处理,结束。然后在状态选择和状态处理之间循环,响应用户操作,完成每个状态对应的功能。

LabVIEW状态机包含四个基本执行元素:

1、While循环-执行多个迭代直至符合停止条件。

2、条件结构-包含表示状态机每个状态的特殊代码。

3、状态枚举-定义状态机的所有状态。

4、移位寄存器-包含在当前迭代中执行的前一个迭代指定的状态。

    目前笔者没有在实际生产环境中使用过这个模式,这个模式可以用数据流顺序结构来代替,但是整个代码框架就很大。整个可以看看自带例子里面的State Machine Fundamentals,有点“队列”的意思。

    还有个例子是playback.vi,往前往后读读取数据库record,更有参考意义。

    在实际运用中,笔者觉得可以把事件结构改成成状态机来包装一下,逻辑复杂点,这样程序代码在就更加方便布置,各个功能也区分开来。

3、生产者消费者模式Producer-Consumer Model

    建立数据缓冲区来异步执行,缓冲区作为数据存储的中间部分,可以是局部变量、全局变量、共享变量、队列、通知器、信号量、datasocket。不同的是,局部变量只能在同一个面板传递,全局变量、队列、通知器、信号量可以在同一台电脑上传递,也就是同个内存都可以读写。共享变量、datasocket可以在同个局域网内传递数据。

    这个是笔者最近经常使用的模式,用起来很香。要是你在其他平台上,自己建立队列得多麻烦啊,所以虚拟仪器在测控方面太有优势了。

    笔者做过的三个项目都是生产者消费者模式,重点阐述这个模式。

    一是甚高频自动维护测试,读取VHF电台、综测仪、频率计测量VHF参数,操作RS232、Telnet、VISA网口。接口读取设备参数是入队列,出队列就处理解析参数并存储,同时不同功能界面用子面板来分开独立显示。

    二是导航设备和动环监控系统,采集导航设备VOR/DME、充电机、UPS、发电机等,完成设备集中监控和数据采集。方法和甚高频的解决方法一样,不同的是有几个设备通过485串口组成总线,存在资源竞用问题。当时是采用不同设备循环入队列,只是在其他面板出队列时通过枚举来区分,这时同个485串口就分开循环使用。其实还有更好的方法,就是信号量,获取信号量自动帮你解决资源竞争的问题。

    如果要改写,你知道怎么做吗。核心的就是获取信号量可以通过name在不同的子面板来使用。

    三是校飞辅助工具,labview方面采集甚高频语音数据,处理脉冲代码调制(PCM)数据,完成语音数据存储与回放。采集和处理存储是通过队列来分开实现,在回放方面是在另一个线程while里面通过事件结构来响应用户点击wav文件播放。

    最近网络上看到一种模式,三个while循环,两个队列组成的生产者消费者模式。采集、处理、存储在不同的线程,中间有两个数据缓冲区。我的第三个校飞辅助工具可以把回放再用一个队列吗?可能还不好操作,因为我的回放的数据是需要刷新全部数据,再加个队列要传递啥呢。所以采集和处理存储是通过队列实现,回放则再其他while循环里面。你有更好的方法吗?

4、事件驱动模式Event Structure Model

    此模式是用过用户事件结构来实现的。笔者做过导航设备维护测试系统,操作安捷伦示波器完成波形分析(瞬态、脉冲、幅值、频谱)和波形保存与回放。系统都是响应用户点击,平时就是在等待状态,不占用CPU资源。只要需要人机交互,事件结构必不可少。

    那有人要问了,无用条件结构,不断读取布尔变量值或其他数值的改变,不行吗?我只能说你out了,事件结构这么精髓的东西都不用,而且里面分支很丰富哦。笔者和同事做过一个功能,就是快捷菜单里面屏蔽设备告警,大家看看下图,应该选择哪个?在窗格-快捷菜单里面。

5、面对对象编程模式(OOP)

    面向对象就是把相关的数据和方法组织为一个整体来看待,包括数据和方法。在.lvclass里面,控件ctl代表数据,子vi代表方法。鄙人没有用过,测控方面我没有见到过用.lvclass,因为都是流程组织一系列动作,也没有继承等功能。不过可以先看看例子,功能是将数字转为字符串。ctl控件表示数据,write和read是方法,写入和读取数据,data encapsulation.vi调用写和读方法得到结果字符串。

    这个模式有点牵强 ,在基于流程的测控领域,有啥用呢。

    还有后台服务模式,也就是属性设置不显示前面板;程序启动模式,就是显示启动界面并完成一系列初始化动作;代理模式,就是子vi的调用方式,在什么时候调用。其实都是些小功能,算不上一种模式。

    最后说一下功能型全局变量(functional global variable),为了避免竞争机制而实现的一种非重入型子vi。我现在在界面传递数据时大量使用的功能,利用未初始化化的移位寄存器,while循环执行一次来完成数据传递,特别是大数组等数据,不产生数据副本,也避免数据竞争。

上一篇下一篇

猜你喜欢

热点阅读