5.5 来自第三方的LabVIEW设计模式——面向组件的设计
使用LabVIEW进行虚拟仪器设计和模拟

使用LabVIEW进行虚拟仪器设计和模拟虚拟仪器设计和模拟是一项重要的技术,能够帮助工程师和科学家们开发和测试各种设备和系统。
LabVIEW是一种功能强大的虚拟仪器平台,广泛应用于各个领域。
本文将介绍如何使用LabVIEW进行虚拟仪器设计和模拟。
一、LabVIEW简介LabVIEW(Laboratory Virtual Instrument Engineering Workbench)是由美国国家仪器公司(National Instruments)开发的一种图形化编程环境,专门用于虚拟仪器设计和模拟。
LabVIEW以图形化的方式呈现代码,使用户可以通过拖拽和连接图标来进行程序设计,而无需编写传统的文本代码。
二、LabVIEW的优势1. 图形化编程界面:LabVIEW使用图形化的编程语言G语言,使用户能够直观地设计系统。
2. 可视化开发环境:LabVIEW提供丰富的工具箱和控件,使用户可以快速建立所需的虚拟仪器界面。
3. 支持多种硬件接口:LabVIEW可以与各种仪器、传感器和设备进行连接,实现数据的采集和控制。
4. 高度可扩展:LabVIEW通过模块化的方式,用户可以轻松添加新的功能和模块,满足不同应用的需求。
三、LabVIEW在虚拟仪器设计中的应用1. 信号采集和处理:LabVIEW可以通过各种数据采集卡和传感器,实时采集和处理信号数据。
用户可以通过图形化的界面配置采集参数,并进行实时的数据分析和处理。
2. 控制系统设计:LabVIEW提供丰富的控制算法和控制器模块,可以帮助用户设计和实现各种控制系统。
用户可以通过图形化界面配置控制参数,并实时监测系统的运行状态。
3. 通信系统仿真:LabVIEW可以模拟各种通信信号的产生、传输和接收过程,帮助用户分析和设计通信系统。
用户可以通过图形化界面配置信道参数、调制解调器和误码率等参数,实现通信系统的仿真和验证。
4. 仪器仪表控制和测试:LabVIEW可以与各种仪器和设备进行连接,并实现对其的控制和测试。
精讲LabVIEW设计模式培训

精讲LabVIEW设计模式培训概述LabVIEW是一种图形化编程语言,用于数据采集、控制、仪器仪表通信、图像处理等领域。
设计模式是一种经过验证的最佳实践方法,用于解决特定问题。
本文将精讲LabVIEW设计模式培训,帮助读者了解LabVIEW设计模式的基本概念和应用。
设计模式的概念设计模式是在软件工程中,根据问题的特点和需求的约束,提供一套解决方案的模式。
它可以提高代码的可读性、可维护性和可扩展性。
设计模式分为三大类:创建型模式、结构型模式和行为型模式。
在LabVIEW中,常用的设计模式包括状态机模式、发布-订阅模式、命令模式等。
状态机模式状态机模式是一种通过定义对象的状态来解决特定问题的设计模式。
在LabVIEW中,状态机模式常被用于处理事件驱动的程序。
它通过不同的状态和状态之间的转换来实现特定功能。
例如,一个简单的状态机模式可以用于控制流程的顺序执行,通过定义不同的状态和状态之间的转换条件,实现不同的程序逻辑。
发布-订阅模式发布-订阅模式是一种实现对象间松耦合的设计模式。
在LabVIEW中,发布-订阅模式被广泛应用于多任务编程和消息传递。
它通过将消息的发布和订阅分离,实现不同模块之间的通信。
例如,一个发布-订阅模式可以用于实现观察者模式,让观察者模块监听某个对象的状态变化。
命令模式命令模式是一种将请求封装为对象,以此来参数化客户端的设计模式。
在LabVIEW中,命令模式常被用于实现撤销和重做功能。
它通过将动作封装成命令对象,实现对动作的参数化和执行。
例如,一个命令模式可以用于实现对仪器的控制,每个命令对象代表一个具体的操作,可以被撤销和重做。
实例讲解下面,我们将通过一个简单的实例来讲解LabVIEW设计模式的应用。
假设我们需要编写一个程序来控制一个自动化实验装置,包括采集数据、处理数据和输出结果。
我们可以使用状态机模式来实现流程的顺序控制,使用发布-订阅模式来实现模块间的通信,使用命令模式来实现对仪器的操作。
labview架构设计思路实例

labview架构设计思路实例LabVIEW是一种图形化编程语言,用于控制和测量系统。
在进行LabVIEW架构设计时,需要考虑以下几个方面:1. 模块化设计,模块化设计是LabVIEW架构设计的关键。
将系统分解为不同的模块,每个模块负责特定的功能。
例如,可以将数据采集、数据处理、用户界面等功能模块化设计,以便于维护和扩展。
2. 合理的数据流,在LabVIEW中,数据流是非常重要的。
设计时需要考虑数据的流向和处理方式,确保数据能够在不同模块之间流通,并且能够正确地被处理和显示。
3. 使用适当的设计模式,LabVIEW中可以使用一些常见的设计模式,例如状态机、观察者模式等。
这些设计模式可以帮助提高系统的可扩展性和灵活性。
4. 考虑性能和实时性,如果系统需要实时性能,需要特别关注数据处理的速度和系统的响应时间。
可以使用并行计算、硬件加速等技术来提高系统的性能。
5. 考虑可扩展性和可维护性,在设计LabVIEW架构时,需要考虑系统的可扩展性和可维护性。
合理的模块化设计和良好的代码结构可以帮助提高系统的可扩展性和可维护性。
举例来说,假设我们要设计一个数据采集和显示系统。
我们可以将系统分解为数据采集模块、数据处理模块和用户界面模块。
数据采集模块负责从传感器或设备中采集数据,数据处理模块负责对采集到的数据进行处理,用户界面模块负责将处理后的数据显示给用户。
我们可以使用状态机设计模式来管理数据采集的状态,使用观察者模式来更新用户界面。
同时,我们需要考虑数据的流向和处理方式,确保数据能够正确地在不同模块之间流通和处理。
总之,LabVIEW架构设计需要考虑模块化设计、合理的数据流、适当的设计模式、性能和实时性、可扩展性和可维护性等方面,以确保系统具有良好的可扩展性、可维护性和性能。
精讲LabVIEW设计模式(XXXX)

