手头又有一块NI的采集卡、一根USB线、几个传感器,目标很明确:用LABVIEW做一套数据采集处理程序,把电压、温度、振动这些信号采进来,实时显示、越限报警、落盘保存。这套活儿我干了差不多十年,从学生时代用LABVIEW课设开始,到后来给产线做设备监控、给实验室搭数据平台,踩过的坑比写过的代码还多。今天就把这套“LABVIEW数据采集处理程序开发”的完整思路、架构选择和实操细节从头到尾聊一遍,适合刚接触数据采集的初学者,也适合已经在用但总觉得程序会卡、数据会丢、架构越写越乱的工程师朋友。
先说清楚这套程序能解决什么问题:把模拟信号变成计算机里的数字,把数字变成界面上的波形,把波形变成报警和文件,同时保证这个过程不卡、不丢、不糊弄人。核心就是三件事——采得对、传得顺、存得稳。围绕这三个目标,我会从需求拆解、硬件配置、生产者消费者架构、数据显示与落盘、常见问题排查,再到一份可以直接照抄的搭建步骤,一步步展开。
1. 先从需求开始:这套程序到底要做什么
1.1 拆开一个典型的数据采集任务
做LABVIEW数据采集最容易犯的毛病,是上来就打开前面板拖控件、接线,等画完了才发现需求根本没理清楚。我接到过的需求十有八九长这样:“帮我做一个采集界面,把传感器数据采进来显示一下就行。”这句话听着简单,但“一下”背后往往藏着完全不同的结果——有的要采5分钟就停,有的要连续采24小时,有的要实时算RMS值,有的只要原始波形,有的还要联动继电器切负载。这些没问清楚,后面全得返工。
以我这次分享的程序为例,它的典型需求可以拆成四块:
- 连续采集多通道模拟输入信号,单通道采样率至少1kS/s,通道数4个。
- 实时显示波形,同时计算并显示当前值、最大值、最小值。
- 设定上下限阈值,超限时前面板报警变色,并输出一个DO信号驱动报警灯。
- 数据持续写入本地文件,按天拆分,方便事后回放和分析。
这些需求拆完之后,系统的每个部件才有存在的理由。没有文件存储,靠截图留数据根本没法用;没有报警逻辑,采集程序就是个带曲线的示波器;没有连续采样,碰到长时间测试就得崩溃。
1.2 为什么选LABVIEW而不是其他方案
有人会问,Python也能做采集,C#也能做,为什么还选LABVIEW?我的答案很直接:如果你要的是快速把测量系统和硬件打通,LABVIEW的性价比确实高。NI的DAQmx驱动封装了绝大多数采集卡的操作,你不需要去查寄存器、写底层驱动,只需要面向“通道”“采样率”“触发方式”这些概念编程;图形化数据流天然适合表达“一边采一边显示一边存”的并行逻辑;再加上丰富的仪器驱动库,和示波器、万用表、PLC、串口设备对接也有现成例程。
当然这不是说LABVIEW天下无敌。做分布式大规模数据处理、做重度算法训练,LABVIEW确实不如Python和云平台灵活。但在单机仪器控制、硬件在环测试、产线设备监测这类场景里,一套好用的LABVIEW数据采集程序可以顶半个硬件工程师,而且调试周期短。后面聊到的“还不被淘汰”的问题,我放到常见问题章节专门讲。
1.3 程序整体架构:采集、处理、显示、存储各管各的
数据采集程序的架构,我一开始也写得稀烂:把所有代码堆在一个while循环里,一边DAQmx读取,一边更新图表,一边写文件。采样率一上去,程序界面就开始转圈,数据读取的间隔也被拖长,采集卡缓存溢出直接报错。后来改成典型的“生产者-消费者”结构,才彻底解决。
这个架构一句话概括:采集循环负责把数据放进队列,处理/显示/存储循环负责从队列里取数据干活,两个循环之间用队列传递数据,互不阻塞。就像工厂里两条传送带之间的缓冲仓,只要仓没被塞爆或搬空,哪条线停了都不会把另一条憋死。
对应到我这次的程序,就是:
- 生产者循环:DAQmx读取,把原始波形按固定块大小塞进队列。
- 消费者循环:从队列里取出数据块,更新波形图表、计算统计量、判断报警、写入TDMS文件。
UI事件处理则用独立的事件结构循环,响应按钮点击、阈值修改等操作,把指令通过用户事件或队列传给消费者循环。这样三个循环各干各的,总线冲突和数据拥塞都能避免。
2. 硬件与采集配置:别小看选型和接线
2.1 板卡、传感器和接线方式怎么定
仿真程序跑得再欢,接到真实硬件上分分钟教做人。采集系统里最容易被忽略但后果最严重的问题,来自硬件选型和接线。
先说传感器。采集电压信号相对简单,但要测温度就得接热电偶或RTD,测振动就得接IEPE加速度计。以热电偶为例,它输出的是毫伏级信号,冷端补偿还得处理。很多采集卡自带冷端补偿通道,接到对应端子就行,但如果你接错通道,补偿就失效,数据直接偏几度。我踩过的坑是:把热电偶正负极接反,LabVIEW里读出来温度不升反降。
再说接线模式。NI采集卡上的AI端子通常支持差分(DIFF)、参考单端(RSE)和非参考单端(NRSE)三种方式。接线模式的选择会直接影响共模抑制和有效分辨率。简单来说:
- 信号源是浮地的(比如电池供电的传感器),距离又近,可以用RSE。
- 信号源有自己参考地的(比如和采集卡共地的设备),建议用NRSE,避免地环路。
- 信号质量差、电压低、环境电磁干扰强的,果断用DIFF,一根信号一根地,干扰对消效果最好。
我这次程序用的是RSE方式,4个AI通道接直流电压信号源。如果你要接的是高精度电桥或者热电堆,强烈建议用DIFF方式并把屏蔽层处理好。
2.2 DAQmx API vs DAQ助手:定时和缓存机制
配置通道有两条路:一条是拖一个DAQ助手控件进来,鼠标点一点生成代码;另一条是直接用DAQmx VI搭建。新手用DAQ助手确实快,但它生成的代码是黑盒,配置一复杂就不知道怎么改。我建议在正式程序里用DAQmx API,哪怕麻烦一点。
核心的API调用链是固定的:
- DAQmx Create Channel (AI Voltage),设置物理通道、量程和接线模式。
- DAQmx Timing (Sample Clock),设置采样率、每通道采样数和采样模式。
- DAQmx Start Task。
- 循环里DAQmx Read。
- 循环结束DAQmx Stop Task和Clear Task。
这里重点说定时与缓存。你配置的“采样率”是采集卡ADC实际的工作时钟频率,它决定了每秒真实采样多少个点;而“每通道采样数”(Samples Per Channel)指的是每次Read操作从驱动缓存里取多少点。这两个参数要配合使用,原则是:Read频率 × 每次读取点数 ≤ 采样率,否则驱动缓存会来不及被取走,缓存满了就报“Slow Consumer”错误。
用我程序里的配置举例:采样率1kS/s,我设置每次读取100点,也就是每条循环10毫秒取一块数据。这样即使消费者循环偶尔慢了一下,队列缓冲区还能扛住,不会立刻丢数据。如果采样率是10kS/s,我可能会把每次读取点数调到1000,让读取块更大,减少队列进出场的次数。
2.3 采样率、量程和去噪之间的取舍
采样率不是越高越好。采集卡是有带宽和存储上限的,采样率越高,数据量和成本都跟着涨。根据奈奎斯特定理,采样率至少是信号最高频率的2倍,但实际工程上我一般按10倍来取,给波形留出足够还原度。比如要看50Hz工频干扰,至少要采500S/s;要看电机振动的高频分量到1kHz,就要采10kS/s。
量程设置也直接影响位数。NI的16位采集卡,如果量程设成±10V,理论分辨率是10V/2^15(约0.3mV)。如果你信号只有±50mV却用了±10V的量程,有效分辨率会大幅下降。所以量程应该贴着信号范围选,宁可留一点余量也不能太大。比如信号最大5V,选±5V或±10V都可以,但选±10V时分辨率损失一半,我一般选±5V再留20%余量。
最后说去噪。软件滤波可以放在消费者循环里,配合硬件滤波一起用。我的习惯是:采集卡自带抗混叠滤波器打开,然后在LABVIEW里再做一个低通滤波VI,截止频率根据信号特征来定。比如温度信号变化慢,做0.1Hz低通能把大部分噪声抹掉;振动信号就不能乱滤,滤波会破坏相位信息。
3. 生产者消费者架构:程序不卡顿的关键
3.1 为什么状态机做不到实时流畅
很多教材教LABVIEW都是从状态机开始。状态机适合做流程控制,比如按步骤执行“初始化—等待指令—执行指令—复位”,但不适合做连续数据的实时处理,因为单循环里每一步都在同一个线程上排队。你在状态机里加一个更新波形的子VI,数据采集就得等它执行完才能再读取,本末倒置。
生产者消费者就不一样。采集循环是最高优先级的硬实时任务,它只负责持续读取DAQmx数据并塞进队列,不做任何耗时操作;界面更新、文件写入、报警判断全部丢给消费者循环。这样UI卡顿不会反过来阻塞采集线程。
如果你采集频率很低(比如每分钟采一个点),状态机完全够用;但只要你面对的是连续采样、实时性要求高的场景,生产者消费者就是门槛级架构,值得花时间掌握。
3.2 生产者循环怎么写
生产者循环的骨架代码不复杂,核心就是DAQmx Read之后把数据入队。但有几个细节必须处理好:
第一,循环结构里必须包含错误处理。DAQmx读取一旦报错,比如缓存溢出、设备断开,程序不能傻傻退出,而应该把错误信息也入队,让消费者循环去弹窗显示并尝试恢复。
第二,队列类型要定义清楚。我一般定义成变体(Variant),因为不同通道块的类型可能变化;但如果你长期只采同一类型,直接用波形数组更高效,避免变体转换开销。
第三,事件结构的“超时”值不能乱填。有人把事件超时设成-1(无限等待),结果生产者循环里一旦UI事件没触发,DAQmx读取就被卡死。正确做法是把事件结构超时设为0或很短,只用来响应UI消息,真正的采集节拍完全由DAQmx读取的等待时间决定。
生产者循环的伪流程大致是:
- DAQmx Read读取一块波形。
- 把波形数据Enqueue到队列。
- 检查错误状态,错误则把错误对象入队并设置停止标志。
- 判断停止按钮标志,退出循环。
3.3 消费者循环:显示、落盘、报警的活儿全在这
消费者循环从队列里取数据后,要干的活是:更新波形图表、刷新统计量、判断越限、写TDMS文件。这些活如果在生产者循环里干,就会造成上面的卡顿问题。
这里有个平衡点:消费者循环处理速度要跟得上数据产生速度。如果你的波形更新频率是每秒10次,而写TDMS文件每秒只能做5次,队列就会越积越长,最后内存爆炸。解决办法有两个方向,一是减小每次处理的数据量(比如显示时降采样,只画每10个点里的1个),二是把文件写入放到更独立的循环里。
我在实际项目中经常拆成两个消费者:一个负责UI更新,一个负责磁盘写入。UI更新可以适当丢帧,优先保证盘上数据完整。毕竟文件丢了没法补救,界面少画一帧影响不大。
3.4 队列深度与背压:内存和实时性的平衡
队列对象有最大容量设置,超过容量时Enqueue默认会等待(阻塞),直到消费者取出元素腾出空间。这个机制叫背压。背压其实是个保护机制:它让生产者慢下来,避免内存无限涨。但如果背压导致DAQmx读取太慢,采集卡缓存就会溢出,于是报错。所以容量要按“最大可接受延迟”来设。
我给一个参考值:若采样率1kS/s,每次入队100点(10ms的数据量),消费者平均处理0.1ms,那么队列容量设500~1000即可,也就是最多缓冲5~10秒的数据。缓冲区越大,扛突发卡顿能力越强,但数据延迟也越大,而且一旦程序崩溃丢失的数据更多。这个权衡要提前想清楚。
我还习惯给队列设置上限之后,在消费者循环里做监控:周期性检查队列剩余空间,如果长时间低于某个阈值,说明处理速度跟不上,就降低显示刷新率或者升级落盘策略。能做到这一步的程序,基本不太会在正式运行中翻车。
4. 数据显示、交互与落盘:程序是否好用的直观标准
4.1 波形图还是波形图表:两者使用场景完全不同
LABVIEW前面板有两个常被混淆的控件:波形图(Waveform Graph)和波形图表(Waveform Chart)。波形图是强制一次性画完整段数据,适合显示历史数据回放;波形图表是像滚动窗口一样,新数据不断往右追加,适合实时流数据显示。采集程序里,实时监测用波形图表,回放分析用波形图。
多通道显示时,把波形数组绑定到波形图表的输入端子即可。要注意的是如果各通道采样率不同,不能用同一个时间轴直接叠画,得把X轴改成相对时间或者先重采样到统一时间基准。我自己的习惯是:采集端就统一采样率,省去后续对齐的麻烦。
波形图表的历史长度也值得调。默认可能只显示最后几千个点,采样率高的程序里,这个长度几秒钟就滚过去了,根本看不清细节。我在监控界面里把历史长度调到10秒~1分钟,配合一个“暂停显示”按钮,方便现场人员细看异常波形。暂停期间文件照样写,只是界面不更新。
4.2 用户交互体验:按钮、回车触发、时间戳
采集程序的UI交互容易过度复杂。我建议所有按钮尽量少,越少越好,但每一个都要有防误触设计。比如“停止采集”这种按钮,最好弹确认框,防止现场人员误点导致数据中断。比如保存路径配置,用路径控件比文本框直观得多。
这里回应一下热词里的“字符输完按回车触发事件”。LABVIEW里文本框控件默认是在输入内容变化时触发事件“Value Change”,但如果想“输完按回车才触发”,处理方式是在字符串控件的“键按下”事件里判断回车键(Key Down事件里判断KeyCode),或者用“Enter”键触发前面板默认按钮事件。我这套程序里的阈值输入就是用这种方式:输入数字后按回车立即生效,不用每次点确认。
时间戳也很重要。这里有个小坑:如果用“获取日期时间”VI获取系统时间,再用字符串格式化拼进文件名,在子VI里用没问题,但要注意线程安全性。LABVIEW的时间函数是全局安全的,但如果你在并行循环里同时调用格式化时间,偶尔会出现字符缓冲互相覆盖的怪现象。对策是在生产者循环里统一生成一个“采样开始时间”,各循环只引用这一个值,不要各调各的。
4.3 TDMS文件存储:为什么我不用Excel或CSV
真要长时间记录数据,别用Excel、别用CSV。Excel写入慢,文件还容易锁死;CSV文本格式体积大、精度受限,而且写一半程序崩了整个文件可能损坏。NI的TDMS格式是体育界的标杆:二进制存储、自带索引、写得快、体积小,还能给每个通道附属性信息,比如设备编号、传感器灵敏度、量程。
在LABVIEW里写TDMS用TDMS Write VI,数据流和文件句柄顺着循环走就行。我建议一个文件对应一天的数据,文件名带上日期,通道分组按信号类型来分。比如温度通道放一个组,电压通道放一个组,每组里再写几个属性,如采样率、量程、备注。这样事后用DIAdem或Python的npTDMS库回放都方便。
有人问“程序崩了TDMS会不会全毁”,答案是TDMS有较强的容错性,即使异常退出,已经写入的部分仍然可读。这一点在长时间现场监测中非常重要,比文本格式稳定太多。
4.4 扩展:串口、Modbus、TCP与视觉检测
一套数据采集程序,在实际工程里很少孤立存在。最常见的是串口通信:从仪表、PLC、电子秤读数据。LABVIEW的串口API(Serial Port Init、Read、Write)用起来比很多人想象中简单,但“波特率、数据位、校验位”必须和对方设备完全匹配,否则读出来的全是乱码。我自己遇到最多的情况是,仪表是19200 8N1,程序里却默认9600,半天查不出原因。
Modbus也是工业现场的常客。LABVIEW实现Modbus有两种方式:一种是调用Modbus库的现成VI,另一种是直接用串口或TCP发Modbus报文自己解析。如果只是简单读几个寄存器,用现成库最快;但如果要协议定制或者调试底层问题,建议自己写裸报文解析,这样对协议的理解才深入。Debug时可以先用Modbus Poll工具抓包确认设备回包,再一步步对LABVIEW侧解析。
TCP通信一般在两个NI设备之间用得多,比如上位机与NI实时控制器交互。这里有个热词“信息量怎么查询”,我理解成“怎么知道TCP缓冲区里有多少数据待读取”。LABVIEW里直接用TCP Read,如果指定读取字节数超过缓冲区存量,它会等待直到收够才返回,容易卡死。正确做法是在自己的应用协议包头里放“数据长度”字段,先读固定长度的包头,解析出长度,再读对应字节数的包体。这样信息量是应用层自己算出来的,而不是靠驱动查询。
再发散一下,热词里还有“机器视觉零件缺陷检测”。这个方向本质上是图像数据的采集处理,思路和模拟量采集是相通的:图像从相机来,通过NI-IMAQdx或NIVision抓取,进队列,消费者循环再做模板匹配、边缘检测、缺陷判断。LABVIEW在这块的优势是图形化编程跟图像处理算法天然亲近,适合搭原型和做产线联调。如果你要做视觉模板匹配,会用Vision Development Module里的模板匹配VI,参数无非是模板图像、搜索区域、匹配得分阈值这几项,调试方法跟数据采集程序里调阈值是一样的——先把变量显示出来,观察边界条件。
5. 常见问题排查与工程管理
5.1 安装、路径、卸载的坑
很多用户卡在第一步——LABVIEW怎么下载、怎么安装、怎么卸载。“labview安装错误”“labview安装路径”“labview 2015 中文版”这类搜索词常年热门。我整理一份速查,按踩坑频率排序:
- 安装前一定要关杀毒软件和系统防火墙,否则关键DLL会被拦,装到一半报错。
- 安装路径不要带中文和空格,建议就装默认路径,或者C盘根目录下的英文目录。路径里有中文会导致部分范例路径无法解析。
- 版本选择要和自己操作系统位数一致,64位LabVIEW配64位驱动,尽量不要混装32位和64位程序。
- 如果装完提示“缺少NI-DAQmx”或设备管理器里看不到板卡,先装NI-DAQmx驱动再装LabVIEW,顺序反了容易出兼容性报错。
- 卸载的时候不要手动删目录,用NI Package Manager统一卸载,否则残留注册表信息,下次安装会出现诡异错误。
一个老版本兼容策略:很多老工程师对2015中文版有感情,因为界面熟悉、资料多。但新项目我建议直接用新版加LVOOP,跑起来更稳。旧项目能用就不折腾,新项目别被旧版本拖后腿。
5.2 数据不对、漏采、UI卡顿的实用排查
排查数据类问题,我有一套固定的顺序,省时间:
第一,看原始数据。先检查采集卡端子上是否有信号,可以用万用表量一下端子电压,和前面板显示做对比,排除传感器和接线问题。
第二,看量程和接线模式是否匹配。信号0~0.1V,量程却设成±10V,显示出来就是一条贴近零轴的细线,分辨率烂到没法看。
第三,看采样配置。如果你要1kS/s连续采,但Read设置为“有限采样”,程序跑一轮就停,那当然没有连续显示。
第四,看队列缓存。UI卡顿时先检查队列深度是否持续增长,增长就说明消费者处理不过来,优先降显示刷新率。
“漏采”问题十有八九是背压导致DAQmx缓存溢出。排查代码先把消费者循环里的耗时操作全部注释掉,只留队列出队和显示,如果这样不再报缓存溢出,那问题就在消费者循环,逐个加回耗时操作定位。
5.3 代码保护、DLL封装和版本管理
热词里有一条“labview要封装dll才能保护代码吗”。我的看法是:想保护核心算法逻辑,封装成DLL是一个可选方案,但没必要一上来就这么干。LABVIEW本身支持生成源代码保护,也就是构建时排除源码或者加密,但真正要发布给客户用的程序,最稳妥的方式是打包成EXE加依赖,配合试用期控制。
如果你确实要封装DLL,LabVIEW可以生成共享库(Shared Library),导出特定VI。注意DLL里的VI不能依赖前面板控件,参数必须通过输入输出端子传递,这对程序架构有要求。另外,版本管理一定要做。很多人一个人在单机环境写LabVIEW,从来不碰版本管理,直到改崩了没得回退才后悔。LabVIEW项目文件本质是XML,Git可以管理,只是比对不太友好,但总比没有强。我自己的习惯是重要的采集程序每改一个里程碑就打个Tag。
5.4 说点大家关心的:LabVIEW还不被淘汰吗
“labview还不被淘汰吗”这个问题,只要是LabVIEW从业者基本都被问过。我的判断很明确:在仪器控制、数据采集、硬件测试这个细分领域,LabVIEW十年内不会被淘汰,因为它的生态壁垒太深了。NI硬件有一套完整的驱动协议栈,第三方测量仪器几乎都带LabVIEW驱动,成千上万的实验室和产线测试系统已经用LabVIEW写好并且稳定运行,替换成本极高。
但也不要对它有不切实际的期待。LabVIEW不适合做高并发Web服务、不适合做大规模机器学习训练、License费用也确实不低。正确的姿势是把它用在刀刃上:做采集与控制,输出标准化文件,后台分析交给Python、数据库、云平台。一个成熟的工程师应该在LabVIEW之外再掌握一种通用编程语言,这样视野和生存空间会大很多。
6. 动手搭建:一版可复现的最小采集程序
6.1 创建工程和配置通道:完整步骤
下面这套步骤,是我这次分享的项目的搭建路径,照着做能跑通一个最小版本。
第一步,打开LabVIEW,新建项目,创建一个VI,名称就叫“主程序.vi”。记得项目保存路径放在英文目录下。
第二步,在前面板放一个波形图表、一组数值显示控件(当前值、最大值、最小值)、两个数值输入控件(阈值上、阈值下)、一个停止按钮、一个路径控件。
第三步,在程序框图中导入DAQmx相关子VI。右键空白处搜索“DAQmx Create Channel”,下拉选择“AI Voltage”,连接到物理通道字符串。物理通道字符串可以在设备管理器里看到,“Dev1/ai0:3”表示设备1的0到3通道。
第四步,添加“DAQmx Timing”,采样模式选“Continuous Samples”,采样率填1000,每通道采样数填100。
第五步,添加“DAQmx Start Task”,然后让任务引用流到DAQmx Read VI,Read的“每通道采样数”填-1,表示每次读取等量的数据块。
6.2 搭建生产者消费者双循环:手把手顺序
项目跑起来之前,程序框图要先搭好。顺序很重要,新手容易一上来就接一堆线,结果哪条线都是乱的。
第一步,先放一个While循环,作为生产者循环。循环里放DAQmx Read,读取结果接到队列的Enqueue元素。
第二步,创建队列函数,放两处引用:一个在生产者循环外初始化,一个在循环结束后释放。队列元素类型设为“波形(Waveform)”,容量500。
第三步,再放一个While循环,作为消费者循环。循环里放Dequeue元素,取出的波形数据分别接到显示控件、统计VI和TDMS Write。
第四步,生产者循环用“停止按钮”和错误簇共同控制退出条件。消费者循环用“队列出队返回错误”和布尔停止标志控制退出。
第五步,两个循环都结束后,加上Clear Task和Release Queue,保证资源释放干净。
第六步,在消费者循环里加报警逻辑:如果当前通道值超过上限或低于下限,把前面板报警指示灯颜色改成红色,并通过DO通道输出高电平驱动报警灯。
这一步全部接好之后,程序就是一个能跑的最小闭环。剩下的优化可以放在显示刷新降频、TDMS属性字段补充、启动时自动选择路径这些细活上。
6.3 参数参考表与交付自检清单
我把常用参数和面向现场的检查点整理成两张表,拿到别的项目也能直接用。
数据采集核心参数参考表:
| 参数名称 | 推荐值/建议 | 设置说明 |
|---|---|---|
| 采样率 | 信号最高频率的10倍 | 太低丢细节,太高浪费资源 |
| 每通道采样数 | 采样率/100左右 | 每次读取的数据块大小 |
| 队列容量 | 500~1000元素 | 容纳5~10秒数据,抗瞬时卡顿 |
| DAQmx量程 | 信号幅值1.2~1.5倍 | 分辨率与安全余量折中 |
| 接线模式 | 低幅值高噪声用DIFF | RSE适合浮地短距离信号 |
| TDMS文件拆分 | 按天或按批次 | 平衡文件大小和查询方便 |
| UI刷新频率 | 10~~20Hz即可 | 越高越占CPU,人眼看不出来 |
交付前自检清单:
- 断掉信号源时,程序是否报合理错误而不是死循环?
- 停止按钮在连续采集状态下是否能在1秒内响应?
- 连续运行2小时,内存占用是否平稳、队列深度是否稳定?
- 文件用对应工具回放是否正确,通道名和采样率属性是否齐全?
- 换一台电脑安装后是否还能跑,驱动版本依赖是否说明清楚?
我每次交付前都过一遍这套清单,能在现场省下大量维护时间。
最后再分享一个小技巧。不要把“显示”和“存储”绑在同一个循环里死等。我做过一次让显示VI每帧重绘大数组,结果盘上数据跟显示帧率一起掉到惨不忍睹。后来把界面更新改成独立循环,并刻意对波形数据做抽点显示,盘上写入完全不受影响。记住一个原则:现场数据和盘上数据是资产,界面只是资产的一扇窗户。窗户可以偶尔模糊,资产不能丢。这套数据采集处理程序的开发思路,也是围绕这个原则搭出来的。希望这份分享能帮你少踩几个我当年踩过的坑。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/weixin_29159441/article/details/167448045



