labview项目实例_labview操作者框架

0.引言

操作者框架适合于多并行任务的项目。在这样的项目中,多个并行任务之间往往需要相互通信,传统的解决办法是,每个任务一个队列,一个while循环,多任务项目需要在一个程序框图使用多个while,不好看。NI说使用Actor Framework能够避免锁死,竞争,增大代码重用度。NI官方论坛上有一个例子,写的很好。

80993595bacf8e7334a8757799dc2e81.png

如上图,这是一个反馈式蒸发器,通过不断向室内吹送水蒸气以达到降温目的。它主要由水位传感器,温度传感器,水箱,水阀,水泵,风扇,海绵组成。原理如下:读取水位,水位过低时,打开水阀向水箱中放水;水位过高时关闭水阀。同时,读取室内温度,温度过高时,打开水泵向海绵上抽水,等海绵吸满水后,打开风扇,向室内鼓风,干燥的风经过湿透的海绵,成为温度较低的湿润的风,以此来降低室内温度;温度过低时,关闭水泵。

项目需求:

  1. 控制水位。过低打开水阀,过高时关闭水阀。
  2. 控制温度。过高时,打开水泵,等一会,再打开风扇。过低时,关闭水泵。
  3. 在界面上显示温度,水泵,风扇状态。
  4. 允许在界面上改动温度限制。
  5. 系统中总共使用两个风扇,一个坏时另一个自动启用。
  6. 系统可以脱离界面运行。

有点小复杂。

解决方案:

系统需要4个模块:

UI(Cooler UI with Events.lvclass)

冷却模块(Cooler.lvclass)

水位控制模块(Water Level.lvclass)

风扇控制模块(Dual Fan.lvclass)

其中冷却模块是主模块,与风扇控制模块和水位控制模块组合关系,和UI模块是关联关系。(PS:Cooler需要负责Dual Fan和Water Level的启动和释放,Cool通过动态事件和Cooler Panel交互),每个模块为一个Actor。

c65dfc742b21362d09a83473c6e6d83a.png

冷却模块(Cooler.lvclass)),水位控制模块(Water Level.lvclass),风扇控制模块(Dual Fan.lvclass)都需要轮询,Dual Fan轮询有没有风扇坏掉了,Water Level轮询水位,Cooler轮询温度。所以写个Timed Loop Controller.lvclass,哪个操作者需轮询要直接从它继承就可以了。继承使代码复用度提高了。

同理,水位控制模块(Water Level.lvclass),风扇控制模块(Dual Fan.lvclass)还有相似的逻辑——超过限位就打开或关闭。写个Level Controller.lvclass作为这两个操作者的父类,因为labview中一个孩子只能有一个父亲,所以Level Controller.lvclass需要继承自Timed Loop Controller.lvclass。

2d453be0c2303127daedd001f92d556e.png

1.创建Timed Loop Controller.class

这个类只需要一个属性:轮询频率。使此类继承Actor.class。

4a8f31dbe3359147cbdbbc28421fc633.png

1.1 Actor Core.vi

4532dc679bff49dfea619ac1eaf36535.png

父类actor.class中的Actor Core.vi被重写,父类actor.class中的Actor Core.vi中有一个状态机,当它收到停止消息时,就会退出,之后局部变量stop?为真,不在发送update消息。

1.2 Update.vi

此vi是空的,留给子类重写。

2. 创建Level Controller.class

Cooler actors 和Water Level actors的逻辑是一样的,都是超过限位就打开或者关闭。所以创建此类作为这两个类的父类,以增大代码重用度。这个类需要三个属性:高限位,低限位,这两个作为输入;另外还需要保存输出的值:高,低,不变。

1c4a1ccbecae91fc4324d25c9c62f263.png
4369c7ed4396232e1e870bfe9f249c7c.png

State Logic.vi是要复用的逻辑,Level Controller肯定要先从硬件读取输入,然后在进行逻辑操作,最后输出结果,输入和输出是和硬件有关系的,但是硬件不同,故读取功能的代码和输出功能的代码肯定不一样,为了使软件可扩展性更好,所以将输入get new level.vi和输出set output state.vi作为虚函数(就是明知程序中必须有,但是又不能写在此类中),这样更换硬件时,我们只需从此类继承,并重写输入输出vi即可。另外,此类重写了Update.vi。重写的update会以固定间隔运行。

3. 创建 Water Level.class


