一 [L5] 数据结构
数据结构除了Scalar以外还有Array和Cluster。
Array
- Uninitialized黑色/ initialized数据类型的颜色,array中数据类型保持一致。一般只用 1D和2D array。
- 2D的第一维是行第二维是列,3D的第一维是页,第二维是行,第三维是列。
- 常用Opreation
- Initialize Array: 生成一个全部元素都相同的array
- Insert Into Array: 在固定位置插入元素/子array,如果插入后的array其他维度尺寸超过原始尺寸,剪切,并丢弃多余内容。
- Delete From Array: 删除并返回剩余array和被删除的array,删除长度可以填过大值。
- Array Min & Max:返回最大值最小值和index,第一个
- Search 1D Array:返回搜索值的index,第一个
- index:返回(维度-1)的切片
- subset:返回维度相同的切片
- size
- build array
- concatenate input: 按维度链接 不增加维度
- 普通:新增第一维 维度+1
Cluster
- Uninitialized黑色 / initialized都为numeric棕色,initialized其他/混合粉色,Error黄色。cluster中数据类型可以不一致。
- 各元素是有序的,会影响unbundle解包是的顺序。
右键 - reoder controls in cluster
- 使用unbundle by name不会因为顺序的改变而出错。
- bundle by name 需要输入一个样板,最好就是 Type Definition。
Type Definitions
Control Options
- custom control: 是一个snapshoot/样本,需要时可以拖一个过来使用,相互之间无联系
- typdef:
右键 - Make Type Def
, 所选 terminal 左上角出现黑色三角。右键 - Open Type Def
,打开生成的 .ctl 文件- 在.ctl文件中 apply changes 会改变vi中terminal的样子
- 在vi中改变 不会影响ctl的样子,可以单独改变颜色,标签等。如果.ctl再次apply changes,所有vi中的改变会消失
- strict typdef:
- vi中不能做任何改变
- ctl中改变同 typdef
Polymorphism
-
数字/Bool的array,纯数字/Bool的cluster,等可以和自己的同类或者和numeric/bool直接进行数学/逻辑运算。
-
运算方式是个对应元素相运算,故不能用于线性代数运算,需要转换成矩阵。
-
Cluster of String / Array of String / Array of Cluster of String 也可以进行整体的字符串运算
-
等等 详见 操作手册 214页 附录B
二 [L4/6/10] 执行结构
1. Loop 循环
a. While循环
至少运行一次。i从0开始,可以选择是 stop-while / do-while。默认传递出一个值,Tunnel类型默认是Last Value。
b. For循环
可以运行0次。i从0开始,for i < N。默认传递出一个array,Tunnel类型默认是Indexing。可以右键边框额外开启conditional terminal,这时N的位置会出现红点,提醒当条件满足或者循环到达次数时会停止。
c. Tunnel 结构隧道
隧道用于接收和输出结构中的数据,颜色取决于数据类型,数据到达输入隧道后结构才开始执行,执行完毕后输出隧道才有输出。隧道有三种类型:
- Last Value
- Indexing
- Concatenating
输入隧道只有Last Value和Indexing两种:
- Last Value将输入作为整体传递入循环,维度不变。
- Indexing将元素的第1维拆分后分批输入循环,维度-1。
输出隧道:
- Last Value将循环结束时的结果传递出去,维度不变。
- Indexing将每次循环的结果进行拼接,维度+1。
- Concatenating将每次循环结果进行拼接,维度不变。输入必须是array,这样才能在原维度上拓展。
注意Indexing和Concatenating在 Array3/4,Array7/8,Array10/11拼接方式的区别,这也是Arrat操作Build Array中普通和concatenate input的区别
Auto-Indexing 自动索引
即输入indexing隧道,Array作为for循环的输入,并在输入隧道开启Indexing时,可以不用设定N的值,相当于 (for item in list),循环次数是array第1维的长度。如果同时设定了N的值,循环次数时N和第1维长度的最小值。
如果auto-indexing连接入while循环,循环次数不收array大小控制,仍有while的条件控制,当array中没有新元素能被取出是,使用变量类型的默认值。
d. Shift Register 位移寄存器
相当于在循环外在内存中创建了一变量,变量在每次循环中被更新。位移寄存器在结构体两边的位置必须处于同一水平位置。
通过拉长左边的寄存器 可以变成 Stacked Shift Register 栈移位寄存器,可以得到上一个循环时的值。
可以右键shift register将其转换为Feedback Node 反馈节点,以避免循环中出现长连线。反馈节点可以改变显示方向。
本身类似于Last Value,array会被当作整体输入输出。
在运行0次的情况下,连接循环的隧道输出的控件是未被初始化的,而连结位移寄存器的控件可以直接访问内存获取数据。
e. Timing
4个常用VI:
- Wait until next ms multiple:产生delay,与系统时间同步
- Wait (ms):产生delay,从激活时间开始算
- Time Delay Express VI:与Wait(ms)相同,多了Error接口,并且以秒做单位。
- Elapsed Time Express VI:不会使程序产生Delay,而是告知启动它后经过的,和是否超过了预设的时间限制。
例:两种方案:1.任务间暂停60分钟,2.任务在整点运行。如果完成任务需要5分钟,从1:00开始,方案1的之后的运行将在2:05,3:10,4:15…方案2之后的运行将在2:00,3:00,4:00… 方案1是wait(ms),方案2是wait until next ms multiple。
3. Case 条件
条件结构每次只能显示一个子程序框图、执行一个条件分支,相当于switch/if…elif…else。
选择器接线端支持的数据类型有
-
整型 Int
可以设定整数范围 a..b 是 包括a和b的闭区间;a.. 或 ..a 是包括 a的半开半闭区间。
-
布尔型 Bool
只有真假两种选择
-
字符串型 String
默认情况下,字符串区分大小写,可在结构框
右键 - Case Insensitiv Match
关闭,此时框体左下角会显示A=a
。单个字母时可以使用 .. : 但 a..c 表示a和b,和整型不同。
-
枚举型 Enum。
-
Error Case
可以创建多个输入输出隧道,所有隧道各个分支共用接口,如果没有连线,输出隧道将显示白色,可以右键选择 右键 - Use Default if Unwired
在未链接时输出默认值。
可以设定默认分支,也就是 (else…),可以设定某分支为默认分支,也可以单独创建默认分支。Bool选择没有也不能设定默认分支。分支可以合并,通过 Tool Palette - Edit Text
改变case。
另见case在状态机中的运用。
4. Event 事件
循环+事件结构用来降低资源消耗,相反如果用循环+条件结构的轮询Polling结构,在每次循环中判断按钮状态,需要消耗大量资源。事件结构将等待直至某一事件发生,并执行相应条件分支以便处理该事件。 并且和条件结构不同,可以关注不同的触发源,设定不同的分支。注意:必须放在循环(while)中,以避免锁定状态;一个循环中放一个事件结构;事件分支内代码经量短快;布尔开关放在分支内。
事件可以源于
- 用户界面 user interface、
- 外部 I/O external I/O 或
- 应用程序的其它部分other parts of the program。
目前关注用户界面事件,有:
- Mouse Clicks
- Key Presses
- Value Changes of a Control
用户界面事件分为两类:
-
Notify 绿色
-
Filter 红色 触发前确认,可以Discard这次触发,有专门的discard选项
事件结构可以设定 Timeout 超时,当等待时间超过设定值时,触发超时事件。默认值为-1,表示永不超时。
5. Sequential 顺序
不要用。在顺序结构中无法立即响应其他操作。
6. State Machine 状态机
使用enum,while,case,shift register 实现。
步骤:
- 列出可能的状态 State
- 在状态程序框图中绘制状态之间的关系 Transaction
- 在LabVIEW中构建状态机
状态 State:
Enum是状态机的状态集合,设定TypeDef,使加入新的状态时可以同步。如果不使用TypeDef,并且Enum产生变化,会显示Coerision Dot。
Enum连入Case来处理这个状态下的具体情况,并且在出口设定新的状态,通过shift register完成状态更新,即完成transaction。
转移代码 Transaction:
-
一对一 Single Default
-
一对二 Select Function
-
一对多 Case Structure
-
一对多 Transition Array
Shift Register:
一个比较清爽的方案是:需要三个位移寄存器,一个给状态,一个给Error,另外把其他信息打包成Cluster,然后使用一个寄存器。
关于状态机的更多实用结构,见 LabVIEW3 。
三 [L4] Plot
- Waveform Chart
- 放在循环内使用,因为它每次往图上新增这次循环中获得的新数据点
- 单图例,即一组数据,直接将scalar指传递给chart。图中只有一条数据线,如温度。
- 多图例,即多组数据,将多个scalar bundle以后形成cluster再传递给chart。图中多个数据线,如温度,湿度等。
- 更新方式:
- 条形图 strip:此模式具有滚动显示功能,类似于纸带条形图记录仪。此模式从左到右绘制值。当它收到新的数据值时,它会在右边界绘出该值,并将旧的值移到左边。
- 示波器图表 scope:此模式类似于示波器的回溯显示。当它接收到每个新值时,它会将值绘制到最后一个值的右侧。当到达绘图区域的右边界时,它会删除绘图并从左侧边界开始再次绘制。
- 扫描图表 sweep:此模式的作用与示波器图表非常相似,但当图表到达右边界时,图表不会被删除。相反,一条移动的垂直线标记了新数据的开始点,并在添加新数据时从左向右移动显示。
- Waveform Graph
- 放在循环外使用,因为它每次画出一组数据。
- 单图例,接收1d-array
- 多图例,接受2d-array,可以使用build array建立2d-array。
- XY Graph
- 放在循环外使用,和matplotlib的plot有点相似,接受一组数据。
- 数据是一个cluster,包括x的一个1d-array和y的一个y的1d-array。
四 [L7] SubVI/Modularity
模块化可以帮助简化代码,重复使用相同的部分。相当于定义一个函数。
-
icon 设定图标
-
连结Connector Pane 连线板, 图标的接线口
- 选择pattern,标准默认样式 4x2x2x4
- 在Front Panel点击 Connector Pane相应位置,再连结需要的Control
- 应该预留左上右上的Reference接口,和左下右下的Error接口,左半边是输入,右半边是输出。
- 再subvi中不应该使用error handler,而应该建立error in和error out的端口。
Required 必需、Recommended 推荐或Optional 可选 的接线端:右键单击连线板上的接线端,从快捷菜单中选择接线端类型,然后为输入或输出端选择必需、推荐和可选。输入端可以设置“必需”,未连接的话SubVI出现断线。输出端不存在“必需”选项。如未连接”推荐”或”可选”接线端,程序框图不会生成任何警告。在Context Help中,“必需”接线端的标签是粗体,“推荐”接线端的标签是普通文本,“可选”接线端的标签是灰色字体。
-
写说明和提示。说明可以使图标在Context Help中显示介绍。提示可以是鼠标移动到图标上时显示简略浮窗说明。
五 [L8/9] Accessing
Hardware
Singal Type:
- Analog
- Digital
- Counter: 包含数字信号特征的数字时间信号。比如上升边缘,边缘频率,脉冲宽度等。
NI MAX:
用来检验,设定,测试硬件设备的软件。还能模拟硬件,绿色是真实设备,黄色是模拟的设备。
- Examining:
- Device Routes:查看设备内部信号传递
- Setting:查看上次内部外部校准Calibration的时间。真实设备可以进行Self-Calibrate。
- Testing
- Self-Test:快速检测
- Test Panels:检测三种信号输入输出是否正常
DAQ Assistant:LabView中连接硬件的Express VI
DAQmx API: LabView中连接硬件的普通VI
DAQmx 需要的步骤:
- Create task
- Configure task
- Start task
- Acquire or generate data
- Clear task
- Check for errors
非NI设备: VISA
File
基本文件读取操作:
高层操作 vs 低层操作
High-Level: 开写关三步合一,简化block diagram,但资源消耗高,仅适合一次性读写。
- Spreadsheet File:1D/2D array → text
- Measurement File:signals(dynamic data types) → .lvm/.tdms
- Waveforms: waveform → text
Low-Level: 一步一步,精细控制,节约资源,适合streaming
- Refnum 线,标记不同的I/O操作,一个操作一个Refnum,防止多个文档打开发生混乱。
- Streaming:文件打开,循环内不断写入。如果用high-level的方式,资源消耗就很高;low-level只需要放入 写 的function就ok。
文件类型:
- ASCII: 普通基于ascii的文档 如txt
- LVM: LabView自己的格式,LabVIEW measurement,固定了格式的ASCII文档。格式是用tab分隔,包含数据和数据生成时间等。用处不大。
- Binary:二进制文件,类似于python的pkl等,小快
- TDMS:National Instrument自己的格式,固定格式的二进制文件。有两个单独的文件构成,一个包含数据和数据特性的二进制文件,一个二进制索引文件。
更多File I/O 相关内容,见 LabVIEW4 。
注:部分图片来源
https://knowledge.ni.com/
https://zone.ni.com/
https://www.ni.com/images/gettingstarted/