3. 自动化平台开发环境搭建

自动化测试平台能否稳定运行,第一道门槛并不在脚本逻辑,而在开发环境与仪表通信链路是否真正打通。本节围绕一条最小可用链路展开:在 Windows 主机上安装 Python 与 .NET 开发环境,安装 VISA 运行时(NI-VISA 或 R&S VISA),通过 PyVISA 或 C# 的 VISA 接口访问仪表,最后用 NI-MAX 与脚本双重验证连通性。理解这条链路的层次关系,比记住安装顺序更重要。

一、先理清通信栈的层次

PC 与 R&S 仪表之间的通信可以抽象为四层:最底层是物理接口(USB、LAN、GPIB 或串口),其上是 VISA 运行时提供的统一 I/O 抽象层,再往上是语言绑定(PyVISA、NI-VISA .NET、R&S VISA 的 C/C++ API),最上层才是测试脚本。VISA 的价值在于屏蔽不同总线的差异,让 write/read 或 query 这类操作对 USB 和 LAN 保持一致。因此,环境搭建的核心不是“装软件”,而是让这四层各自就位并互相可见。

PC 与 R&S 仪表通信栈与连通性验证路径 R&S 仪表 SCPI 命令解析 USB / LAN / GPIB 接口 VISA 资源地址 如 TCPIP::192.168.1.50::INSTR 或 USB0::0x0AAD::0x0118::... *IDN? 返回厂商/型号/序列号/固件 Windows 开发主机 应用层 Python 脚本 / C# 程序 语言绑定层 PyVISA / VISA .NET VISA 运行时层 NI-VISA 或 R&S VISA(二者择一,避免冲突) 物理接口层 USB 驱动 / 网卡 / GPIB 卡 NI-MAX 用于枚举资源、发 *IDN? 自检

二、Python 与 C# 开发环境

Python 侧建议使用 3.9~3.12 的 64 位版本,安装时勾选“Add Python to PATH”。创建独立虚拟环境可避免依赖污染:

python -m venv rsauto
rsauto\Scripts\activate
pip install pyvisa pyvisa-py numpy
pip install pyvisa-py   # 若使用纯 Python 后端而非 NI-VISA

C# 侧推荐 Visual Studio 2022 或 VS Code + .NET SDK 8。新建控制台项目后,通过 NuGet 安装 VISA 绑定包,例如 NationalInstruments.Visa 或 R&S 提供的 .NET 程序集。若使用 R&S VISA,需在项目中引用其安装目录下的 RsVisa32.dll 或对应 .NET 封装。

三、VISA 运行时的选择与安装

NI-VISA 与 R&S VISA 都实现了 VISA 规范,但同一台机器上同时安装两者容易造成资源地址解析冲突。工程上通常二选一:若仪表以 R&S 为主,优先安装 R&S VISA;若还需兼容其他厂商设备,NI-VISA 的通用性更好。安装后务必重启,使 USB 驱动与 VISA 服务生效。

安装完成后,在命令行执行 pip install pyvisa 后运行 python -m visa info,可查看 PyVISA 当前使用的后端库及其版本,这是排查“找不到设备”的第一手信息。

四、NI-MAX 枚举与自检

NI-MAX(Measurement & Automation Explorer)是验证链路的图形化入口。打开后展开“设备和接口”,应能看到已识别的仪表资源。选中设备后点击“打开 VISA 测试面板”,在输入框发送 *IDN?,正常应返回类似:

Rohde&Schwarz,FPC1500,123456,1.20

若此处无返回,问题一定在 VISA 层或物理层,与 Python/C# 代码无关。常见原因包括:USB 线仅供电不传数据、LAN 网段与仪表不在同一子网、防火墙拦截、VISA 未安装对应总线驱动。

五、PyVISA 连通性验证

NI-MAX 通过后,用 PyVISA 做脚本级验证。以下示例假设仪表 LAN 地址为 192.168.1.50,实际使用时替换为 NI-MAX 中显示的资源字符串:

import pyvisa

rm = pyvisa.ResourceManager()
print(rm.list_resources())

inst = rm.open_resource('TCPIP0::192.168.1.50::INSTR')
inst.timeout = 5000
print(inst.query('*IDN?'))

inst.write('*RST')
inst.write('FREQ:CENT 1GHz')
print(inst.query('FREQ:CENT?'))
inst.close()

判断标准:list_resources() 能列出目标地址;*IDN? 返回四段式字符串;设置中心频率后回读值与设定值一致(示例中为 1GHz,实际回读可能带单位或科学计数法)。若 list_resources() 为空,检查后端是否为 @py 或系统 VISA;若超时,先确认 NI-MAX 中同一地址能否通信。

六、C# 侧最小验证

C# 中通过 VISA 会话打开资源并查询,逻辑与 PyVISA 一致:

using NationalInstruments.Visa;
using var rm = new ResourceManager();
using var session = (MessageBasedSession)rm.Open("TCPIP0::192.168.1.50::INSTR");
session.RawIO.Write("*IDN?\n");
Console.WriteLine(session.RawIO.ReadString());
session.RawIO.Write("FREQ:CENT 1GHz\n");
session.RawIO.Write("FREQ:CENT?\n");
Console.WriteLine(session.RawIO.ReadString());

注意 C# 写入 SCPI 命令时通常需要显式换行符 \n,而 PyVISA 的 write 默认会追加终止符,这是两种绑定在细节上的差异。

七、连通性验证检查表

检查项预期结果不通过时的排查方向
设备管理器识别仪表出现对应 USB/网络设备换线、换口、装驱动
NI-MAX 枚举资源列出 TCPIP/USB 资源地址VISA 未装、网段不符、防火墙
NI-MAX 发 *IDN?返回厂商、型号、序列号、固件接口配置、终止符、仪表远程模式
PyVISA list_resources包含目标地址后端选择、环境变量
PyVISA query *IDN?与 NI-MAX 一致超时设置、资源字符串拼写
C# 打开会话并查询控制台输出 IDN 字符串程序集引用、平台目标 x64
若同时安装 NI-VISA 与 R&S VISA,可能出现同一仪表被两个运行时重复枚举或地址冲突。建议在“程序和功能”中卸载不用的一个,并清理系统 PATH 中多余的 VISA 目录,再重启验证。