PyVISA 实战:用 Python 控制物理实验室常用仪器

@[toc] 1. 行文动机 2. What Do U Need? 3. NI MAX & NI VISA 4. Work In Python 

行文动机

如果你是一名物理系(或是其它的理工科,想来也大差不差)的学生,那么几乎每个学期你都会享受(这个学分少但耗时长)的课程。一开始,看到各式各样的仪器,诸如函数发生器、示波器以及台式万用表等等,会感到相当新奇。

上面的按键看似琳琅满目,然而事实上,你上了几节课之后,就会发现,也不过如此。难道这些几千上万的设备仅仅只能像我们课上那样按一下测一下?如果我希望实现一些更高级的控制应该怎么办?或者哪怕不谈复杂的控制,如果我希望用发生器产生一整天的信号,难道我当真要在实验室里面按一天的按钮?

真这样的话,那大伙的科研都没得做了。此文的行文正是源于此:为大家介绍如何能够通过 python \texttt{python} python编程控制实验室里的设备,以更好的服务自己的实验需求(比如你的科研或是大创项目)。

这或许是从“只是学生”到“开始科研”的第一步

What Do U Need ?

  • 一台电脑(笔记本也OK)
  • 你需要控制的仪器。不用担心我们将要介绍的方式无法控制,因为它几乎可以控制市面上所有支持标准通信接口的测试测量仪器,比如Ethernet、GPIB、serial、USB、VXI和PXI。但是本篇中,我们介绍的是最简单的最简单的USB
  • USB2.0-USB Type B的连接线,如下图所示:
右侧接口即为USB-Type B
在仪器后边,一般会有USB-TypeB插口

NI MAX & NI VISA

NI VISA(Virtual Instrument Software Architecture)是National Instruments开发的一套标准化仪器通信架构,它为GPIB、USB、以太网、串口等各种硬件接口提供了统一的编程接口,让开发者无需关心底层通信细节。NI MAX(Measurement & Automation EXplorer)则是NI VISA配套的图形化管理工具,主要用于自动发现连接的仪器设备、查看和测试VISA资源地址、配置通信参数以及进行基础的设备诊断,是初次配置仪器时的得力助手。

在Python仪器控制中,NI VISA作为底层通信引擎,通过PyVISA库为Python程序提供实际的仪器通信能力,而NI MAX则主要在前期配置阶段发挥作用——帮助用户快速找到仪器的VISA地址,这个地址随后会被写入Python代码中用于建立连接。

NI MAX与NI VISA的官方下载页面: https://www.ni.com/en-us/support/downloads/drivers/download.ni-visa.html

直接下载即可

下载完成后,我们需要打开NI VISA,获取设备的通信地址:

还没有使用USB线连接设备和电脑之前

当我们使用USB线完成设备的连接后,点击Refresh。稍等一段时间,我们就会发现,VISA成功找到了新的设备:

USB

红框圈起来的部分中,USB0::0X1AB...的部分即为通信地址。我们需要做的,只是简单地复制到Python中即可。

Work In Python

为了能够在python中实现对于设备的控制,我们肯定需要安装依赖库:

pip install pyvisa 

安装完依赖库之后,就可以进行对设备的控制了。下面我们结合一些典型操作为大家介绍如何控制:

示例代码基于常见的 USB/TCP/GPIB 设备(示波器、函数发生器、数字万用表)。更详尽的、可直接复制即用的控制代码放在Github仓库https://github.com/HorseRunningWild/PhyExp-Device-Control

1. 库导入 + Resource   Manager \texttt{Resource Manager} Resource Manager

import pyvisa import time import numpy as np import matplotlib.pyplot as plt import openpyxl # 如果要写 Excel# --- 请根据实际情况修改这些地址 --- dmm_address ='USB0::0x1AB1::0x09C4::DM3R240300120::INSTR'# DMM 的地址(示例) func_gen_address ='USB0::0x1AB1::0x0641::DG4E232700999::INSTR'# 函数发生器地址(示例)# 建立 ResourceManager(与 VISA 后端连接) rm = pyvisa.ResourceManager()

说明:

  • ResourceManager() 是和系统的 VISA 库(NI-VISA / Keysight / pyvisa-py 等)对接的入口。
  • 地址字符串是资源字符串(resource string),不同连接方式格式不同:USB、GPIB、TCP/IP(TCPIP::)等。可以用 rm.list_resources() 列出当前能发现的设备。

2. 发现设备(探索可用地址)

print("发现的 VISA 资源:")for r in rm.list_resources():print(" ", r)

说明:

  • 经常第一步就是 list_resources()——把它当“发现附近仪器”的函数。
  • 如果找不到设备,先检查 USB 驱动、线缆、设备电源或 NI-VISA 是否安装正确。
  • 当然,实现这一点本质上是通过NI MAX的,只不过我们没有通过打开NI VISA的方式,而是直接在Python中实现。