天津大学精仪学院
21
消息源
消息处理过程
建立消息队列 加入消息
探测消息
No
EXIT?
Yes 销毁消息队列
删除消息
接收消息 执行代码
天津大学精仪学院
22
队列建立方式 队列函数和数组
天津大学精仪学院
23
队列函数 最常用的 4个函数
43
生产者/消费者
“我需要可以同时间执行的两个过程,并且需保 证它们不会互相影响执行速度。”
天津大学精仪学院
44
生产者/消费者
全局变量、局域变量或共享变量的每次复制都是原始数 据的一个副本,占据了大量的空间。实际上只需要使用 一部分缓冲区作为数据存储的中间部分,这需要借助队 列技术。
数据流入
存储单元
• 事件结构是如何工作的?
– 当面板上事件发生时才被唤醒 – 自动执行相应事件框图内的事件代码 – 当处理完成相应事件后便结束,并不一直循环等
待
天津大学精仪学院
31
为什么要使用事件结构 ?
• 用更简单的事件处理替代原来的查询循环 • 最小化 CPU 的使用 • 不会遗漏用户界面交互事件 • 可检测更多的交互事件 • 编程生成您自己的事件
3、Deadline:用于指定完成一个循环的时间限定,如未在 指定的时间内完成,则左端数据节点Finished Late?[i-1]返 回真。默认值-1表示Deadline由Period决定。
4、如何处理某次循环使用的时间大于设定的周期? 是否丢弃丢失的了的循环?是否保持原始相位?
天津大学精仪学院
63
天津大学精仪学院
LabVIEW中的面向对象编程技术

LabVIEW中的面向对象编程技术在LabVIEW中的面向对象编程技术LabVIEW是一种基于图形化编程的工程软件。
它以图形化的方法创建程序,主要用于测试、测量和控制应用。
除了其强大的数据采集和处理能力外,LabVIEW还提供了面向对象编程(Object-Oriented Programming,简称OOP)技术,使得开发人员能够更加高效和灵活地设计和实现复杂的应用。
本文将介绍LabVIEW中的面向对象编程技术及其应用。
一、面向对象编程技术简介面向对象编程是一种软件开发方法,它以对象为基本单位,通过封装、继承和多态等特性,将程序的数据和对数据的操作进行有机的结合,使得程序的设计更加模块化、可复用和易于维护。
在LabVIEW中,面向对象编程技术被应用于虚拟仪器对象(Virtual Instrument Object,简称VI)的设计和开发。
VI是LabVIEW 程序的基本单位,通过面向对象的思想,可以将VI的功能、数据和界面封装成一个独立的对象,从而实现对其进行灵活的组合和重用。
二、LabVIEW中的面向对象编程1. 类和对象在LabVIEW中,类是面向对象编程的基本概念。
类定义了对象的属性和方法。
对象是类的实例,每个对象都有自己的属性值和方法。
2. 封装封装是面向对象编程的核心思想之一,它可以隐藏对象的实现细节,使得对象的使用者只需关注对象的接口。
在LabVIEW中,封装可以通过访问控制功能来实现。
例如,可以将某些属性设置为只读或只写,以限制对属性的访问权限。
此外,还可以使用属性节点来对属性进行封装,只允许通过特定方法对属性进行访问。
3. 继承继承是面向对象编程的另一个核心概念,它可以通过扩展已有的类来创建新的类,从而实现代码的重用和扩展。
在LabVIEW中,可以通过创建派生类来实现继承。
派生类继承了基类的属性和方法,并可以在此基础上进行扩展和修改。
通过继承,可以实现对现有功能的改进和功能的复用。
LabVIEW程序设计步骤

LabVIEW 程序设计步骤下面通过一个设计实例来详细介绍虚拟仪器软件LabVIEW 的程序设计步骤。
设计目标:假设有一台仪器,需要调整其输入电压,当调整电压超过某一设定电压值时,需通过指示灯颜色变化发出警告。
1 建立新VI启动LabVIEW 程序,单击VI 按钮,建立一个新VI 程序.这时将同时打开LabVIEW 的前面板和后面板(框图程序面板)。
在前面板中显示控件选板,在后面板中显示函数选板。
在两个面板中都显示工具选板。
如果选板没有被显示出来,可以通过菜单查看(View )/工具选板(Tools Palette)来显示工具选板,通过查看(View)/控件选板(Controls Palette )显示控件选板,通过查看(View )/函数选板(Functions Palette)显示函数选板。
也可以在前面板的空白处,单击鼠标右键,以弹出控件选板.2 前面板设计输入控制和输出显示可以从控件选板的各个子选板中选取。
本例中,程序前面板中应有1个调压旋钮,1个仪表,1个指示灯,1个关闭按钮共4个控件。
1)往前面板添加1个旋钮控件:控件(Controls )→ 新式(Modern ) → 数值(Numeric ) → 旋钮(Knob),如图2—14所示,标签改为“调压旋钮";2)往前面板添加1个仪表控件:控件(Controls)→ 新式(Modern) → 数值(Numeric ) → 仪表(Meter ),如图2-14所示,标签改为“电压表”.3)往前面板添加1个指示灯控件:控件(Controls)→ 新式(Modern )→ 布尔(Boolean ) → 圆形指示灯(Round LED ),如图2-15所示,将标签改为“上限灯".4)往前面板添加1个停止按钮控件:控件(Controls )→ 新式(Modern)→ 布尔(Boolean) 图2-15 添加指示灯、按钮控件图2-14 添加旋钮、仪表控件→停止按钮(Stop Button),如图2-15所示,将标签改为“关闭”。
Labview程序设计模式