Water Level是一个具体类,继承自Level Controller。前面的Level Controller和Time Loop Controller是虚类,类似于c++中的虚类,不能够实例化对象,labview虽然没有这个规定,但这样做没什么意义。labview中,虚类负责逻辑设计,具体类(子孙类)负责具体的输入输出,和具体的硬件相关,这样带来的好处是,硬件更换时,只需要从虚类继承那些已经被设计好的逻辑,重写那些输入输出等和硬件有关的vi即可。

输入输出,可以由全局变量来模拟。这样会使测试软件时会方便很多。有人把它叫做HAL,即hardware abstraction layer 虚拟硬件层,瞬间高大上(⊙o⊙)…。HAL是继承父类的具体类,运行时就能够检验软件逻辑有没有错误。在设计是,最好设计个HAL,以方便调试。

这里面的Water Level就是HAL。

f84ccacfc088356e5a79a286c82cf532.png

其中输入输出都是用的全局变量来模拟的。

Get New Level.vi:

ffcc4dac63b3614db81cc5ae0b1e4984.png

Set Output State.vi:

358307e757c1dcd2db5b4c86f5804fab.png

写好后就可以测试了。

4. 创建Dual Fan.class


Dual Fan 是继承自Timed Loop Controller的具体类。属性为两个风扇的状态:打开或关闭,正常或故障。

f6ab7f87ef40f5548d4328e18d8ffd92.png
dec33b008e722a65a36d9637810a4010.png

为了让其他操作者能够打开或关闭风扇,需要为Power Off.vi和Power On.vi创建消息。当一个风扇故障时需要打开另一个,所以需要轮询风扇是否故障,这个功能通过重写父类Update.vi实现。

ed0a6f583a7043951edd9c5245052d03.png

完成后可对本类进行测试:

97c902c087b611e8afb0148d686df088.png

5. 创建Cooler.class


Cooler继承自Level Controller的具体类。Water Level和Dual Fan组合成了Cooler,所以要负责这两个操作者的启动和关闭。

b176520f296c66633c12b557a1efd314.png
cd2f1a311e20421b3ce31aa105db6384.png

Get New Level.vi不用说,还是从全局变量中读取模拟的温度值。之后是逻辑处理,父类已经写好,不用操心这部分,之后就是输出Set Output State.vi:

340d0da7bac5ac2b842a1762f83a1586.png

这里的代码解释了为什么要将Dual Fan队列的引用类型和Run Fan Delivery Notifier放到本类的私有数据中——因为他要根据温度值,控制风扇的打开和关闭,有Dual Fan队列的引用,直接向这个队列发送消息即可。由于pump打开后,需要等一段时间来让水充满海绵,所以需要使用Run-Delayed Send Message.vi,因为风扇关闭后此通知器就不用了,所以需要释放。

625f0fa9028775ec046a17235caf0ff0.png

Dual Fan队列和Water Level放到本类的私有队列中还有一个原因,那就是我们想Cooler关闭时,Dual Fan和Water Level也必须关闭(也有其他办法,在Cool的Actor Core中启动Dual Fan和Water Level时,获取他们的消息队列,然后创建一个和调用父方法并行的while,停止Cooler时,在这个while中向Dual Fan和Water Level发送停止信号,这个需要添加一个while循环),简单的办法是:

f3ec9a43a64311cb09dc8652e7acc33f.png

6. 操作者框架的优点


1.轮询代码(Timed Loop Controller)重用了3次,限位代码(Level Controller)重用了3次。

2.不用自己往消息队列添加消息了。而是使用的封装好的Send XXX msg.vi。

3.程序面板中while没那么多了。

7. 创建User Interface.class


到此,还有两个功能没有实现:

1.显示内部温度,水泵状态,风扇状态;

2.允许用户改变温度限制。允许Cooler脱离界面运行。

最健壮的解决方案是,将UI和消息传递部分分开,这样就减弱了Cooler和Cooler Panel的耦合,可以更灵活的更改界面。类似于MVC(model,view,control)——这里是将V和C分开了。

为了使软件有最大的灵活度,还要创建一个abstract user interface layer,AUIL,虚的用户界面。AUIL包括了UI类支持的所有消息和应该包含的公共代码。Cooler将能够向AUIL的任何子类发送状态消息。

8. 创建Cooler UI with Events.class


这个Actor操作者就是AUIL,虚类Cooler UI with Events。

当然首先Cooler UI with Events要继承自Actor。Cooler UI with Events将会从Cooler操作者中接收消息,然后这些消息会被此类转化为用户事件user events,最后由本类的事件结构处理。此类的所有子类都会注册这些事件,当子类接收到消息时,会更新前面板——UI。

