admin 管理员组文章数量: 1086019
2024年3月28日发(作者:matlab傅立叶)
LabVIEW设计模式汇总
LabVIEW设计模式汇总
本文归纳了LabVIEW中常用的几种设计模式,介绍了各种设计模式的特点及适用范围,
并提供了每种设计模式对应的典型应用实例。
1 标准状态机
1.1简介
状态机(State Machine)是编程中经典的设计模式之一。状态机对系统所有可能的状态
进行罗列,在每个状态分支中执行该状态的代码,并指明系统要执行的下一个状态。状态机
能清晰和准确地完成与状态密切相关的任务。
1.2结构
图1-1为典型的标准状态机结构。系统包含“Initialize”,“Idle”,“Case1”,“Case2”,
“Stop”五个状态;系统可以在“Initialize”中初始化系统参数,在“Idle”中专门做状态
选择处理,“Case1”和“Case2”为用户自定义的状态分支,“Stop”状态使系统停止运行。
图 1-1 标准状态机结构
1.3要点
(1)状态枚举常量
该枚举常量包含了系统所有可能的状态,每次可以选择一个指定的状态。
(2)带移位寄存器的while循环
状态机通过while循环上的移位寄存器传递下一个要执行的状态,每次循环只能执行一
个条件分支。
(3)条件结构
该条件结构的每个分支对应一个系统的可能的运行状态。
Tips:
可以将枚举常量设计为自定义控件类型。当系统状态需要修改时,只需要修改一次“自定义控件”即
可更新整个程序中所有的枚举常量。
将枚举常量连接到条件结构的选择器接线端后,右击条件结构边框,选择“为每个值添加分支”,可
以轻松地为条件结构实现分支配置。
1.4实例
(1)情景:
使用温度监控系统监测当前温度,当温度超过高温阈值时发出“高温警报”,当温度低
于冷冻阈值时发出“冷冻警报”。
1
LabVIEW设计模式汇总
(2)代码:
详见附件中的“标准状态机”项目文件。
图 1-2 前面板设计
图 1-3 程序框图设计
1.5小结
标准状态的应用非常广泛,它的特点是:
(1)系统的所有状态和转换条件都是可以提前预期设定的,而不是随机产生的;
(2)系统一次只能执行一个状态,不适合做并行任务处理。
如何定义状态是其中最关键的因素。状态机的状态要设计全面,指向明确合理。在着手
编程之前,需要先确定系统的状态转移图,检查是否有状态遗漏,各状态执行代码是否均衡
合理,是否方便以后的需求拓展。
虽然标准状态机具有结构简单,设计方便的优点,但由于它要求系统的状态必须是预知
的,且当前状态只能由上一个状态决定。当系统需要人机交互或者其他复杂操作时,标准状
态机则无能为力,还需要采用其他的设计结构。
1.6参考资料与范例
[1] /content/docs/DOC-14959
[2] /content/docs/DOC-22972
[3] /content/docs/DOC-4594
[4]LabVIEW te Machine Test
2
LabVIEW设计模式汇总
2队列消息处理器
2.1简介
队列消息处理器与标准状态机并没有太大区别,不同点在于队列消息处理器是使用数组
(或队列)来储存状态,而标准状态机使用的是自定义枚举控件传递状态。正因为如此,导
致队列消息处理器有以下优势:
(1)通过数组(或队列)添加状态,可以一次性指定多个即将执行的状态;
(2)状态的数据类型更灵活,可以是数据、布尔、字符串等;
(3)使用队列添加状态时,可以在队列消息处理器循环外部向队列中插入状态,改变状态
的执行顺序。
2.2结构
在LabVIEW中通常使用数组或队列实现队列消息处理器,如图2-1所示。前者使用“创
建数组”和“删除数组元素”函数,后者使用“元素入队列”和“元素出队列”函数。
图 2-1 典型的队列消息处理器
2.3要点
(1)使用数组操作函数的队列消息处理器
“创建数组”函数可以向消息数组中一次添加多个消息,“删除数组元素”函数的“已
删除的部分”接线端与条件结构的选择器接线端相连。
(2)使用队列操作函数的队列消息处理器
“元素入队列”函数可以一次向队列中添加多个消息,如果要新加入的消息立即执行,
请使用“队列最前端插入元素”函数添加该消息,而不是普通的“元素出队列”函数。“元
素出队列”函数读出队列中最前端的消息并同时将其从队列中删除。
2.4实例
(1)情景:
使用温度监控系统监测当前温度,当温度超过高温阈值时发出“高温警报”,当温度低
于低温阈值时发出“冷冻警报”,并同时记录该温度值。
3
LabVIEW设计模式汇总
(2)代码:
详见附件中的“队列消息处理器”项目文件。
图 2-2 前面板设计
图 2-3程序框图设计
2.5小结
队列消息处理器与标准状态机非常相似,队列消息处理器同标准状态机一样,需要注意
分支的合理划分。它的特点是:
(1)传递的消息是动态变化的,可以一次添加多个消息;
(2)消息的数据类型更加灵活,可以是数值、布尔、字符串等;
(3)使用队列传递状态消息时,可以在循环外部向队列中插入消息,方便对队列消息处理
器的控制。
2.6 参考资料和范例
[1] /white-paper/14119/en
[2]/93-222758235745274320108mdashm
[3]LabVIEW ue Message
[4]LabVIEW ued Message
4
LabVIEW设计模式汇总
3事件结构
3.1简介
事件结构是LabVIEW中另一种非常重要的设计结构。在事件结构发明之前,系统需要
不断地“轮询”用户事件是否发生,执行效率非常低。事件结构类似于“中断”功能,只有
当事件发生后,CPU才对其进行处理,事件没发生之前,CPU可以执行其他进程或任务。
事件结构能大大节约系统资源,同时也避免了事件遗漏。
3.2结构
事件结构包含五个基本元素。
(1) 事件选择器——指定本分支所处理的用户事件;
(2) 事件数据节点——用于识别事件发生时LabVIEW返回的数据;
(3) 事件过滤节点——只有在过滤型事件分支中才会显示。过滤事件能在LabVIEW处理事
件之前告知用户该事件已发生,使用户可以自定义处理该事件。
(4) 超时接线端——当在规定时间范围内没有任何指定的事件发生,则进入超时分支;
(5) 动态事件接线端——需要与“注册事件”函数配合使用,可以在程序运行时处理由程序
内部指定希望产生的事件。
图3-1 事件结构
3.3要点
(1)事件结构
用来监测所有的用户交互操作。
(2)while循环
为了多次处理事件,事件结构一般要放在while循环中,且一个程序只需要有一个事件
结构。
Tips:
事件分支中的处理程序越快越好。如果在下一个用户交互事件发生时,上一个事件还没有处理完,则
不能及时响应下一个事件。
通常,LabVIEW只有在用户直接与活动前面板交互时才产生用户界面事件。使用共享变量、全局变量、
局部变量、DataSocket时,LabVIEW不生成事件。但使用值(信号)属性可以产生“值改变”事件。
3.4案例
(1)情景:
使用温度监控系统监测当前温度。当点击“开始采集”按钮时,系统采集一次当前温度
5
LabVIEW设计模式汇总
值;当点击“数据分析”按钮时,系统对最近一次的温度值进行分析,根据温度所处范围发
出高温报警或冷冻报警;当点击“停止”按钮时,系统停止。
(2)代码:
详见附件中的“事件结构”项目文件。
图3-2 前面板设计
图3-3程序框图设计
3.5小结
事件结构是LabVIEW中的经典设计结构,适合用户交互事件较多的应用。但事件结构
需要注意的细节也特别多,处理不好很容易发生锁死或错误。事件结构单独使用时只能执行
一些简单的独立事件,我们往往将它应用在其他设计模式中发挥更大的作用。
3.6参考资料与范例
[1]/reference/zhs-XX/help/371361H-0118/lvconcepts/notify_and_filter_events/
[2]/reference/zhs-XX/help/371361J-0118/lvconcepts/using_events_in_labview/
[3] /reference/zhs-XX/help/371361H-0118/lvhowto/hndlstoploopbool/
[4]/reference/zhs-XX/help/371361H-0118/lvhowto/dynamic_register_event/
[5]LabVIEW 2012examplesgeneraltemplatesTop Level
6
LabVIEW设计模式汇总
4事件状态机
4.1简介
事件状态机是将事件结构与状态机结合的设计模式,常用来处理多个用户界面事件。在
LabVIEW启动界面中通过“创建项目”-“简单状态机”得到的设计模板,即为本节所介绍
的事件状态机。
4.2结构
图4-1为典型的事件状态机结构,包含“Initialize”,“Wait for Event”,“User State 1”,
“User State 2”,“Stop”五个状态;其中,系统初始化后会长时间停留在用于监测用户界
面事件的“Wait for Event”分支。当对应的用户事件产生时,系统转向执行对应的处理分
支,执行完毕后返回“Wait for Event”分支。
图 4-1 事件状态机的基本结构
4.3 要点
(1)事件结构分支
事件结构是事件状态机的核心,完成对所有用户交互事件的实时监测。
(2)其他分支
其他分支的执行速率要尽可能快,否则会影响系统对用户交互事件的响应速率。
4.4实例
(1)情景:
使用温度监控系统监测当前温度。当点击“开始采集”按钮时,系统以10Hz的采样率
连续采集50个温度值;当点击“数据统计”按钮时,系统对最近一次的采集数据进行统计,
计算出最高温度,最低温度和平均温度;当点击“数据存储”按钮时,系统将最近一次的采
集数据进行保存,文件名称为用户点击“数据存储”按钮的时间;当点击“数据回放”时,
系统打开文件对话框,用户选择自己感兴趣的记录文件进行回放;当点击“停止”按钮时,
系统停止。
(2)代码:
详见附件中的“事件状态机”项目文件。
7
LabVIEW设计模式汇总
图 4-2 前面板设计
图 4-3程序框图设计
4.5小结
与标准状态机不同,事件状态机的特点是:
(1)主要用于需要响应多种用户事件的系统;
(2)系统长时间处于一个包含事件结构的状态分支中;
(3)状态机一次只能处理一个分支,不适合做并行的事件处理。
事件状态机适用于简单的事件处理。但事件结构与其他条件分支共享一个循环,当系统
在某个条件分支中执行时间较长时,会导致下一次事件响应延迟。另外,对于一个事件发生,
对应处理该事件的条件分支只能运行一次。如果我们希望用户按下“开始采集”按钮后,程
序连续不断地运行“采集”条件分支,则事件状态机无法满足该需求,我们需要使用其他设
计模式来实现。
4.6参考资料与范例
[1] /content/docs/DOC-11192
[2] /reference/zhs-XX/help/371361H-0118/lvhowto/hndlstoploopbool/
[3] LabVIEW 2012examplesgeneraluievents (Full).llbNew Event
8
LabVIEW设计模式汇总
5主从设计模式
5.1简介
主从设计模式由一个主循环(Master)和一个或多个从循环(Slave)组成。该设计模
式将任务分配到多个循环中并行处理,提高了系统效率,体现了LabVIEW支持多线程的优
点。
利用通知器一对多的信息传递特点,主从设计模式常常用来同步控制几个速率不同的并
行循环任务;利用通知器潜在有损的传输特性,可以用来低速执行数据显示,但不适合于数
据记录。
Tip:通知器类似于通信中的广播方式,一点发出消息,其他所有接收点都可以同时接收到,因此特别
适用于一对多的信息传播。通知器操作函数不缓冲已发送的消息,如果消息被发送后没有任何节点在等待,
则当另一消息被发送后数据将丢失,通知器的执行类似于单元素,有损耗的绑定队列。
5.2结构
图5-1为主从设计模式的基本结构,程序上方的while循环为主循环(Master),下方
的循环为从循环(Slave)。主循环通过通知器操作函数控制从循环运行。
图 5-1 主从设计模式的基本结构
5.3要点
(1)一个主循环,多个从循环
多个从循环同时接收主循环的命令控制,但它们的执行速率可以不同。
(2)通知器
只能在主循环内使用“发送通知”函数,从循环内使用“等待通知”函数。
Tip:注意各通知器(或队列)释放引用的时机。如果从循环中的“等待通知”函数还在执行,而其
他程序部分已经释放了该通知器的引用,则会发生错误。
5.4实例
(1)情景:
系统同时监控环境的温度和湿度。当点击“开始采集”按钮时,系统开始同时采集用户
指定个数的温度值湿度值,“开始按钮”的文字说明变为“正在采集”,当采集结束后恢复为
“开始采集”。当点击“退出”按钮时,系统停止运行。
(2)代码:
9
LabVIEW设计模式汇总
详见附件中的“主从设计模式”项目文件。
图 5-2 前面板设计
图 5-3 程序框图设计
5.5小结
由于通知器的“一对多”特性,主从设计模式经常被用来控制几个不同速率的循环。但
由于通知器使用潜在有损的传输机制,如果主从循环的执行速率不同,常常会发生数据丢失
现象。如果需要高速和大量的数据传递,这种设计模式就不太合适,推荐使用生产者和消费
者模式。
5.6参考资料与范例
[1] /content/docs/DOC-29591
[2] /content/docs/DOC-14758
[3]LabVIEW s Data with
10
LabVIEW设计模式汇总
6生产者/消费者(数据)
6.1简介
在生产者/消费者(数据)结构中,生产者不断“生产”数据,通过队列传递给消费者
进行“消费”。该结构的一个突出特点就是队列充当了生产者和消费者循环之间的“缓存”
作用,生产者循环和消费者循环速率可以不同。当生产过剩,缓存区内的数据会越来越多;
当消费过快,缓存区数据会越来越少,当缓存为空时,消费者变为等待状态,直至缓冲区中
出现可用数据。在生产者/消费者(数据)结构中,最常见的问题就是内存溢出,此时需要
提高消费者循环的执行速率或降低生产者循环的速率。
6.2结构
图6-1为生产者/消费者(数据)的基本结构。程序上方的while循环是生产者循环,生
成所需要的数据。程序下方的while循环是消费者循环,完成数据处理。两者通过队列操作
函数完成数据传递。
图 6-1 生产者/消费者(数据)基本结构
6.3要点:
(1)while循环:并行循环充当“生产者”和“消费者”的角色。
事实上,生产者/消费者(数据)模型中,不拘泥于只使用两个循环,根据实际需要,
可以使用多个“生产者”,也可以使用多个“消费者”。但由于消费者从队列中取出元素后会
将原数据从队列中删除,因此多个消费者共存时,消费者消费的将会是不同的数据。因此,
在多个“生产者”或者“消费者”并存时,它们之间的数据传递也会变得复杂,编程时需要
留意。
(2)队列函数:在并行循环结构之间传递数据。
编程者可以灵活使用各个队列操作函数。例如使用“队列最前端插入元素”可以使消费
者接收到最新的数据。
6.4实例
(1)情景:
11
LabVIEW设计模式汇总
使用温度监控系统监测当前温度,系统采样率为100Hz。当温度超过高温阈值时发出
“高温警报”,当温度低于冷冻阈值时发出“冷冻警报”。
(2)代码:
详见附件中的“生产者/消费者(数据)”项目文件。
图 6-2 前面板设计
图 6-3 程序框图设计
6.5小结
在工业应用中,往往需要同时采集和处理大量数据,因此生产者/消费者(数据)设计
模式的应用非常广泛。它的特点是:
(1)多线程同步执行,程序执行效率高;
(2)适合大量的数据流处理。
生产者/消费者(数据)结构并没有涉及人机交互过程,如果需要进行大量的人机交互,
可以采用生产者/消费者(事件)结构。
6.6 参考资料与范例
[1] /content/docs/DOC-14758
[2] /content/docs/DOC-8962
12
LabVIEW设计模式汇总
7生产者/消费者(事件)
7.1简介
生产者/消费者(事件)设计模式与生产者/消费者(数据)设计模式非常类似,区别是
两者处理的对象不同,前者为数据,后者是事件。
在生产者/消费者(事件)结构的生产者循环中,事件结构保持监测前面板产生的用户
交互事件,并将事件信息送入队列;在消费者循环中,根据队列中的事件信息执行对应的处
理操作。相比事件状态机,生产者/消费者(事件)体现了LabVIEW支持多线程的特点,提
高了系统的执行效率。
7.2结构
图7-1为生产者/消费者(事件)的基本结构,由while循环,事件结构和传递事件信息
的队列组成。
图 7-1 生产者/消费者(事件)基本结构
7.3要点
(1)事件结构
专门用来监测所有的用户交互操作。
(2)
while
循环
遵循程序中最好只有一个事件结构的原则,生产者/消费者(事件)结构一般只使用一
个生产者,但可以有多个消费者(需要用到多个队列)。
Tip:推荐使用的循环同步停止方式
当生产者循环监测到用户按下“Stop”按钮时,将“停止”消息写入队列,消费者循环接收到该消息
后转向“停止”分支,在该分支中,程序将“True”传递给循环条件接线端。
7.4实例
(1)情景:
温度监控系统监测当前温度。当点击“开始采集”按钮时,系统开始连续采集50个温
度值,采样率为10Hz;当点击“数据统计”按钮时,系统对最近一次的采集数据进行统计,
13
LabVIEW设计模式汇总
计算出最高温度,最低温度和平均温度;当点击“数据保存”按钮时,系统将最近一次的采
集数据进行保存;当点击“数据回放”时,系统打开文件对话框,用户选择自己感兴趣的记
录文件进行回放;当点击“停止”按钮时,系统停止。
(2)代码:
详见附件中的“生产者/消费者(事件)”项目文件。
图 7-2 前面板设计
图 7-3 程序框图设计
7.5小结
生产者/消费者循环(事件)结构适合需要处理多个用户事件的系统。但该结构也存在
缺点,例如生产者发出一次指令,消费者循环只能运行一次。但在实际的数据采集应用中,
我们更希望生产者发出“开始”指令后,消费者循环能开始连续采集,而不是只采集一段数
据。因此,单一的生产者/消费者(事件)结构也有一定的局限性。
7.6参考资料与范例
[1] /content/docs/DOC-30005
[2] /content/docs/DOC-2145
[3] /content/docs/DOC-14974
14
LabVIEW设计模式汇总
8 混合设计模式
8.1简介
在实际工程应用中,用户的需求往往是多元化的,既需要数据连续采集和处理,同时还
希望系统能及时响应自己的特殊操作。但标准设计模式能实现的功能往往比较单一,要么只
能处理分立的几个事件,要么只能执行不涉及任何用户交互操作的连续数据任务。可见,在
复杂的系统任务中,单一的设计模式已经不能满足需求,我们往往会用到组合了多个标准设
计模式的混合设计模式。
混合设计模式能结合各个设计模式的优点,满足更多的任务需求。但不可避免地,功能
越强大,系统结构也越复杂。本节给出了一种典型的混合设计模式,实现了温度测量系统的
数据采集、存储和分析功能。在LabVIEW自带的项目范例“连续采集与记录”也是一种典
型的混合设计模式,但程序结构较复杂,供感兴趣的读者参考。
8.2结构
本节介绍的一种混合设计模式如图8-1所示。该结构是由一个生产者/消费者(事件)
与两个消息队列处理器组合而成:
图8.1 一种典型的混合设计模式结构
8.3要点
(1)指令中心
程序上方的两个循环组成系统的指令中心,采用生产者/消费者(事件)模式设计,实
现监测用户事件和分配任务命令的功能。
15
LabVIEW设计模式汇总
(2)功能模块
程序下方的两个循环是系统的功能模块,采用消息队列处理器模式设计,完成系统的两
个独立功能。功能模块可以在自身内部产生消息,也可以接收指令中心的消息。
功能模块的设计结构可以多种多样。如果要连续执行,可以采用队列消息处理器,如果
只需要分步骤执行一次,使用标准状态机就可以。
(3)队列(或通知器)
指令中心和功能模块,以及功能模块之间往往有很多数据交流。队列和通知器是两种主
要的数据传递方式,两者的区别是:队列适合“多对一”的传递方式,通知器适合“一对多”
的传递方式,但通知器属于潜在有损的传输机制,不适合用于高速大量的数据处理过程。
8.4案例
(1)情景:
设计温度监控系统,能同时控制连续的温度采集、存储和报警功能,允许用户自由设置
系统参数和查看历史记录文件。
(2)代码:
详见附件中的“混合设计模式”项目文件。
图8-2 前面板设计
图8-3 程序框图设计
Tips:
16
LabVIEW设计模式汇总
队列消息处理器中需要注意的问题
(1)指令中心发出的“停止”命令建议使用“队列最前端插入元素”函数,而不是普通的“元素入队
列”函数,以便立即停止功能模块;
(2)在功能模块的“停止”分支中要执行清除消息队列操作,消除队列中残留的消息(“开始”)影响,
否则循环不会停止。
(3)注意释放队列(或通知器)引用的时机。避免释放队列(或通知)引用之后,还有“元素出队列”
和“等待通知”VI在运行。一般将所有释放引用放在程序最末端执行。
子VI与主VI的数据传递
在子VI的循环内的显示控件不能实时将数据传递到主VI。解决的办法有两种:使用“控件引用”函
数;使用队列。
8.5小结
在实际工程应用中,大多数应用的功能需求都会比较复杂,往往需要结合各种基本设计
模式的特点,通过混合设计模式来实现。
结束语
没有一种万能的设计模式能恰好满足世界上所有的应用需求。因此,编程最重要的不是
编程者的技巧,而是编程者的思路。唯有深入领会各种标准设计模式的设计思想,才能将它
们灵活地运用在各式各样的应用中。
附件:
LabVIEW设计模式汇总-
17
版权声明:本文标题:LabVIEW设计模式汇总 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1711593867a601479.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论