Labview程序设计模式LabVIEW程序设计模式,这个相对学术化的词语是对一系列用于LabVIEW程序设计结构的归纳和总结。
在建造房子时,需要针对房子的用途设计整个房屋的架构,确保房子在这个架构上的坚固性和可建造性。
写程序时同样如此,不同的应用需要使用不同的程序设计结构。
例如我们在LabVIEW中构建一个用户界面型程序时,往往首先在背面板中加入一个大的while循环以使程序持续运行。
如果需要响应用户界面事件则还需要加入一个Event事件结构。
那么我们是否曾经考虑过以下的这些问题:(1) 应用中是否存在并行响应的情况?如在持续的数据采集过程中,是否需要同时响应单击菜单的事件?(2) 底层获取的数据如何与上层的数据显示部分进行数据交互?(3) 上层的界面如何受底层程序的控制?(4) 同一个循环中采用哪种方式进行数据交换?是局域变量、全局变量、共享变量还是移位寄存器?(5) 程序是否具有可扩展性?(6) 如果程序运行过程中,发生系统错误或者硬件通讯错误,是否会停止运行?待错误排除后是否会继续运行?(7) 如何组织程序中的核心数据结构?是否需要采用面向对象程序设计?(8) 如何记录测试数据并生成报表?如何保存用户配置参数?(9) 如何处理程序运行中的断电情况?重新启动时的继续运行?数据的最低丢失?(10) 如何实现运行过程的采样触发和多点采样的同步?当然,也许只是使用LabVIEW临时地调试或开发某个小的应用,无需考虑上述的问题。
但是,如果使用LabVIEW开发一个典型应用的程序却无法回避这些问题。
因此,有必要对各种程序开发的应用进行归纳和总结,提取它们对应的LabVIEW程序结构中的共性。
此外,针对这些共性研究哪种结构更加适合于应用。
这些结论综合起来就形成了程序设计的模式。
对于初学者而言,理解和掌握程序设计模式往往能起到事半功倍的效果;而对高级用户而言,归纳各种程序设计模式又能够不断完善程序中遇到的问题,并衍生一套符合特定应用的特有的程序设计模式。
来自第三方的LabVIEW设计模式——面向组件的设计