先看它的私有数据:

58620d12a8103b5556936d8551f900af.png

下面是这个库是这部分的所有功能。这里面Cooler UI with Events包括了所有功能,除了显示。为了使系统整容更方便,这里使用Cooler Panel这个子类来负责颜值部分。当审美疲劳时,随时可以通过继承Cooler UI with Events获得新的面目。

99526130464497cd8177ff3cfbf82204.png

1.重写Pre Launch Init.vi。

105a4a67863d0e75d83c14a452904c96.png

创建三个用户事件,分别用来更新风扇状态,温度和水泵。这里的Events就是本类私有数据的Events。私有数据中还有一个

3df0aab2a049b6a428509cbd11d2d395.png

,主要是为了向Cooler发消息,如果只是为了显示,就不用添加Cooler这个队列了,直接执行动态事件就可以了。添加Cooler这个队列,就是为了向Cooler发送命令。

8f1a2652bc3337e0c040211a9718285a.png

Send Write Deadband的错误接线没有输出,因为如果想单独测试UI或UI启动但Cooler没启动时,Send Write Deadband有可能会输出错误,这个不太好。什么时候要连错误输出什么时候不要连错误输出,要按照情况来定。上面已经说了UI怎么向Cooler发命令,下面再讲Cooler怎么向UI发命令。

2.Update Fan.vi。

fb548cb1fce8b2d8381227d887eed26a.png

3.创建消息:

a. Change Desired Temperature

b. Update Fan

c. Update Pump

d. Update Temperature

e. Write Cooler

这些消息就是为了让其他Actor操作本Actor。

9. 修改Cooler.class


原来设计的Cooler,是自己运行,他并不会将自己状态告诉UI,你不告诉人家,人家怎么知道。

修改办法:Cooler中所有涉及风扇状态,水泵状态,温度改变的vi都要向UI通知。

1.Cooler.lvclass:Get New Level.vi。读取温度后通知UI。这里不将Send Update Temperature的错误输出连接到error out,是为了程序在没有UI的时候也能正常运行。

1fb157b2b5aa1af77d514b9e1ff8989b.png

2.Set Output State.vi。设置读取后温度,经逻辑处理,输出为水泵的状态。也要通知给UI。Send Update Pump的错误输出端也没有连,原因你懂的。

5db61d3b64ddb705bbc19f51b6df8534.png

3.Update Fan Status.vi。更新风扇状态。这个有点小曲折。因为UI和Cooler平起平坐(关联),Dual Fan是由Cooler启动的,Dual Fan和UI之间没法交流。所以只好在Cooler中写个public的Update Fan Status.vi,并为他创建消息,这样Dual Fan的状态就会通过Cooler传给UI。也就是Dual Fan状态改变时,要先给Cooler发消息,由于Cooler知道UI的队列,Cooler收到消息后会向UI发消息。

31ded50cea167a2375f03ced23d255cd.png

4.前面都是修改Cooler类,现在轮到Dual Fan类了。

a.Dual Fan.lvclass:Post Update.vi。这里使用了Read Caller Enqueer.vi,读取调用者Cooler的消息队列,Cooler收到消息后会调用Update Fan.vi,这个vi将向Cooler Pannel发送用户事件来更新UI。这样,就可以通过多次调用Post Update.vi来更新UI。

668ca82e5120cb1df4634a70cbebeb2c.png

b.在Power On.vi, Power Off.vi和Update.vi更新UI。

Power On.vi:

4e01f19f9ac7867e5ba0e734b9f4f532.png

Power Off.vi:

206f3ff4579d7d67e5dc0976e20fd674.png

Update.vi:

19ee4f4b5a99c40d16195adb73df8160.png

10. 创建颜值担当Cooler Panel.class


Cooler Panel只负责UI交互。

直接来:

4c789062ff5c06291d8321afad4ba103.png

创建要和Actor状态机并行运行的的while时,一般会采用这种伎俩。为了在适当的时候,停止和Actor状态机并行运行的的while,这里使用了再次使用了用户事件。Timed Loop Controller中停止和Actor状态机并行运行的的while的方法,是Actor状态机执行完毕后,局部变量布尔开关变为false,导致while停止。上图这种是需要在界面上人为控制系统停止才使用的,当然也可以使用其他办法,如队列,信号值什么的,但NI建议只使用一种,所以UI部分已经使用了用户事件,这里也使用用户事件来做。至此UI和Cooler全部完成,只需将他们启动了。

