ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Agilent 34970A LabVIEW驱动全解析:从VISA到SCPI

Agilent 34970A LabVIEW驱动全解析:从VISA到SCPI 简介一套面向安捷伦34970A数据采集器的LabVIEW驱动程序例程适用于在LabVIEW环境下开发测试测量与自动化控制应用的工程师解决设备通信、测量参数配置、多通道扫描切换和数据读取等常见需求。压缩包共72个文件以60个vi子程序为核心并包含7个mnu菜单文件、1个lvlib库文件、1个lvproj工程文件以及aliases、html、bin3等辅助文件整体仅1.29MB便于快速下载与部署。驱动覆盖设备连接、配置测量、扫描和切换、数据回读及错误处理等关键环节并附有高级扫描、EZ扫描、矩阵开关、RF复用等示例VI可直接借鉴或二次开发。目前已有2396人学习下载适合需要快速将34970A接入LabVIEW测试系统或希望参考成熟驱动结构完成自主开发的工程师。 前阵子做环境试验数据记录桌上那台Agilent 34970A采集单元是二十多年前的老产品稳定可靠实验室一直舍不得换。接手后的第一件事是想把它接入新部署的LabVIEW上位机实现自动采集。翻遍手头文档和论坛帖子发现一个有意思的现象大家聊“agilent_34970 LabVIEW驱动程序”时说的根本不是同一件事。有人让去Keysight官网下载IO Libraries Suite有人让装NI-VISA还有人直接扔来一个34970A专用驱动包结果装了之后设备管理器里什么都看不到。这篇文章就把这块彻底讲透包括驱动层级怎么分、软硬件环境怎么搭、最小通信程序怎么写、扫描数据怎么解析以及项目中实际踩过的几个坑。适合刚接触34970A和LabVIEW的测试工程师以及想把老式台架仪器变成自动化测试节点的人。1. 为什么大多数人卡在“34970A驱动”这一步很多帖子把“驱动”混在一起说是最大的认知障碍。对34970A这种台式仪器来说“能被LabVIEW控制”需要三层都通才行。第一层是物理传输层。GPIB卡需要装IEEE-488驱动USB-GPIB转接器需要装USB驱动串口直接用系统自带驱动或USB转串口芯片驱动。这一层搞不定时电脑根本认不到硬件操作系统提示“无法验证驱动数字签名”“设备代码39”等错误。第二层是VISA层。这一层相当于仪器通信的公共API。NI-VISA和Keysight IO Libraries Suite都实现了VISA标准负责把“GPIB0::1::INSTR”“ASRL1::INSTR”这种资源字符串映射到底层总线协议。LabVIEW的VISA函数选板就是通过这一层发命令的。第三层才是仪器本身支持的SCPI命令集。34970A出厂支持标准SCPI命令比如*IDN?查身份、MEAS:VOLT:DC?测电压。这不叫“Windows驱动”而是“仪器固件自带的解析协议”。很多人去设备管理器里找34970A当然找不到。它又不是PCI板卡不是靠某个.inf文件枚举出来的设备。正确思路是先打通前两层再用SCPI命令去控制。理解了这一点后面的路就顺了。1.1 “驱动”这个词实际指三层东西继续把三层展开说。GPIB场景下物理传输层往往最折腾。NI GPIB-USB-HS插入电脑后如果没装NI-488.2驱动设备管理器里会出现一个带问号的未知设备。你即使装了NI-VISA也可能因为底层488.2没就绪而找不到资源。串口场景相对简单但老电脑的原生COM口越来越少USB转串口芯片的兼容性又千奇百怪。建议优先选FTDI芯片的转接线兼容性明显比某些国产裸芯片好。VISA层装好后会提供一个资源管理工具。NI的设备用NI-MAXKeysight设备用Connection Expert。它们的职责是扫描总线上挂的仪器并给每个仪器分配唯一的VISA资源名称。实际项目中我见过有人把仪器地址设成GPIB1::1但NI-MAX扫描时总线号是0于是怎么连都超时。不是设备坏了就只是那位工程师没搞清“总线号、设备地址”这两组数字的含义。SCPI命令层是最后要攻克的部分。34970A作为老一代产品命令集非常标准网上所有例程几乎都绕不开CONF、MEAS、ROUT:SCAN、FETC这几条。只要物理层和VISA层稳定SCPI命令本身很少出错。真正容易错的是通道语法和返回数据的解析这一点后面单独说。1.2 你该装的到底是哪个“驱动”接下来面对的选择是装NI-VISA还是Keysight IO Libraries Suite我见到的失败案例多半是两者都装过、版本还互相冲突或者用了NI-MAX去连接一个Keysight Connection Expert创建的别名。我的建议是如果手里的接口硬件是NI GPIB-USB-HS、NI PCI-GPIB这类装NI-VISA用NI-MAX做自检。如果使用的是Agilent 82357B USB-GPIB或者直接走34970A的RS-232串口装Keysight IO Libraries Suite会更顺手它自带Connection Expert能主动扫描总线上所有设备。注意两个软件可以在同一台电脑上共存但不要让两者同时去管理同一个接口卡。实际项目里我习惯以NI-VISA为主因为LabVIEW自带的就是VISA函数选板开发时不需要额外配置如果客户现场没有NI硬件改用纯串口连接我也仍然用NI-VISA访问ASRL资源这样程序换台电脑就能跑。官网那个“34970A LabVIEW驱动”要不要下其实它是一个旧式软面板和一堆LabVIEW子VI用于演示功能。我看到很多人装完这个“驱动”后还是一脸懵原因是他们连VISA通信都没调通。所以别把它当成必需品先跑通*IDN?再决定要不要用它的封装。2. 环境搭建的坑GPIB、串口、USB转GPIB怎么选2.1 不同连接方式下的VISA地址怎么填34970A的通信接口主要有GPIB和RS-232两种。34972A增加了LAN和USB但很多老实验室还在用34970A。接口选择直接决定VISA资源名连接方式VISA资源示例注意事项GPIB如NI GPIB-USB-HSGPIB0::1::INSTR仪器面板上的GPIB地址必须和地址位数一致RS-232串口ASRL3::INSTRWindows下的COM口编号可能与物理口不一致Agilent 82357B USB转GPIBGPIB1::1::INSTR82357B的驱动为Keysight IO LibrariesNI-MAX不一定识别先解决一个小问题34970A的GPIB出厂地址是多少不同批次不完全相同我见过0和1都有千万别想当然。正确做法是开机按Utility翻到GPIB Address页面确认电脑端NI-MAX或Keysight Connection Expert里也填同样地址。RS-232的坑更多。34970A后面板是九针串口和普通PC串口一样需要确认波特率、数据位、奇偶校验、停止位与前面板设置一致。很多老手册默认写9600-8-N-1但我建议开机后在Utility里重新核对一遍因为如果设备之前被人改过配置用错波特率时仪器不报错只是Read一直超时。2.2 驱动安装后最常见的三个报错我在不同电脑上装过很多次报错主要集中在这三类第一个是Windows安装USB转GPIB或老USB转串口芯片驱动时提示“数字签名无法验证”。这通常是驱动版本太旧、没有微软签名。解决路径有两个一是换厂商发布的新版签过名的驱动二是临时进入“禁用驱动程序强制签名”模式装上旧驱动。后者是应急手段不建议作为长期方案。第二个是NI-MAX连接时报“VISA资源无效或找不到设备”。这种情况先别怀疑硬件坏了多数是因为设备管理器中GPIB接口卡没识别或者连接软件选错了VISA地址。用NI-MAX的“扫描VISA资源”按钮看看实际出现的是什么地址通常一切物理连接正常时GPIB0::1::INSTR会自动列出来。第三个是点击VISA测试面板发送*IDN?后一直超时。如果物理层驱动都正常重点检查SCPI命令结尾的换行符。GPIB方式下我一般用\nRS-232方式下要确认终止符匹配。LabVIEW里可以在VISA Configure Serial Port中把终止符设成0xA否则命令会一直攒在缓冲区里。3. 从*IDN?开始用LabVIEW VISA写最小通信驱动3.1 最小通信程序的完整链路环境就绪后写第一段LabVIEW程序。我的习惯是永远从身份查询开始先发*IDN?收到正确响应才说明VISA层、地址、SCPI协议全部通畅。后续所有功能都建立在这个最小链路上。LabVIEW中的节点调用顺序是VISA Open输入VISA资源名称如GPIB0::1::INSTR或ASRL3::INSTRVISA Write写入命令字符串例如*IDN?\nVISA Read从仪器缓冲读回结果如“Agilent Technologies,34970A,...”VISA Close关闭会话。一个关键细节是VISA Read需要预先指定缓冲区大小。很多初学者的程序读一个短回答没问题一旦扫描一串数据返回就乱码所以我习惯先调用VISA的属性节点Bytes at Port读到可用字节数后再动态决定VISA Read的缓冲区长度。如果是GPIB则可以先把缓冲区设成4096等读到完整数据后按实际长度截断。另外向34970A发送命令时字符串末尾的换行符不能省。虽然SCPI也接受LF作为命令终止符但如果你用NI-VISA默认设置Write末尾不带结束符的话仪器会一直等在那里直到超时。可以认为VISA底层会把\n字节发出去如果你的命令字符串里已经带了\n就不要在串口配置里再添加终止符否则容易出现双终止符导致命令解析错乱。3.2 把通信封装成可复用的Command/Query子VI每次写Open、Write、Read、Close太啰嗦也容易漏错误处理。我通常做两个子VICommand.vi负责发一条无返回命令比如*RST、INIT。内部结构是Open、Write、Close任何一步出错都把错误簇向上传。Query.vi负责发一条带返回的命令比如*IDN?、MEAS:VOLT:DC?。内部结构是Open、Write、Read、Close返回VISA Read读到的字符串。这两个子VI做好后主程序里的逻辑就变成“搭积木”。例如想读取电压资源名GPIB0::1::INSTR 命令MEAS:VOLT:DC 10,1e-3,(101) 返回值示例9.88000000E-01用Query.vi拿到字符串再转成浮点数就完成了。子VI里要注意的是关闭VISA会话之前要把Read剩余缓冲清掉否则下次打开时老数据会串进来。方法是在Close前发一个*CLS清状态寄存器。如果只是发测量命令而不读下一次查询结果会混乱。4. 扫描列表与数据解析把实际采集流程真正跑通4.1 用SCPI配置扫描列表的推荐流程34970A做多点采集时我一般不用逐通道发送MEAS?而是配置扫描列表让机器按顺序扫描后一次性返回所有数据。这样效率高也避免继电器反复切换带来的串扰。推荐命令序列*RST CONF:VOLT:DC 10,1e-3,(101:110) ROUT:SCAN (101:110) TRIG:SOUR IMM INIT FETC?解释一下CONF:VOLT:DC 10,1e-3,(101:110)表示配置101到110通道为直流电压测量量程10V分辨率1mVROUT:SCAN设定扫描通道列表TRIG:SOUR IMM表示立即触发INIT初始化测量FETC?把结果一次性读出来。通道号是这种仪器特有的语法(101:110)中“101”指的是1号插槽的01通道“110”是1号插槽的10通道。千万不要写成(1:10)。我第一次调试就在这里卡了半天以为是地址配置问题实际上纯粹是通道语法理解错了。如果你要扫描温度、电压混合信号可以用CONF:TEMP TC,K,(101)配置热电偶再用ROUT:SCAN把热电偶和电压通道放同一个列表。不同测量功能混扫是34970A的强项配置上只会稍微繁琐一点。4.2 从ASCII到数组解析返回字符串FETC?返回的是一长串ASCII码多个数值用逗号分隔类似9.88000000E-01,1.92000000E00,4.95000000E00在LabVIEW里最省事的工具是“Spreadsheet String To Array”函数它可以把逗号分隔的字符串按分隔符拆开转成数值数组。注意“Delimiter”输入要填英文逗号。如果返回数据里还带换行符别忘先用Trim Whitespace清理。还有一个坑如果扫描通道很多或仪器内部扫描时间较长FETC?并不会立刻把数据准备好。LabVIEW的VISA Read只做一次读不到指定长度就会超时。我的做法是在Query.vi里加一个等待循环先等一定时间再反复用属性节点查询Bytes at Port直到数据完整或者干脆把VISA Timeout设成5秒并在INIT后延时几百毫秒再执行FETC?。具体延时取决于扫描通道数和继电器稳定时间。4.3 二进制格式的坑4字节转浮点数网上搜34970A数据解析时经常会看到“将4字节数据转换为浮点数”的提问这多半涉及SCPI的二进制传输模式。命令FORMAT:DATA HEX可以把测量结果输出成二进制十六进制流每个浮点数占4字节。这样做传输快但必须按IEEE-754格式拼回浮点数。34970A的二进制数据按IEEE-754单精度浮点格式排列四个字节拆出来之后要注意字节序。LabVIEW中可以用“Unflatten From String”函数选Single精度也可以自己把HEX字符串转成U8数组再组合成U32最后用变体函数转Single。如果只是做测试记录我更建议直接用默认ASCII模式牺牲一点传输速度换来足够简单。只有当扫描速度超过每秒几十个通道才值得考虑二进制模式。一个更容易被忽略的点切到二进制格式后*TRG触发、数据结束判定方式都变了如果沿用ASCII解析会出现数据错位问题。所以除非有明确性能需求否则我劝你先别碰二进制。5. 做成可维护的驱动包我的落地经验和易错点5.1 生产者-消费者架构处理长时间采集从最小通信到扫描采集剩下的问题就是怎么把程序做得稳定。我的建议是别把采集逻辑全塞进一个While循环里尤其不要在一个事件结构里做长时间等待。比较稳的框架是生产者-消费者UI事件循环生产者负责按用户设置生成采集任务通过队列发给采集循环采集循环消费者负责执行Command/Query、解析数据、写入文件再把状态通过通知发回UI。这个结构的好处是测量过程不会被前面板的按钮点击阻塞也不会因为写文件慢而漏掉下一次采集。采集循环内部建议使用状态机初始化、配置、开始扫描、读取数据、解析数据、记录、停止。每次循环之间通过队列或变量传递配置状态跳转清晰。对34970A这种老设备这种结构已经足够应对绝大多数环境试验、电池老化测试和传感器标定需求。5.2 远程模式与前面板的冲突处理34970A进入远程控制模式后前面板很多按键会变成灰色这是正常现象。调试程序时如果你在电脑端把仪器设成了远程模式关掉软件后面板没反应不要急着拔电源。先执行SYST:LOC或发送GTL指令让它回到本地模式即可。我的程序通常初始化时先发*CLS清状态、*RST恢复默认配置、再发SYST:REM进入远程模式。进入远程前还要检查仪器上是否有人正在手动操作有些老工程师习惯先在前面板设置量程再在电脑端启动程序。如果初始化里直接*RST会把人家设的量程都清掉造成误会。现在的做法是初始化时只发*CLS和SYST:REM把具体配置交给用户界面填写的参数只有在用户点“恢复默认”时才发*RST。5.3 三个最容易被忽略的时序问题第一是继电器稳定时间。34970A内部扫描用的是机械继电器切换后电压或温度读数会有短暂波动。如果扫描速度太快前几个点可能不以稳定值。建议在扫描配置里加ROUT:SCAN:DEL设置一点延迟比如10ms到100ms。做精密电压测量时我甚至会设为200ms虽然牺牲速度但数据干净。第二是自动量程对首测读数的影响。第一次用MEAS:VOLT:DC?时如果仪器正在自动量程结果可能偏大或接近满量程。稳一点的做法是先发一次CONF:VOLT:DC指定好量程再触发测量。这样第一个点也可靠。第三是长时间采集后的VISA会话释放问题。如果程序每秒钟打开一次VISA会话再关闭连续跑一两天后可能出现“VISA resource not found”的诡异现象。排查下来往往是Close在出错分支里没有执行。所以子VI的错误处理一定不能偷懒即使Read超时了也要保证Close执行、会话释放。一个不错的技巧是使用LabVIEW的错误合并接线把Open、Write、Read、Close连成串最后统一输出错误簇这样即使中途出错也不会漏掉Close。最后分享一个很实用的习惯把Command.vi和Query.vi连同34970A的资源名称设置一起封装成独立配置模块每次实验只要填一个仪器资源名就能在任何LabVIEW版本里快速调用。这套代码可以跨项目复用从34970A换到34972A时唯一要改的只是资源字符串和个别命令。多年下来我最深的体会是老仪器的“驱动”不是靠某个安装包解决的而是靠把通信链路理清楚、把数据解析做扎实。把最小驱动写好后后面再复杂的测量需求都能稳步扩展。本文还有配套的精品资源点击获取
返回列表