Binary transfer of waveform data in float format
This example script demonstrates using the :WAVeform:YFORmat:IBLock:FLOat:YDATa? query to transfer waveform data in 32-bit
single-precision floating-point (float) format to the script's folder.
This example script uses the PyVISA read_raw() method to read the binary data.
Example Script
waveform-data-float-format.py
#!python3
"""This program illustrates getting waveform data in 32-bit
single-precision floating-point (float) format values
in the Infiniium XR8 oscilloscope.
"""
# Import modules.
import pyvisa
import sys
import struct
import numpy as np
import time
import platformdirs
# Global variables.
# oscilloscope_visa_address = "TCPIP0::lab-zir-p1z-2.cos.is.keysight.com::inst0::INSTR"
oscilloscope_visa_address = "TCPIP0::localhost::hislip0,4880::INSTR"
timeout = 20000 # 20 seconds.
# Save Locations
base_file_name = "my_data"
local_base_directory = f"{platformdirs.user_documents_dir()}\\"
def exit_program():
"""Exit program."""
# Close connection to oscilloscope.
sys.stdout.write("Closing oscilloscope connection.\n")
Infiniium.write(":SYSTem:GTLocal") # Unlock GUI.
Infiniium.clear() # Clear oscilloscope communications interface.
Infiniium.close() # Close communications interface to oscilloscope.
rm.close() # Close resource manager.
print("End of program.")
sys.exit()
def check_error_queue(when):
"""Check error queue."""
errors_found = False
while True:
# Keep reading errors until "No error".
error_string = Infiniium.query(":SYSTem:ERRor:NEXT? DIAGnostic")
if error_string: # If there is an error string value.
if error_string.find("0,", 0, 2) == -1: # Not "No error".
errors_found = True
print(f"ERROR: {error_string}")
else: # "No error"
break
else: # :SYSTem:ERRor:NEXT? DIAGnostic should always return string.
errors_found = True
print("ERROR: :SYSTem:ERRor:NEXT? DIAGnostic returned nothing.")
break
if errors_found:
print(f"Exited because error(s) found when: '{when}'")
exit_program()
# ==========================================================
# Main program:
# ==========================================================
# Connect and initialize oscilloscope.
rm = pyvisa.ResourceManager("C:\\Windows\\System32\\visa64.dll")
try:
Infiniium = rm.open_resource(oscilloscope_visa_address)
except Exception:
print(
f"Unable to connect to oscilloscope at {oscilloscope_visa_address}. Aborting program."
)
sys.exit()
Infiniium.timeout = timeout # Set global timeout.
Infiniium.clear() # Clear the instrument bus.
# Lock GUI happens automatically.
# Default Setup.
print("Default Setup.")
Infiniium.write(":SYSTem:DEFault")
# Use auto-scale to automatically set up oscilloscope.
print("Autoscale.")
Infiniium.query(":SYSTem:AUToscale;*OPC?")
# Stop acquisitions and clear the display.
Infiniium.write(":ACQuire:STOP")
Infiniium.write(":ACQuire:CDISplay")
# Capture an acquisition.
Infiniium.write(":ACQuire:POINts:AUTO OFF")
Infiniium.write(":ACQuire:POINts 1048576")
Infiniium.write(":TIMebase:INTerpolate:AUTO OFF")
Infiniium.write(":TIMebase:INTerpolate:METHod NONE")
Infiniium.query(":ACQuire:SINGle;*OPC?")
# Download waveform data.
# Specify the system byte order.
Infiniium.write(":SYSTem:BORDer LENDian")
qresult = Infiniium.query(":SYSTem:BORDer?").strip()
print(f"System byte order: {qresult}")
# Disable sinx/x interpolation.
Infiniium.write(f":TIMebase:INTerpolate:AUTO OFF")
Infiniium.write(f":TIMebase:INTerpolate:METHod NONE")
# Set the waveform source.
channel = "CHANnel1"
Infiniium.write(f":WAVeform:SOURce {channel}") # Set waveform source to channel.
qresult = Infiniium.query(":WAVeform:SOURce?").strip()
print(f"Waveform source: {qresult}")
# Get the number of waveform points.
points = int(Infiniium.query(":WAVeform:YFORmat:POINts?"))
print(f"Waveform points: {points}")
# Get numeric values for later calculations.
x_increment = float(Infiniium.query(":WAVeform:YFORmat:XINCrement?"))
print(f"Waveform X increment: {x_increment:f}")
x_origin = float(Infiniium.query(":WAVeform:YFORmat:XORigin?"))
print(f"Waveform X origin: {x_origin:f}")
# Create time axis.
data_times = (np.linspace(0, points - 1, points) * x_increment) + x_origin
# Get the waveform data.
Infiniium.write(":WAVeform:YFORmat:IBLock:FLOat:YDATa?")
raw_bytes = Infiniium.read_raw()
if not raw_bytes.startswith(b"#0"):
raise ValueError("Invalid indefinite-length block header received.")
# Unpack into list of data values.
data_values = struct.unpack("%df" % points, raw_bytes[2:-1])
print(f"Number of data values: {len(data_values)}")
np_data_values = np.array(data_values)
# Save as CSV.
header = f"Time (s),{channel} (V)\n"
now = time.time() # To show how long it takes to save.
filename = f"{local_base_directory}{base_file_name}_{channel}.csv"
# Using "with open" takes care of a lot of stuff, and no need to explicitly close.
with open(filename, "w") as filehandle: # 'w' means open for writing; can overwrite.
filehandle.write(header)
np.savetxt(filehandle, np.vstack((data_times, data_values)).T, delimiter=",")
# np.vstack basically concatenates the timing info and analog data
# into one 2D array, but it will be shape (2 rows, NPoints columns),
# and typically one wants (NPoints rows,2 columns), and
# the .T (transpose) at the end takes care of that.
print(f"It took {str(time.time() - now)} seconds to save {channel} in csv format.")
# To read the csv data back into Python:
# with open(filename, 'r') as filehandle: # r means open for reading.
# recalled_csv_ch = np.loadtxt(filehandle,delimiter=',',skiprows=1) # Skiprows keeps it from pulling the header in.
del filehandle, filename, header
# Save as a NumPy binary file.
now = time.time() # To show how long it takes to save.
filename = f"{local_base_directory}{base_file_name}_{channel}.npy"
with open(
filename, "wb"
) as filehandle: # 'wb' means open for writing in binary; can overwrite.
np.save(
filehandle, np.vstack((data_times, data_values)).T
) # See comment above regarding np.vstack and .T.
print(f"It took {str(time.time() - now)} seconds to save {channel} in binary format.")
# To read the NumPy binary data back into Python:
# with open(filename, 'rb') as filehandle: # rb means open for reading binary.
# recalled_NPY_ch = np.load(filehandle)
# Check error queue.
check_error_queue("End of program")
# Exit program.
exit_program()
For more information, read the information on the :WAVeform:YFORmat:IBLock:FLOat:YDATa? query