c40221008b3ab053caa81405afb05ce5.png

11. 创建Application Launcher.class


这个启动者的名字叫Feedback Evaporative Cooler Demo.vi。

fda1b1cfb702d810a2ee484f338269ca.png

12. 软件测试


如果风扇A打开或风扇B打开或室外温度小于室内温度时,室内温度减小。

ec27fa7207ea802669337476ed990666.png

如果风扇A关闭并且风扇B关闭并且室外温度大于室内温度时,室内温度增加。

018a995ba5d2d62fc619f92f524638b3.png

更多教程,请关注 labview工作室 ,学习labview或需要源码的朋友,欢迎关注留言咨询。

需要labview培训请留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/430140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eclipse发布web不带项目名的url

默认发布后访问地址是&#xff1a; http://localhost:8080/huanle/ 要达到的效果是&#xff1a; http://localhost:8080/ 不带项目名的url的好处是&#xff0c;不用再在每个地址前加<% path%>了&#xff1a; &#xff08;很烦有木有&#xff09; 操作方法&#x…

php 随机在文章中添加锚文本_页面SEO优化的锚文本优化概念

SEO优化分为结构优化和页面优化&#xff0c;页面的SEO优化中其中一个重点是锚文本的建设。锚文本的概念就是网站的内部链接&#xff0c;较为常见的就是将文章中的关键词作为锚文本。但在具体建设当中&#xff0c;很多网站对锚文本的处理出现了很多错误。这是因为对锚文本的优化…

eclipse发布web显示异常,清除缓存也无效?

发布的项目突然之间显示就不正常了&#xff0c;清除了n遍缓存&#xff0c;tomcat目录&#xff0c;一点效果都没有&#xff0c;这时候&#xff0c;应该用Dreamweaver检查下页面代码&#xff0c;很可能是你不小心删了点什么。 下面是一个血的教训&#xff0c;浪费了一上午时间&a…

关于NPN和PNP传感器的应用区别(转载)

http://blog.csdn.net/greatwgb/article/details/9120735 PNP与NPN型传感器其实就是利用三极管的饱和和截止&#xff0c;输出两种状态&#xff0c;属于开关型传感器。但输出信号是截然相反的&#xff0c;即高电平和低电平。PNP输出是高电平1&#xff0c;NPN输出的是低电平0。 …

spring security:第一个程序

spring security虽然已经简化了&#xff0c;但配置还是要小心翼翼的。这里运行起第一个spring security程序。 环境&#xff1a; spring 4.2.4spring security 4.0.4 &#xff08;GA&#xff09; 搭建步骤&#xff1a; pom.xml 加入web和config模块&#xff0c;config模块是…

文献引用的标准格式_外语论文文献引用格式—APA Style

APA Style写外语论文时&#xff0c;非常注意引用格式的使用。APA作为常见的论文引用格式之一&#xff0c;常被用于心理学、教育学和社会学科领域。可是你知道APA格式要如何使用&#xff1f;APA格式有哪些要求&#xff1f;下面小编为大家整理一下~什么是APA格式&#xff1f;APA格…

pandas 提取某几列_【科学计算工具二】初识Pandas

和Numpy最大的不同&#xff0c;Pandas的数据有对应的index。一、Series数组Series 是带有标签的一维数组&#xff0c;可以保存任何数据类型&#xff08;整数&#xff0c;字符串&#xff0c;浮点数&#xff0c;Python对象等&#xff09;&#xff0c;轴标签统称为索引创建Series数…

开发物体识别桌、_科研人员开发突破性的技术,允许盲人识别形状和物体

一项令人难以置信的新技术正在让失明人士有能力识别形状和物体&#xff0c;而这些形状和物体都是在他们的大脑上“画出来”的。一篇描述该技术的研究论文刚刚发表在《细胞》杂志上&#xff0c;正如ScienceNews报道的那样&#xff0c;这可能是向盲人提供一种视觉上与周围世界互动…

spring webflow getting start

概述 很多时候&#xff0c;我们写的流程都嵌在一大堆代码中&#xff0c;没有办法直观的管理。而spring webflow可以将流程抽出来&#xff0c;放到一个单独的xml文件中&#xff0c;这样流程就不会埋没在代码里了。 今天要做一个很简单的流程&#xff1a; 商品发布流程 Created…

windows 修改nginx端口号_分享Nginx搭建图片服务器简单实现