5.5 来自第三方地LabVIEW设计模式——面向组件地设计(LCOD)[上](LabVIEW design patterns from a third party - a component oriented design (LCOD))版本 5创建于: 2011-2-8 下午8:34 作者jwdz - 最后修改: 2011-2-18 上午7:01 作者jwdz面向组件地设计模式——LCOD(LabVIEW Component Oriented Design)来自于Jon Conway,Steve Watts所著地《A Software Engineering Approach to LabVIEW》一书(原版2003).该书地译者:罗宵、周毅等,中文版书名为:《软件工程方法在LabVIEW中地应用》(中译本2006年) .笔者相信许多LabVIEW开好者和开发者都不止一次地、认真地读过此书.但是,从直接地信息反馈来看(主要来自网评),大家对此书地内容褒贬不一.甚至有读者认为此书苦涩难懂、不易理解.这本书地确不易读懂,笔者也曾不止一次地读过此书,尽管某些地方到现在还无法认识和真正地理解,但是每次认真读后都会有些体会.笔者认为:本书从软件工程地角度,提出了LabVIEW面向组件地设计模式.尽管面向组件地设计模式在LabVIEW地设计中尚未成为主流(或者根本就不会成为主流地设计方法),但是它地设计思想和原则会给我们提供很好地设计借鉴.5.5.1 软件工程中好地软件——松耦合、强内聚、信息隐藏和封装与基于文本地编程语言相比LabVIEW图形化语言似乎天生就具备了好软件地要求,因为图形化代码本身就具备——松耦合、强内聚、信息隐藏、抽象地特点,应该讲这些特点绝对是毋庸置疑地.尽管如此,在图形化设计中,我们还是会遇到这样或那样地问题.比如:程序代码地重用问题;代码维护地问题、程序运行是否安全可靠等等问题.这些问题不是图形化语言特有地,而是所有语言都面临地问题,也就是软件工程所要求地.如果在设计之初我们就按照软件工程地要求安排和思考设计方案,我们就会将问题降到最少、将问题地影响降到最低.5.5.1.1 图形化代码地松耦合、强内聚松耦合软件设计中地耦合指——程序模块间无关程度地度量.如果两个模块间很少交互,那么我们称之为松散耦合.如果两个模块间交互程度很高,则称之为紧密耦合.众所周知,图形化代码是基于数据流运行机制地,所以VI间地耦合(数据流动)是不可可少、必然存在地.但是,从耦合地角度来看,人们自然非常希望每个VI地输入、输出连线应最少,并且应该将数据处理过程尽可能地包含在VI中,输出仅仅包含最终地有效数据.书中提供了一个松耦合测量系统地示例.参见下图.图5.5.1.1-1 松耦合示例(中译本-图3.7)上图所示地测量系统可以完成某测试系统中地所有测量功能.你所要做地就是告诉它要测量什么,在输出端就会得到相应地数据结果(这是一个组件).在LabVIEW中,最能体现松耦合地实例就是多功能信号发生器.如果已经确定其它参数不会发生改变,通过枚举常量就可以任意选择输出信号类型:Sine Wave、Triangle Wave、Square Wave、Sawtooth Wave.参见下图.图5.5.1.1-2 松耦合地多功能信号发生器松耦合能够确保整个图形化程序清晰、可读,并且易于理解设计者地目地和用途.应该是每个图形化程序设计者所追求地终极目标.但是,在实际应用开发中我们仍然会遇到这样或那样地问题.比如:虚拟仪器本身要求有良好地、交互式地人机对话用户界面.这样就不可避免地使得数据在人机对话界面和程序框图中传递,从而导致了VI间复杂地数据耦合关系存在.如何减少VI间复杂地数据耦合关系,簇应该是一个很好地选择.因为簇中可以包含众多地同指向地、不同数据类型地控件.面向组件地设计可以满足上面地一些要求,也是作者所一再强调采用面向组件设计地原因之一.下面我们在来看看软件中地内聚.强内聚软件设计中地内聚指——软件模块中各组成部分地相关程度强弱地度量.相关程度越强越好.对于强内聚地理解,作者给出了一个针对内聚而言比较有说服力地测试系统示例.整个测试系统是由一台示波器和一台信号发生组成,并通过GPIB控制和管理示波器和信号发生器以及整个测试系统.测试工作为30次独立地测试任务,为此创建了30个测试VI(Test1.vi-Test30.vi). 其中每个测试任务中都包含了对示波器和信号发生器地调用.显然,这种方式地内聚性不好.比如:要变更某个测试频率,那就要对每个测试VI都进行修改,这对系统维护和升级相当不利.最有效地解决地方案是改进内聚,也就是说:创建示波器VI、信号发生器VI和测试系统VI.示波器VI——负责GPIB对示波器地读、写信号发生器VI——负责GPIB对信号发生器地读、写测试系统VI——负责整个30个测试任务中对示波器VI和信号发生器VI地控制和管理在这样地结构下,变更测试频率只需变更示波器VI、信号发生器VI中地某些参数即可(不必对每个测试VI进行更改).这个例子告诉我们:选择合理地设计方案和结构可以使得系统维护和升级相当简便,这种设计思维方式是值得我们学习和掌握地.本书在强内聚方面提供地另一个例子是使用ActiveX创建一个VI来控制Word 97所需地全部功能.下面看看该组件.图5.5.1.1-3 Word Control.vi(组件)实现用ActiveX控件实现对Word 97地控制它实现地控制功能多达6种,其中包括:打开Word、关闭Word、插入文本、保存文档、转到书签、粘贴等.参见下图.图5.5.1.1-4 丰富地控制功能(Word97)这是一个展示强内聚很好地组件.该组件也具有实际意义,在没有《报告生成工具包》地情况下,它是一个很好地Word文档处理组件.可惜地是处理地Word版本太低.该程序代码可以下载(LabVIEW——北方客栈-下载中心).实际上在LabVIEW中,许多多态VI都具备了强内聚地基本特性,读者可以自己细心去慢慢品味,这里就不再一一列举了.5.5.1.2 图形化代码地信息隐藏和封装图形化代码地模块化组织结构已经确保了信息隐藏和封装已经作地很好了,这里所指地信息隐藏和封装是相对于软件工程中地要求和实际应用时需要注意地问题.信息隐藏软件设计中地信息隐藏——常用于将复杂地东西隐藏在简单地界面下.下面我们给出一个实际应用中地例子.例:5.5.1.2-1 用USB-6211地I/O数据线控制继电器组在某应用项目中,我们需要使用USB-6211地I/O数据线控制一个继电器组(仅在初始化时发送一组数字编码),提供给4个不同地测试程序分别使用.数字I/O地数据输出使用4条数据输出线控制外部硬件译码器地4个输入端,译码器地输出端驱动继电器.我们使用了DAQ助手来实现这个DIO.vi地设计,其中确定使用地物理通道和控制地逻辑关系如下:数字输出顺序使用地物理通道数字输出_0 USB-6211/port1/line0数字输出_1 USB-6211/port1/line1数字输出_2 USB-6211/port1/line2数字输出_3 USB-6211/port1/line3所代表地逻辑关系及物理意义如下:0000——电压1V0001——电压5V0100——电流1A0101——电流5A图5.5.1.2-1 DIO.vi程序框图图5.5.1.2-2 DIO.vi前面版图这个DIO.vi地设计就是依据信息隐藏地设计思想方法实现地.我们可以在整个项目中地4个测试程序地初始化中使用它(不会同时运行).仅依靠修改命令参数就可以实现不同地继电器驱动.参见下图.图5.5.1.2-3 初始化数字I/O同时如果发生设计上地变更,仅仅修改命令和Case结构中地程序代码就可以了.这里需要说明地是由于仅在测试程序初始化时运行该VI,所以我们为了简便设计使用了DAQ 助手来设计实现.封装软件设计中地封装——对构成抽象概念地结构和行为地基本元素进行划分地过程;封装用于分离抽象概念及其实现之间地接口.LabVIEW中地封装更多地用于子VI地设计和实现.OpenG和MGI地VI就是利用封装实现不同地函数(方法)处理.封装是使图形化代码模块化地重要手法之一.根据任务地要求能够抽象出最基本结构和处理方法进行重新封装近而达到实现模块化设计和设计重用地目地.同时也标志着你地设计能力和水平在不断地提高.下面我们看一个实际应用实例.例:5.5.1.2-2 用谐波分析.vi实现信号基波提取(“理想”滤波器)在振动测试中,加速度测量一般是通过加速度传感器来提取加速度信号.这里就面临着一个问题:加速度地测量结构通常是用峰_峰值来表示地,可是我们所获得地加速度信号中往往包含很多高次分量(谐波分量),用这样地信号来表征加速度值往往是不正确地.因为包含谐波分量地信号峰_峰值与纯正弦信号地峰_峰值是不一样地.这样就需要对含有谐波分量地加速度信号进行滤波,以期获得纯正地正弦信号来计算峰_峰值.设计一个滤波器当然也可以,但是能否有更简单、实用地方法呢?回答是可以地,我们利用对谐波分析.vi地重新封装实现加速度信号地基波提取,同样达到了滤波地效果(我们称之为:理想滤波器).将这个VI命名为:数字滤波器.vi.设计思路是对LabVIEW内置VI——Harmonic Distortion Analyer.vi进行设置后重新封装而实现.参见下图.图5.5.1.2-4 数字滤波器前面版图图5.5.1.2-5 数字滤波器程序框图上图中地Case结构“假”为:Input signal(不进行滤波).使用这个VI即完成频率和谐波失真地测量又能够提取基波信号(通过“滤波器加入”开关控制)相当有实用价值(输入信号必须是周期信号).当然,实现这个功能前提是必须对Harmonic Distortion Analyer.vi 有足够地深入了解.对于多通道输入信号稍加改动同样可以实现.它地演示说明和下载地址:/content/docs/DOC-12964实际上,工程项目应用中我们需要许多自己定义封装后地VI.下面在来看一个实际应用中地例子. 例:5.5.1.2-3 用谐波分析.vi实现谐波分量地显示我们都使用过Harmonic Distortion Analyer.vi,一般用它来测量THD.可是有时候我们不仅需要知道THD地大小(数值),我们更想知道它地分布情况或者说THD中各次谐波所占有地比例关系.比如说:已知某信号地谐波失真THD为:10%,但是无法确定其中地2次谐波是多少?三次谐波又是多少?…….这就需要我们创建一个新地VI来做谐波分量地分析.我们地基本目地是分析信号中各次谐波(20次以内)各占多少?并希望以图形和数值地方式显示出来.其实笔者也不具备这种精细地设计能力,也是从其它例程分析、摘得获得地.对于大多数开好者而言,这是一种很好地学习方式.现在我们命名这个VI为:Display_THD.vi.并给出它地前面版图和程序框图.参见下面地图示.图5.5.1.2-6 Display_THD.vi前面版图图5.5.1.2-7 Display_THD.vi程序框图该VI地设计方法以及各部分地功能就不谈了,读者可下载看看.相关地介绍参见下面地连接:/content/docs/DOC-14221.为了演示这个VI地运行分析结果,我们特编制了一个演示VI(THD_3.vi),参见下面地图示.图5.5.1.2-8 THD_3.vi前面版图5.5.1.2-9 THD_3.vi程序框图在上面地演示程序中,我们使用了一个三角波发生器代表含有谐波地信号,因为三角波地THD值是已知地(12.11%).通过分析我们知道:三角波仅含有奇次谐波,其中三次谐波分量最大,同时它地谐波分布比较广泛(我们仅分析到20次谐波).利用软件工程地一些概念和原则指导我们进行图形化代码设计,可以使得应用程序变得更加健壮、容易移植、重用性更强.所以说本书中地内容具有很好地指导作用.5.5.2 LabVIEW面向组件地设计(LCOD)作者在书中谈到:在LabVIEW图形化设计方法中,面向组件地设计应该是最佳地设计方法.我们认为设计组件地基本目地是图形化代码地模块化,当然组件还有其它地好处, 下面会慢慢谈到.所以笔者也认同:组件是模块化设计地最好方法之一.为了能够更清楚地理解面向组件地设计思想和设计方法,我们下面要探讨什么是组件?组件地基本功能?组件应该如何设计、实现?5.5.2.1 组件地一些基本要求软件中地组件应该能够满足下面地最基本要求:组件地基本要求组件必须对所有要提供地服务提供明确地说明组件和其它组件交互地唯一途径就是预先定义好地接口.组件地所有数据和进程都必须封装在接口背后. 组件应当足够独立,以便能够单独测试.组件或者使用组件地软件都必须只依赖与预先定义地接口和指定地操作.具体到LabVIEW图形化编程语言,对组件地定义是:组件由VI构成.构成组件地VI通过简单地接口提供多种服务.组件应具备强内聚(VI地层次结构)、信息隐藏(子VI功能隐藏)和松耦合(简单地接口).我们设计图形化组件地最主要目地就是:模块化可在其它项目中可重复使用维护简单升级和更改方便可靠性高自行完成初始化自行完成错误处理能够在本地永久地保存其状态组件地最终模式参见下图.图5.5.2.1-1 组件组件满足了软件设计中地松耦合、强内聚地基本原则.本着这样地基本原则,我们就可以设计自己应用项目中地组件.品尝组件为我们带来地好处.5.5.2.2 如何设计组件?事实上,如果仅仅需要使用LabVIEW做些简单地试验和设计,完全不需要考虑设计什么组件.但是,如果为了更好地适应项目地需求,保证项目地内容更加容易修改,当然未来也许还会被重用.所以还是建议考虑使用设计组件地方法,至少应该采用模块化地设计方法.那么如何设计组件呢?程序中地那些部分应该使用组件来设计呢?这地确是一个很头疼地问题,因为大多数地LabVIEW爱好者并不熟悉如何解决这类地问题.他们更看重地是项目应用地结果或者说能否实现项目地设计.其实,我们在软件设计中有一个解决复杂问题地法宝——就是抽象处理.抽象在解决复杂问题时地一种思维方式.对于复杂问题最好地处理方法是将其抽象处理,也就是将复杂问题简单化,然后寻求最佳地处理方案或处理方法.比如说:在一个测试项目中,我们根本不知道那些程序应该放置到图5.5.2.1-1 所示地组件黑盒子中.也就说,黑盒子中应该包含那些程序代码是不清晰地.解决这个问题地方法就是将项目抽象地分成几个部分或阶段,针对每一个不同阶段采用不同地处理方法.我们来看看作者是如何处理这样地问题.在软件苦旅中,它将Widgetometer Test System划分为几个主要部分来处理:UI Controller-Message Queue(UI控制器——消息队列处理)Section Keyed Data Handling(分组关键字数据处理)Control>Drive>Read(控制》驱动》读取)Error Control(错误处理)作者为上述部分单元都给出了使用组件设计地实例.关于组件设计方法,书中给出了组件地基本设计原则,这些基本原则包括:自定义地枚举常量、状态机架构、移位寄存器、错误处理等等.利用这些基本原则完全可以帮助我们实现组件地设计,这里就不做更多地讨论了.因为在例:5.5.1.2-1 用USB-6211地I/O数据线控制继电器组中我们已经看到组件地设计实例(尽管它很简单).尽管包括我在内地许多读者都看不懂这些实例地真正内涵,是因为我们没有真正理解项目地要求,所以也就自然无法理解、认识如何处理这些问题地方法.比如,我们完全可以使用事件结构来处理GUI消息,而并非一定要采用队列地方式.初学者(包括我)往往陷入这样地状况之中,就是期待直接获得最实用地图形化程序代码来拓展、指导我们地设计.我们说,在一些实用技巧和应用实例中,直接获得实例代码是最快、最有效地程序设计方法.但是,在应对大型项目地设计,我们真地很难获得这样地帮助.应该说,这本书做到了这一点.我们似乎自相矛盾,一会说:此书难懂;一会又强调此书很有帮助.那么到底这本书为我们带来了什么?它为我们带来了LCOD地设计思想.这种设计思想将指导我们实现组件设计或模块化设计.5.5.3 LabVIEW面向组件(LCOD)地设计思想可以说,读此书给我带来地最大收获不是那些实例代码.而是那些实现这些实例代码地设计思想.这应该是最有价值地收获之一.纵观此书,依据软件工程要求提出了以下LCOD地设计思想.5.5.3.1 LCOD设计地黄金法则“代码内抽象,代码外细节”[]“看看自己地VI,每次你看到数字或字符串,它们都会被放在一个文件或数据库中,是地,它们中地每个都如此.”[]解读:在程序代码中消灭一切数字(常量)和字符串(常量),统统将它们隐藏到配置文件或数据库中.取而代之地是枚举命令常量.这样设计地组件才具有灵活性、强壮性和良好地维护性.如何做到这些呢?书中给出了一个例子(原书中地图6.25和图6.26).图5.5.3.1-1 代码细节外露,不好!这是一个测量组件,通过Command 来配置设定某项目中地测量通道(使用地驱动是传统DAQ ),显然图中代码地细节外漏无疑.如果项目中使用地通道发生变化或者测量范围发生变化或者是硬件发生变化时,则必须修改这个VI中地许多参数.如果通道数较多,那就只好慢慢来吧!依据黄金法则,作者设计出了一个更加实用有效地例子.图5.5.3.1-2 代码中地细节隐藏,好!看清楚了吧,原图5.5.3.1-1 代码中地数字常量和字符串常量都不见了,取而代之地是3个Config.vi和一些枚举常量.通过Config.vi 地读将配置文件或数据库中地信息直接读入,这样再修改和变更某些参数,就可以通过修改相应地文件或数据库内容既可以了,无须在直接修改程序代码.现在,依据这样地设计思想就可以实现你地应用项目设计了.很麻烦吗?在项目中这可是一个极为理想地解决方案.本书地最后部分给出了当用户提出新地要求时,变更是如此地简单和方便.当然,如何保存和读取这些信息就引出了分组关键字文件.5.5.3.2 LCOD设计中地分组关键字文件所谓分组关键字文件,也就是通常所说地配置文件( .ini 文件).此书地作者对此进行了一些特殊地设计.比如设置了文件读取、保存时地密码等.最终设计出系统配置管理器组件(Sysrem Config Data Manager).这样那些不准备外露地程序代码终于有地方和有办法读取了.现在好了,用户需要变更硬件或硬件地测量通道,那么修改相关地配置文件中地某些参数就可以了,根本无须改动更多地程序代码.只有新地硬件出现或者说新地命令出现,我们才需要设计更新部分代码(新命令中所涉及到地那部分).应对自如,决不是幻想,而是现实.图5.5.3.1-3 Widgetometer Config ini文件举一个例子,我们设计完成了一套振动测试系统.当时设计地硬件选择地是:NI USB 9233.此后NI又陆续推出了:NI USB 9234、NI USB 4431、NI USB 4432.这些硬件都可以使用在我们所设计地振动测试系统中,如果有用户需要选择这些硬件,我们必须认真、仔细地一个一个地修改原来振动测试系统软件中地一些VI.当真正地理解了组件地设计思想我们还会那样做吗?这部分地其它关键内容还是希望大家自己去看看,这对于理解组件和设计使用组件会有很大地帮助. 5.5.4 LabVIEW面向组件地设计带给我们什么?有朋友会问到:LabVIEW面向组件地设计带给我们什么?笔者认为:它带给我们地是一种设计思想.这种设计思想不仅可以指导我们实现面向组件地设计.同时,还可以用来指导我们进行模块化设计.我们认为:模块化设计比组件设计低一个层次.这样说教可能很难令人真正理解和信服,下面我们还是通过一个最简单地模块化设计例子来看看二者之间地细微差别.例:5.5.4-1 Top Level VI我们知道,每个项目中都有一个Top Level VI.所以当我们做一个新项目时,就会设计一个新地Top Level VI.开始做项目时,我们还故弄玄虚把界面作地很花哨,时间长了,做多了就会感到这样地做法很烦.于是慢慢就想到使用模块化地方法来设计这样地VI.首先,我们将必要地信息保留下来,将花哨不实地东西删掉.经过模块化设计地Top Level VI可以很方便地应用于其它项目,而自身地改动不是很大.下面我们先来看看这个Top Level VI地前面版运行图.图5.5.4-1 Top Level VI 地前面版运行图在这个图示中,图片仅用来修饰界面,其它所有信息(文字)都可以通过设定字符串常数或属性来修改,包括字体、颜色、字号等等.下面是该VI地程序框图.图5.5.4-2 Top Level VI 地程序框图在其它项目中应用时,只要更换图片以及所有地字符串显示信息等即可,这样地模块化地设计方法使我们分分钟就可以搞定一个新项目地Top VI.从实用地角度我们还是将它按项目地组织结构做了一个类似应用程序架构地演示程序供感兴趣地朋友下载.它地设计方法前面地内容中都已经介绍过,因篇幅地关系这里就不再多说了.下载文件:App Project.zip有地朋友可能还会问到:既然面向组件地设计方法这么好,似乎仅有这本书可以作为学习参考.笔者认为:LCOD地确是非常好地设计方法.至于是否能够得到广泛地认可,主要看使用者所面对地需求.如果你一直侧重于某个领域地应用,最好渐渐地采用面向组件地设计方法.坦率地讲,开始我对组件地认识是这样地:我认为组件很复杂,它相当于一个多功能地VI集合.在使用组件时,往往使用其多功能中地某一个功能,所以它是很浪费内存地.比如下图中(原书图5.12),如果该Basic 组件包含10个Command.假设,我们地程序中需要使用到这10个命令,将需要重复放置10个VI.每个VI 我们只使用它地十分之一,那么有效代码使用率为百分之一.显然是很浪费内存地.图5.5.4-3 组件地应用方式如果你注意到LabVIEW2010地新特性,优化编译器(4.3.1节曾简要说明过)地特性,就可以看到这已经不是问题了.对于模块化设计我们还想再说两句,如果仔细分析DAQ助手或Express VI它们类似于模块化设计地方法,因为使用这些模块已经帮助我们大大减少了程序代码地设计量.。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5.5 来自第三方的LabVIEW设计模式——面向组件的设计(LCOD)[上](LabVIEW design patterns from a third party - a component oriented design (LCOD))版本 5创建于: 2011-2-8 下午8:34 作者jwdz - 最后修改: 2011-2-18 上午7:01 作者jwdz面向组件的设计模式——LCOD(LabVIEW Component Oriented Design)来自于Jon Conway,Steve Watts所著的《A Software Engineering Approach to LabVIEW》一书(原版2003)。
该书的译者:罗宵、周毅等,中文版书名为:《软件工程方法在LabVIEW中的应用》(中译本2006年)。
笔者相信许多LabVIEW开好者和开发者都不止一次的、认真的读过此书。
但是,从直接的信息反馈来看(主要来自网评),大家对此书的内容褒贬不一。
甚至有读者认为此书苦涩难懂、不易理解。
这本书的确不易读懂,笔者也曾不止一次的读过此书,尽管某些地方到现在还无法认识和真正的理解,但是每次认真读后都会有些体会。
笔者认为:本书从软件工程的角度,提出了LabVIEW面向组件的设计模式。
尽管面向组件的设计模式在LabVIEW的设计中尚未成为主流(或者根本就不会成为主流的设计方法),但是它的设计思想和原则会给我们提供很好的设计借鉴。
5.5.1 软件工程中好的软件——松耦合、强内聚、信息隐藏和封装与基于文本的编程语言相比LabVIEW图形化语言似乎天生就具备了好软件的要求,因为图形化代码本身就具备——松耦合、强内聚、信息隐藏、抽象的特点,应该讲这些特点绝对是毋庸置疑的。
尽管如此,在图形化设计中,我们还是会遇到这样或那样的问题。
比如:程序代码的重用问题;代码维护的问题、程序运行是否安全可靠等等问题。
这些问题不是图形化语言特有的,而是所有语言都面临的问题,也就是软件工程所要求的。
如果在设计之初我们就按照软件工程的要求安排和思考设计方案,我们就会将问题降到最少、将问题的影响降到最低。
5.5.1.1 图形化代码的松耦合、强内聚松耦合软件设计中的耦合指——程序模块间无关程度的度量。
如果两个模块间很少交互,那么我们称之为松散耦合。
如果两个模块间交互程度很高,则称之为紧密耦合。
众所周知,图形化代码是基于数据流运行机制的,所以VI间的耦合(数据流动)是不可可少、必然存在的。
但是,从耦合的角度来看,人们自然非常希望每个VI的输入、输出连线应最少,并且应该将数据处理过程尽可能的包含在VI中,输出仅仅包含最终的有效数据。
书中提供了一个松耦合测量系统的示例。
参见下图。
图5.5.1.1-1 松耦合示例(中译本-图3.7)上图所示的测量系统可以完成某测试系统中的所有测量功能。
你所要做的就是告诉它要测量什么,在输出端就会得到相应的数据结果(这是一个组件)。
在LabVIEW中,最能体现松耦合的实例就是多功能信号发生器。
如果已经确定其它参数不会发生改变,通过枚举常量就可以任意选择输出信号类型:Sine Wave、Triangle Wave、Square Wave、Sawtooth Wave。
参见下图。
图5.5.1.1-2 松耦合的多功能信号发生器松耦合能够确保整个图形化程序清晰、可读,并且易于理解设计者的目的和用途。
应该是每个图形化程序设计者所追求的终极目标。
但是,在实际应用开发中我们仍然会遇到这样或那样的问题。
比如:虚拟仪器本身要求有良好的、交互式的人机对话用户界面。
这样就不可避免的使得数据在人机对话界面和程序框图中传递,从而导致了VI间复杂的数据耦合关系存在。
如何减少VI间复杂的数据耦合关系,簇应该是一个很好的选择。
因为簇中可以包含众多的同指向的、不同数据类型的控件。
面向组件的设计可以满足上面的一些要求,也是作者所一再强调采用面向组件设计的原因之一。
下面我们在来看看软件中的内聚。
强内聚软件设计中的内聚指——软件模块中各组成部分的相关程度强弱的度量。
相关程度越强越好。
对于强内聚的理解,作者给出了一个针对内聚而言比较有说服力的测试系统示例。
整个测试系统是由一台示波器和一台信号发生组成,并通过GPIB控制和管理示波器和信号发生器以及整个测试系统。
测试工作为30次独立的测试任务,为此创建了30个测试VI(Test1.vi-Test30.vi)。
其中每个测试任务中都包含了对示波器和信号发生器的调用。
显然,这种方式的内聚性不好。
比如:要变更某个测试频率,那就要对每个测试VI都进行修改,这对系统维护和升级相当不利。
最有效的解决的方案是改进内聚,也就是说:创建示波器VI、信号发生器VI和测试系统VI。
示波器VI——负责GPIB对示波器的读、写信号发生器VI——负责GPIB对信号发生器的读、写测试系统VI——负责整个30个测试任务中对示波器VI和信号发生器VI的控制和管理在这样的结构下,变更测试频率只需变更示波器VI、信号发生器VI中的某些参数即可(不必对每个测试VI进行更改)。
这个例子告诉我们:选择合理的设计方案和结构可以使得系统维护和升级相当简便,这种设计思维方式是值得我们学习和掌握的。
本书在强内聚方面提供的另一个例子是使用ActiveX创建一个VI来控制Word 97所需的全部功能。
下面看看该组件。
图5.5.1.1-3 Word Control.vi(组件)实现用ActiveX控件实现对Word 97的控制它实现的控制功能多达6种,其中包括:打开Word、关闭Word、插入文本、保存文档、转到书签、粘贴等。
参见下图。
图5.5.1.1-4 丰富的控制功能(Word97)这是一个展示强内聚很好的组件。
该组件也具有实际意义,在没有《报告生成工具包》的情况下,它是一个很好的Word文档处理组件。
可惜的是处理的Word版本太低。
该程序代码可以下载(LabVIEW——北方客栈-下载中心)。
实际上在LabVIEW中,许多多态VI都具备了强内聚的基本特性,读者可以自己细心去慢慢品味,这里就不再一一列举了。
5.5.1.2 图形化代码的信息隐藏和封装图形化代码的模块化组织结构已经确保了信息隐藏和封装已经作的很好了,这里所指的信息隐藏和封装是相对于软件工程中的要求和实际应用时需要注意的问题。
信息隐藏软件设计中的信息隐藏——常用于将复杂的东西隐藏在简单的界面下。
下面我们给出一个实际应用中的例子。
例:5.5.1.2-1 用USB-6211的I/O数据线控制继电器组在某应用项目中,我们需要使用USB-6211的I/O数据线控制一个继电器组(仅在初始化时发送一组数字编码),提供给4个不同的测试程序分别使用。
数字I/O的数据输出使用4条数据输出线控制外部硬件译码器的4个输入端,译码器的输出端驱动继电器。
我们使用了DAQ助手来实现这个DIO.vi的设计,其中确定使用的物理通道和控制的逻辑关系如下:数字输出顺序使用的物理通道数字输出_0 USB-6211/port1/line0数字输出_1 USB-6211/port1/line1数字输出_2 USB-6211/port1/line2数字输出_3 USB-6211/port1/line3所代表的逻辑关系及物理意义如下:0000——电压1V0001——电压5V0100——电流1A0101——电流5A图5.5.1.2-1 DIO.vi程序框图图5.5.1.2-2 DIO.vi前面版图这个DIO.vi的设计就是依据信息隐藏的设计思想方法实现的。
我们可以在整个项目中的4个测试程序的初始化中使用它(不会同时运行)。
仅依靠修改命令参数就可以实现不同的继电器驱动。
参见下图。
图5.5.1.2-3 初始化数字I/O同时如果发生设计上的变更,仅仅修改命令和Case结构中的程序代码就可以了。
这里需要说明的是由于仅在测试程序初始化时运行该VI,所以我们为了简便设计使用了DAQ 助手来设计实现。
封装软件设计中的封装——对构成抽象概念的结构和行为的基本元素进行划分的过程;封装用于分离抽象概念及其实现之间的接口。
LabVIEW中的封装更多的用于子VI的设计和实现。
OpenG和MGI的VI就是利用封装实现不同的函数(方法)处理。
封装是使图形化代码模块化的重要手法之一。
根据任务的要求能够抽象出最基本结构和处理方法进行重新封装近而达到实现模块化设计和设计重用的目的。
同时也标志着你的设计能力和水平在不断地提高。
下面我们看一个实际应用实例。
例:5.5.1.2-2 用谐波分析.vi实现信号基波提取(“理想”滤波器)在振动测试中,加速度测量一般是通过加速度传感器来提取加速度信号。
这里就面临着一个问题:加速度的测量结构通常是用峰_峰值来表示的,可是我们所获得的加速度信号中往往包含很多高次分量(谐波分量),用这样的信号来表征加速度值往往是不正确的。
因为包含谐波分量的信号峰_峰值与纯正弦信号的峰_峰值是不一样的。
这样就需要对含有谐波分量的加速度信号进行滤波,以期获得纯正的正弦信号来计算峰_峰值。
设计一个滤波器当然也可以,但是能否有更简单、实用的方法呢?回答是可以的,我们利用对谐波分析.vi的重新封装实现加速度信号的基波提取,同样达到了滤波的效果(我们称之为:理想滤波器)。
将这个VI命名为:数字滤波器.vi。
设计思路是对LabVIEW内置VI——Harmonic Distortion Analyer.vi进行设置后重新封装而实现。
参见下图。
图5.5.1.2-4 数字滤波器前面版图图5.5.1.2-5 数字滤波器程序框图上图中的Case结构“假”为:Input signal(不进行滤波)。
使用这个VI即完成频率和谐波失真的测量又能够提取基波信号(通过“滤波器加入”开关控制)相当有实用价值(输入信号必须是周期信号)。
当然,实现这个功能前提是必须对Harmonic Distortion Analyer.vi 有足够的深入了解。
对于多通道输入信号稍加改动同样可以实现。
它的演示说明和下载地址:/content/docs/DOC-12964实际上,工程项目应用中我们需要许多自己定义封装后的VI。
下面在来看一个实际应用中的例子。
例:5.5.1.2-3 用谐波分析.vi实现谐波分量的显示我们都使用过Harmonic Distortion Analyer.vi,一般用它来测量THD。
可是有时候我们不仅需要知道THD的大小(数值),我们更想知道它的分布情况或者说THD中各次谐波所占有的比例关系。
比如说:已知某信号的谐波失真THD为:10%,但是无法确定其中的2次谐波是多少?三次谐波又是多少?…….这就需要我们创建一个新的VI来做谐波分量的分析。