完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
这一次要谈到的是如何将上一回的红绿灯程序用 State Machine 的架构来改写,并且可以很弹性地来扩充程序功能。State Machine 的写法不难,初学者练习写过几次后就可以跳脱以往用 Sequence 写法的思维,不会遇到大一点的程序就把程序码写得很零乱而不好维护,而是试着把程序的每一步流程拆开来写。这是往后能用 labview 写出一个好程序的基础。 State Machine 主要由 Loop 、Shift Register 、Case Structure 以及存成 Type Definition 的Enum Control 。其中 Enum Control 是用来表示程序的状态,按下右键选择 Edit Items… 就可以编辑,如下图。
通常我会设定 Initial 、Idle 和 Stop 这三种状态,然后再将其他会用到的状态编入,如下图。
将状态编辑入Enum Control 并且存成 Type Definition 后关掉。接着在主程序界面放上一个 While Loop ,并且在循环上右键 Add Shift Register ,以及在循环里面再放上一个 Case Structure 。然后将存成 Type Definition 的 Enum Control 按下右键 Change to Constant ,并且接线进 Shift Register 和 Case 。最后在 Case 的选单上按下右键 Add Case for Every Value ,此时所有在 Enum Control 里面的状态都会出现在 Case 的选单里面,如下图。
以下我以用 State Machine 写成的红绿灯程序为例:
上图是 Initial 的状态,可以把红绿灯想成一般的仪器,我们在控制仪器时,第一步会先将仪器资源打开并初始化。一般的写法会将这个步骤写在 While Loop 前面。但这样如果程序执行过程中发生 Error 而需要将仪器 Reset 时,就要在循环里面另外写一个 Reset 的程序。状态机写法的好处是把 Initial 也当作一种状态。当程序执行过程中需要将仪器初始化时,只要让状态机进入 Initial 的状态即可。所以在储存 State 的 Shift Register 会将它初始化为 Initial 。
如上图,在状态机中,除了可直接指定下一个状态之外,也可以设为当条件满足时再跳到下个状态。所以在红灯、黄灯和绿灯的状态中, Wait Time 是用 Count 来计时。在前一个状态可以指定下一个状态的 Wait Time ,当 Count 每次递减而归零,满足条件时,才会跳到下一个状态以及更新 Wait Time 的 Count 值。
当进入绿灯的状态时,可以指定下一个状态要让红绿灯重新启动或是停止,如果 Next State 是 Initial 的话,红绿灯就会连续执行;若 Next State 是 Stop 的话,红绿灯则只会执行一次。所以整个程序流程为 Initial -> Red (wait 3 seconds) -> Yellow (wait 1 second) -> Green (wait 2 seconds) -> Initial …… 。
如上图,当使用者按下 Stop 按键时,程序就会进入 Stop 的状态再离开循环。这样的写法可以在 Stop 这个状态先将仪器的控制命令先归零再释放资源,而不会让程序都停止了,而仪器还在继续工作。另外,当程序执行过程中,仪器出错而需要将仪器关掉时,也可以让程序进入 Stop 的状态再离开程序。
如果程序需要有两个以上的按键来选择状态时,可以采用上图的写法。例如红绿灯程序要增加一个 Restart 的功能,当红绿灯在执行过程中,使用者只要按下 Restart 就可以让红绿灯重新从红灯亮起。如上图左下角的程序码,将两个 Boolean Control 先 Build Array ,再用 Search 1D Array 去搜寻哪一个按键被触发了。接着再用 Index Array 去选择要执行哪一个状态,如果都没有按键被触发,则输出结果为 -1 ,将结果 +1 接到 Index Array 的 Index 接点,就会将 Array 中第一个 State ,也就是原本 Shift Register 的值输出; Restart 按键按下,会输出 Initial 的状态;而当 Stop 按键按下,则会执行 Stop 的状态。在这个写法上可以很容易地扩充按键的数量,但一次只能触发一个事件,当有两个以上的按键被同时被按下时,只有第一个事件会被执行,而这也是 State Machine 架构的一个缺点。 当程序写到这个部分,大部分的功能都已经完成了。现在如果这时又想再增加一个 Start 的按键,让红绿灯在程序一开始执行时并不启动,而是让使用者来决定它什么时候要启动。此时, Idle 这个状态就派上用场了,我们可以在一开始进入 Initial 的状态里面, Next State 不要指向 Red 而是指向 Idle 。当红绿灯初始化完成后,程序会在 Idle 这个状态中轮询,直到 Start 被按下时,红绿灯才会开始启动。
如果不想让程序在 Idle 的状态中不做事仍一直轮询的话,可以把 Event Structure 加入 State Machine 里面,如下图。如此一来,程序在 Idle 的状态中就不会一直轮询而浪费 CPU 资源,而是等待使用者触发按键才会继续执行程序。不过要记得把其他按键的触发也写入 Event Structure 中,否则在这个状态中,使用者只有按下 Start 按键才能触发程序。
最后再增加一个功能,我想要让黄灯亮时可以闪烁。以上一回提到将红绿灯的功能模块化,以及这回的使用 State Machine 的程序架构,增加程序功能是非常轻松简单的。我们只要修改原本 Traffic Light 的 Sub VI ,让它增加可以让灯号闪烁的功能,如下图所示。 |
|
相关推荐
11 个讨论
|
|
|
收藏下。慢慢消化
|
|
|
|
|
|
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
211 浏览 0 评论
请教大神,在labview里面对实时扫描资源中的C系列模块NI9234进行配置发生非预期错误
1709 浏览 0 评论
1585 浏览 0 评论
LABVIEW 2023 Q1调用python后一直报错1671
1960 浏览 2 评论
5207 浏览 3 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 12:20 , Processed in 0.908664 second(s), Total 76, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
6475