第一步&#xff1a;安装vsftpd提供ftp服务https://www.cnblogs.com/lyq159/p/12070791.html第二步&#xff1a;安装Nginx提供http服务1.安装准备&#xff1a;安装Nginx环境a) gcc      安装nginx需要先将官网下载的源码进行编译&#xff0c;编译依赖gcc环境&#xff0c;如…

C#学习笔记-数据的传递(公共变量)以及Dictionary

看的代码越多&#xff0c;写的代码越多&#xff0c;就越是享受这些字符&#xff0c;终于渐渐懂得了那种传闻中的成就感&#xff0c;特别是自己从看不懂然后一步一步学&#xff0c;一个代码一个代码地敲&#xff0c;最后哪怕只是完成了一个小功能&#xff0c;也都是特别自豪的&a…

斐波那契数列通项公式

1.对于斐波那契数列来说&#xff0c;存在通项公式&#xff0c;f[n] 2、Hdu练习题1568&#xff1b; 大意求斐波那契数列中的某一项&#xff0c;n很大&#xff0c;只能在O(1)时间求出&#xff0c;并且只要前四位 当n很大时最后一项几乎为零转载于:https://www.cnblogs.com/dlut-l…

服务器驱动精灵_驱动精灵真的可以帮你安装驱动吗?别再无脑装驱动了

之前和大家讲过一期安装官方纯净系统的方法&#xff0c;戳我查看然后很多人就说重装之后显卡驱动掉了打游戏卡的跟PPT一样。于是很多人在重装系统或是进行了重大硬件更新后&#xff0c;一般会采用第三方驱动管理软件来进行硬件的更新&#xff0c;实际上这是一种自杀式行为&…

(原创)网吧桌面背景添加文字,转载注明出处!

很简单的小工具&#xff0c;可用于公告等。 下载地址&#xff1a;http://pan.baidu.com/s/1i5dPQTJ 密码&#xff1a;sfw7 博客地址&#xff1a;http://www.cnblogs.com/flybox/ 如有必要&#xff0c;后续可添加功能&#xff1a;远端配置文字内容等&#xff0c;方便多网吧统一…

前端vue适配不同的分辨率_前端面试时,被问到项目中的难点有哪些?

在每个前端求职者的面试过程中&#xff0c;一定都有过被面试官问到项目中的难点&#xff0c;而答不上来的情况。为了让大家在前端面试前准备得更加充足&#xff0c;小编准备了一些易被忽视且难度较高的前端面试题&#xff0c;希望可以帮助大家更加顺利完成求职&#xff0c;找到…

在jsp页面里动态生成EL表达式的key

如图&#xff0c;页面中有n个商品列表需要加载&#xff0c;这个列表的名字分别是list1、list2…listn&#xff0c;总之不是写死的。 在Ctroller里面&#xff0c;可见参数名师动态生成的&#xff1a; RequestMapping(method RequestMethod.GET) public String showIndex(Model…

AutoLayout--masonry使用

[label1 mas_makeConstraints:^(MASConstraintMaker *make) { //使左边间距为 make.left.equalTo(self.view.mas_left).offset(11); //顶部间距 make.top.equalTo(self.view.mas_top).offset(70); //高度 make.height.equalTo(30); }]; [label2 mas_makeConstraints:^(MASConst…

matplotlib 热力图_5分钟入门 Seaborn 热力图可视化

Seaborn是基于matplotlib的Python可视化库。它提供了一个高级界面来绘制有吸引力的统计图形。Seaborn其实是在matplotlib的基础上进行了更高级的API封装&#xff0c;从而使得作图更加容易&#xff0c;不需要经过大量的调整就能使你的图变得精致。注&#xff1a;所有代码均在IPy…

Linq(拓展方法+select())

拓展方法&#xff1a; 目的&#xff1a;对于已存在类型的行为进行拓展 注意事项&#xff1a; 1&#xff1a;扩展方法必须是一种特殊的静态方法 2&#xff1a;扩展方法必须是在静态类中 3: 扩展方法的优先级低于同名类的方法 4&#xff1a;扩展方法只在特定的命名空间内有效 5&a…

手机全部零件名称图片_【直播课】一条记录中显示多张图片

↑点击上方“Access软件网”免费订阅温馨提示这是一节免费课&#xff0c;干货太多&#xff0c;强烈推荐&#xff01;今天(2019年1月10日)晚上8点&#xff0c;准时开讲&#xff0c;欢迎大家前来听课&#xff01;点击文章末尾左下角的原 理本课示例是显示某个零件的图片&#xf…