3. 打开一个设备并询问标识

inst = rm.open_resource(func_gen_address) inst.timeout =10000# 毫秒级超时,按需要调整 idn = inst.query('*IDN?')# 大多数仪器支持 *IDN? 来返回厂商/型号/序列号print("Instrument ID:", idn.strip())

说明:

  • .open_resource() 返回一个 instrument 对象,用它来 write()(发送命令)和 query()(发送并读取回复)。
  • query() 等于 write() + read(),常用于 SCPI 命令能立即返回的场景。
  • 设置 timeout 很重要:避免无响应时无限挂住。

4. 基本读写模式:

常用的基本读写模式有:.write().query().read().read_raw()

# 写命令(无返回) inst.write(':SOURce1:VOLTage 1.0')# 设置电压(取决于厂商命令)# 读命令(返回字符串) resp = inst.query(':MEASure:VOLTage:DC?') val =float(resp)# 解析为浮点数(若返回数字)

说明与建议:

  • .write():发送不需要返回的命令(例如设置电压、开/关输出)。
  • .query():发送后期望得到立即回复的命令(例如测量)。
  • 有些仪器返回二进制数据(波形),这时候需要用 .read_raw().read_bytes() 并结合二进制解析。

5. 安全关闭(try / finally 模式)

inst =Nonetry: inst = rm.open_resource(dmm_address)# 做一些读取或设置print(inst.query('*IDN?'))finally:# 无论是否发生异常都要确保关闭连接if inst isnotNone:try: inst.close()except Exception:passtry: rm.close()except Exception:pass

说明:

  • 仪器连接资源要在结束时释放(close()),否则下次打开可能失败或者 USB 资源被占用。
  • 推荐把关键段放在 try/finally 中,或使用 context manager(某些 pyvisa 版本支持 with)。

6. 读取示波器二进制波形(通用思路)

示波器通常把波形以二进制块返回,且伴随一段 :WAV:PRE?(preamble)描述缩放信息。把原始样本转换为电压的常见公式:

V = (sample - yref) * yinc + yorg 

下面是一个简化版的读取流程(Rigol / 一些示波器类似):

import numpy as np # 假设 inst 是已连接的示波器对象# 尝试读取 preamble(自带缩放参数) pre = inst.query(':WAV:PRE?')# 例如返回 CSV 字段:format,type,points,count,xinc,xorg,xref,yinc,yorg,yref parts =[p.strip().strip('"')for p in pre.split(',')if p.strip()!='']# 尝试解析常用字段 points =int(parts[2]) yinc =float(parts[7]); yorg =float(parts[8]); yref =float(parts[9])# 读取二进制数据(厂商差异大,可能需要 'WAV:DATA?' 或 ':WAV:FORMat WORD;:WAV:DATA?')# 下面仅示意 pyvisa 的二进制读取 raw = inst.read_raw()# 直接读取原始二进制块,具体命令请先通过 query(':WAV:DATA?') 触发命令# 解析 IEEE 488.2 格式的二进制块头('#' + len + digits ...),这里建议参考厂商文档或直接使用 inst.query_binary_values samples = inst.query_binary_values(':WAV:DATA?', datatype='h', container=np.array)# 'h' = 16-bit signed volts =(samples.astype(np.float64)- yref)* yinc + yorg 

说明:

  • 推荐使用 inst.query_binary_values()(pyvisa 提供)来直接把二进制数据转成数组,datatypeis_big_endian 等参数需根据仪器选择。
  • 一定要先拿到 preamble(缩放参数 yinc/yorg/yref),否则得到的只是“原始计数”。
  • 仪器厂商命令差异大(Keysight/ Rigol/ Tektronix),看设备手册最保险。

7. 将数据保存为 CSV / Excel

import csv # 保存 CSVwithopen('data.csv','w', newline='')as f: writer = csv.writer(f) writer.writerow(['amp_vpp','measured_v'])for a, v inzip(amp_points, measured_v): writer.writerow([a, v])# 写入 Excel(openpyxl 示例)from openpyxl import Workbook wb = Workbook() ws = wb.active ws.append(['amp_vpp','measured_v'])for a, v inzip(amp_points, measured_v): ws.append([a, v]) wb.save('data.xlsx')

说明:

  • CSV 适合快速导出,Excel(openpyxl)适合给非程序员查看或交付报告。
  • 写文件前建议检查目录写权限。

8. 常见问题与排查清单

  • 找不到设备:检查线缆 / 设备电源 / 是否安装 NI-VISA 或 pyvisa-py。运行 rm.list_resources() 看系统是否识别。
  • 命令无响应或阻塞:增加 timeout;用 *IDN? 检查基本通信;确认是否需要先 :SYST:LOCAL 之类的命令切换模式。
  • 二进制读取出错:先打印 :WAV:PRE? 的返回,确认 yinc/yref/yorg;用 inst.query_binary_values() 来简化解析。
  • 频繁查询导致仪器卡住:减慢查询频率、增加 sleep、合并查询、或只在需要时查询(例如每 N 次读一次幅值)。
  • 单位/量程不对:注意仪器的单位命令(VPP / Vrms / Vpp),并在读数前把仪器设置为期望单位。
