入门 PyVISA(五)

读取和写入数值

有些仪器只需一次查询,就能将较大的数据集传输到计算机或从计算机中传输出去。一个典型的例子是示波器,可以查询整个电压轨迹。或者是任意波形发生器,必须将想要生成的函数传送给它。

基本上,此类数据有两种传输方式:ASCII 格式(速度慢,但人类可读)和二进制格式(速度快,但更难调试)。

PyVISA 基于消息的资源为此提供了不同的方法,称为 read_ascii_values()、query_ascii_values() 和 read_binary_values()、query_binary_values()。

读取ASCII值

如果示波器(在变量 inst 中打开)已配置为在发出 CURV? 命令时以 ASCII 格式传输数据,就可以像这样查询数值:

>>> values = inst.query_ascii_values('CURV?')

values 将会是一个包含设备值的列表。

在很多情况下,需要的不是列表,而是不同的container类型,例如 numpy.array。当然,也可以在之后像这样转换数据:

>>> values = np.array(inst.query_ascii_values('CURV?'))

但有时避免使用中间列表会更有效,在这种情况下,你可以在查询中直接指定container类型:

>>> values = inst.query_ascii_values('CURV?', container=numpy.array)

在container中,你可以使用任何可调用/可迭代类型。

有些设备以 ASCII 格式传输数据,但不是十进制数,而是十六进制或八进制。 或者,可能希望接收字符串数组。在这种情况下,可以指定一个转换器。例如,如果希望接收十六进制的整数,可以指定一个转换器:

>>> values = inst.query_ascii_values('CURV?', converter='x')

转换器可以是 Python 字符串格式化代码之一。但如果需要,也可以指定一个只接受一个参数的可调用函数。默认转换器是 "f"。

最后,有些设备可能会以不常用的分隔方式返回值。例如,如果返回值以"$"分隔,则可以执行以下调用:

>>> values = inst.query_ascii_values('CURV?', separator='$')

可以提供一个接收字符串并返回可迭代字符串的函数。分隔符的默认值是","(逗号)。

读取二进制值

如果示波器(在变量 inst 中打开)被配置为在发出 CURV? 命令时以二进制(BINARY)格式传输数据,那么需要知道使用的是哪种数据类型(例如 uint8、int8、single、double 等)。PyVISA 使用与 struct 模块相同的命名约定。

还需要知道字节序。PyVISA 默认为小端。如果双倍值 d 是大端位,调用将是:

>>> values = inst.query_binary_values('CURV?', datatype='d', is_big_endian=True)

还可以指定输出容器类型,就像之前显示的那样。

默认情况下,PyVISA 将假定数据块是按照 IEEE 标准格式化的。如果你的仪器使用 HP 数据块,你可以向 read_binary_values 传递 header_fmt='hp'。如果仪器不使用任何数据头,则只需将 header_fmt='empty' 发送给 read_binary_values。

默认情况下,PyVISA 假定仪器会在数据块末尾添加终止字符,并确保读取数据块末尾的终止字符,以避免出现问题。这种行为非常适合许多设备。但有些设备会省略终止字符,在这种情况下操作会超时。在这种情况下,首先使用 read_raw 函数(可能需要多次调用)读取答案,确保可以从仪器实际读取数据,并检查数据块的广告长度是否与仪器读取的长度一致(加上标头)。如果是这样,就可以放心地传递 expect_termination=False,PyVISA 将不会在报文末尾查找终止字符。

如果可以顺利读取仪器信息,但使用此方法时无法获取完整信息(VI_ERROR_CONN_LOST、VI_ERROR_INV_SETUP 或 Python 崩溃),请尝试传递不同的 chunk_size 值(默认值为 20*1024)。这个问题的根本机制尚不清楚,但改变 chunk_size 已被用来解决这个问题。需要注意的是,对大型传输使用较大的块大小可能会加快传输速度。

在某些情况下,仪器使用的协议可能不会指示传输的字节数。例如,Keithley 2000 总是返回完整的缓冲区,其大小由 trace:points? 命令报告。由于二进制数据块可能包含终止字符,PyVISA 需要知道预计传输的字节数。在这种情况下,您可以使用 data_points 关键字参数传递预期的点数。字节数将根据数据块的数据类型推断。

最后,如果您在读取文件时只想提取字节对象,您可以使用 "s "数据类型,并将字节作为容器传递。

写入 ASCII 数值

要将函数形状上传到任意波形发生器,命令可以是 WLISt:WAVeform:DATA <波形名称>,<函数数据>,其中 <波形名称> 告诉设备以哪个名称存储数据。

>>> values = list(range(100))
>>> inst.write_ascii_values('WLISt:WAVeform:DATA somename,', values)

同样,也可以指定转换器代码。

>>> inst.write_ascii_values('WLISt:WAVeform:DATA somename,', values, converter='x')

分隔符也可以像在 query_ascii_values 中一样指定。

>>> inst.write_ascii_values('WLISt:WAVeform:DATA somename,', values, converter='x', separator='$')

可以提供一个接收可迭代字符串并返回字符串的函数。分隔符的默认值是','(逗号)。

写入二进制值

>>> values = list(range(100))
>>> inst.write_binary_values('WLISt:WAVeform:DATA somename,', values)

同样,也可以指定数据类型和字节序

>>> inst.write_binary_values('WLISt:WAVeform:DATA somename,', values, datatype='d', is_big_endian=False)

如果数据已经包含在字节对象中,则可以使用 "s "格式。

事与愿违时

PyVISA 提供了一种从设备传输数据和向设备传输数据的简便方法。上述方法在 99% 的情况下都能正常工作,但总有一些特定的设备不遵循任何标准协议,而且非常不同,无法使用上述参数进行调整。

在这种情况下,需要获取数据:

>>> inst.write('CURV?')
>>> data = inst.read_raw()

然后你需要实现解析它的逻辑。如果 read_raw 调用失败,也可以尝试只读取几个字节:

>>> inst.write('CURV?')
>>> data = inst.read_bytes(1)

如果调用失败,可能意味着仪器没有应答,可能是因为它需要更多时间,也可能是因为第一个指令没有被理解。

你可能感兴趣的:(PyVISA,python)