You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从其他程序访问IVI会话,实现Python高效设备多次读数?

问题

我正在使用Python comtypes通过IVI获取M918x PXI DMM测量设备的读数。由于打开设备会话耗时较长,而我需要进行数百次读数,因此希望在一个持续运行的程序中保持会话“存活”,按需轮询获取结果。请问:

  1. 这种方式是否为最优方案?
  2. 该如何实现?

当前代码

import argparse
from comtypes.client import CreateObject

# 读取命令行参数
parser = argparse.ArgumentParser(description='从M918x PXI DMM读取直流电压')
parser.add_argument('--VISA_ADDRESS', default='PXI9::13::0::INSTR', help='从Keysight Connection Expert或NI-MAX获取', type=str)

args, unknown = parser.parse_known_args()             # 解析命令行参数
visa_address = args.VISA_ADDRESS        # 'PXI9::13::0::INSTR'

# 创建对象 - 注意".1"
IVI_COM_AgM918x = CreateObject("AgM918x.AgM918x.1")

# 初始化仪器
IVI_COM_AgM918x.Initialize(visa_address, False, False, "")

# 进行直流电压测量,量程200V,分辨率0.01V
retval = IVI_COM_AgM918x.DCVoltage.Measure(200.0, 0.01, True)
print(retval)

# 关闭仪器会话
IVI_COM_AgM918x.Close()

我的设想

运行一个程序完成会话初始化:

# 创建对象 - 注意".1"
IVI_COM_AgM918x = CreateObject("AgM918x.AgM918x.1")
    
# 初始化仪器
IVI_COM_AgM918x.Initialize(visa_address, False, False, "")

之后需要读数时执行:

# 进行直流电压测量,量程200V,分辨率0.01V
retval = IVI_COM_AgM918x.DCVoltage.Measure(200.0, 0.01, True)
print(retval)

回答

1. 保持会话存活是否为最优方案?

是,这绝对是你当前场景的最优方案,原因如下:

  • IVI仪器的Initialize操作包含建立VISA连接、加载配置、初始化硬件等步骤,重复执行会带来显著时间开销,几百次测量的累计延迟会非常可观。
  • IVI规范本身支持长期保持会话,只要仪器连接稳定,复用同一个会话完全符合设备使用逻辑,不会对硬件造成额外负担。
  • 复用会话能避免频繁断连重连可能引发的通信异常,提升测量稳定性。

2. 具体实现方式

你可以将会话初始化与读数逻辑整合到一个持续运行的程序中,以下是几种实用方案:

方案一:固定次数循环轮询

适合预先知道测量次数的场景:

import argparse
import time
from comtypes.client import CreateObject

def main():
    parser = argparse.ArgumentParser(description='从M918x PXI DMM批量读取直流电压')
    parser.add_argument('--VISA_ADDRESS', default='PXI9::13::0::INSTR', help='从Keysight Connection Expert或NI-MAX获取', type=str)
    parser.add_argument('--count', default=100, help='测量次数', type=int)
    parser.add_argument('--interval', default=1, help='测量间隔(秒)', type=float)
    args = parser.parse_args()

    # 仅初始化一次会话
    dmm = CreateObject("AgM918x.AgM918x.1")
    dmm.Initialize(args.VISA_ADDRESS, False, False, "")
    
    try:
        for i in range(args.count):
            retval = dmm.DCVoltage.Measure(200.0, 0.01, True)
            print(f"第{i+1}次测量结果: {retval}V")
            time.sleep(args.interval)
    finally:
        # 确保无论是否异常,都关闭会话
        dmm.Close()

if __name__ == "__main__":
    main()

方案二:手动触发按需读数

适合需要人工控制测量时机的场景:

import argparse
from comtypes.client import CreateObject

def main():
    parser = argparse.ArgumentParser(description='从M918x PXI DMM手动触发读取直流电压')
    parser.add_argument('--VISA_ADDRESS', default='PXI9::13::0::INSTR', help='从Keysight Connection Expert或NI-MAX获取', type=str)
    args = parser.parse_args()

    # 初始化会话
    dmm = CreateObject("AgM918x.AgM918x.1")
    dmm.Initialize(args.VISA_ADDRESS, False, False, "")
    
    print("仪器已初始化,输入'r'读取测量值,输入'q'退出程序")
    
    try:
        while True:
            cmd = input("> ").strip().lower()
            if cmd == 'r':
                retval = dmm.DCVoltage.Measure(200.0, 0.01, True)
                print(f"测量结果: {retval}V")
            elif cmd == 'q':
                print("退出程序,关闭仪器会话")
                break
            else:
                print("无效指令,请输入'r'读取或'q'退出")
    finally:
        dmm.Close()

if __name__ == "__main__":
    main()

关键注意事项

  • 必须使用try...finally块保证会话最终被关闭,避免仪器资源泄漏。
  • 若测量间隔较长,可定期发送简单查询(如读取仪器ID)保持连接活跃,防止超时断开。
  • 长时间运行的程序建议添加异常捕获,处理通信中断并尝试重新初始化会话。

内容的提问来源于stack exchange,提问作者DarkLight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:39:52