在放置上述控制Demo代码的Github仓库https://github.com/HorseRunningWild/PhyExp-Device-Control,还有Hill Climbing和PID算法结合实验仪器一同实现测量与控制的脚本,大家可以自行探索。

Read more

部署Qwen3-VL-32b的踩坑实录:多卡跑大模型为何vLLM卡死而llama.cpp却能“大力出奇迹”?

部署Qwen3-VL-32b的踩坑实录:多卡跑大模型为何vLLM卡死而llama.cpp却能“大力出奇迹”?

踩坑实录:多卡跑大模型Qwen-VL,为何vLLM模型加载卡死而llama.cpp奇迹跑通还更快? 前言:部署经历 针对 Qwen2.5-32B-VL-Instruct 满血版模型的部署实战。 手头的环境是一台配备了 4张 NVIDIA A30(24GB显存) 的服务器。按理说,96GB的总显存足以吞下 FP16 精度的 32B 模型(约65GB权重)。然而,在使用业界标杆 vLLM 进行部署时,系统却陷入了诡异的“死锁”——显存占满,但推理毫无反应,最终超时报错。 尝试切换到 Ollama(底层基于 llama.cpp),奇迹发生了:不仅部署成功,而且运行流畅。这引发了我深深的思考:同样的硬件,同样模型,为何两个主流框架的表现天差地别? 本文将围绕PCIe通信瓶颈、Tensor Parallelism(张量并行) 与 Pipeline

By Ne0inhk

在Windows11利用llama.cpp调用Qwen3.5量化模型测试

1.下载llama.cpp二进制文件 访问 https://github.com/ggml-org/llama.cpp/releases 或者 https://bgithub.xyz/ggml-org/llama.cpp/releases 选择适合自己平台的。我没有独立显卡,所以选择CPU版本 https://bgithub.xyz/ggml-org/llama.cpp/releases/download/b8192/llama-b8192-bin-win-cpu-x64.zip 解压到\d\llama8\目录。 2.下载量化模型 按照 章北海mlpy 公众号:Ai学习的老章~ID:mindszhang666 写的知乎文章Qwen3.5 0.8B/2B/

By Ne0inhk

WhisperX语音识别终极完整指南:从零安装到高效使用

WhisperX语音识别终极完整指南:从零安装到高效使用 【免费下载链接】whisperXm-bain/whisperX: 是一个用于实现语音识别和语音合成的 JavaScript 库。适合在需要进行语音识别和语音合成的网页中使用。特点是提供了一种简单、易用的 API,支持多种语音识别和语音合成引擎,并且能够自定义语音识别和语音合成的行为。 项目地址: https://gitcode.com/gh_mirrors/wh/whisperX 想要实现快速语音转文字和精准的说话人分离技术吗?WhisperX正是您需要的解决方案!作为基于OpenAI Whisper的增强版本,WhisperX在语音识别领域提供了前所未有的处理速度和准确性。本指南将带您从零开始,轻松完成WhisperX的安装配置。 🎯 为什么选择WhisperX? 传统语音识别工具往往存在处理速度慢、时间戳不精确等问题。WhisperX通过创新的处理流程,完美解决了这些痛点: * 极速处理:相比传统方法快3-5倍 * 精准对齐:提供单词级别的时间戳标记 * 智能分割:自动识别并分离不同说话人 * 多语言支

By Ne0inhk

GitHub Copilot 教程

文章来源:https://vscode.it-docs.cn/docs/copilot/overview.html GitHub Copilot 为 Visual Studio Code 增加了多代理开发功能。规划好你的方法,然后让AI代理在项目中实现并验证代码变更。并行运行多个代理会话:本地、后台或云端。从一个中心视角管理所有角色。内联建议、内联聊天和智能行为会帮助你完成整个编码流程。 代理与代理会话 代理端到端地处理完整的编码任务。给代理一个高级任务,它会将工作拆分成步骤,编辑文件,运行终端命令,调用工具,并在遇到错误或测试失败时自我纠正。每个任务都运行在一个代理会话中,这是一个持续存在的对话,你可以跟踪、暂停、继续或交接给另一个代理。 重要 你们组织可能在VS Code中禁用了代理。请联系你的管理员以启用此功能。 从中央视图管理会话 并行运行多个代理会话,每个会话专注于不同的任务。聊天面板中的会话视图为你提供了一个统一的地方来监控所有活跃会话,无论是本地运行、后台还是云端运行。查看每次会话的状态,切换,查看文件变更,

By Ne0inhk