Jitter Measurements
This simple Python script, measure-jitter.py, makes some Jitter measurements.
Script
measure-jitter.py
#!python3
"""This program illustrates making Jitter measurements in
the Infiniium XR8 oscilloscope.
"""
# Import modules.
import pyvisa
import sys
from matplotlib.ticker import EngFormatter
# Global variables.
oscilloscope_visa_address = "TCPIP0::localhost::hislip0,4880::INSTR"
timeout = 20000 # 20 seconds.
eng_s = EngFormatter(unit="s", places=2, sep=" ")
eng_V = EngFormatter(unit="V", places=2, sep=" ")
# Files location.
standard_folder = "C:\\Users\\pw5670\\Documents\\Keysight\\Infiniium\\"
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.
# Move waveform file to oscilloscope disk.
wfm_data_file = "Jitter_Noise.h5"
wfm_data_file_local = f"../{wfm_data_file}"
wfm_data_file_osc = f"{standard_folder}{wfm_data_file}"
f = open(wfm_data_file_local, "rb")
file_bytes = f.read()
f.close()
message = f':DISK:FILE:WRITe? "{wfm_data_file_osc}",'
Infiniium.write_binary_values(message, file_bytes, datatype="s")
success_or_failure = Infiniium.read().strip()
if success_or_failure == "1":
print(f"Local file copied to oscilloscope disk: {wfm_data_file_osc}")
else:
print(f"FAILURE copying local file to oscilloscope disk: {wfm_data_file_osc}")
# Default Setup.
print("Default Setup.")
Infiniium.write(":SYSTem:DEFault")
# Stop acquisitions and clear the display.
Infiniium.write(":ACQuire:STOP")
Infiniium.write(":ACQuire:CDISplay")
# Load waveform data from oscilloscope disk into waveform memory.
Infiniium.write(f':WMEMory1:FILE:NAME "{wfm_data_file_osc}"')
Infiniium.write(":WMEMory1:FILE:LOAD")
print(f"Waveform data loaded from oscilloscope disk: {wfm_data_file_osc}")
# Turn off channel 1.
Infiniium.write(":CHANnel1:DISPlay OFF")
# Make jitter measurements.
Infiniium.write(":MEASure:JITTer1:JITTer:RJBandwidth NARRow")
Infiniium.write(":MEASure:JITTer1:JITTer:TJBer 1E-12")
Infiniium.write(":MEASure:JITTer1:JITTer:EDGE BOTH")
Infiniium.write(":MEASure:JITTer1:JITTer:SMEThod SPECtral")
Infiniium.write(":MEASure:JITTer1:JITTer:MODE TPHase")
Infiniium.write(":MEASure:JITTer1:JITTer:EOPening SER")
Infiniium.write(":MEASure:JITTer1:JITTer:PTYPe PERiodic")
Infiniium.write(":MEASure:JITTer1:SOURce WMEMory1")
Infiniium.write(":MEASure:JITTer1:JITTer:UNITs SECond")
jitter_results_dict = {}
Infiniium.write(f":MEASure:JITTer1:JITTer:ANALysis ON")
jitter_measurements = ["EWIDth", "TJ"]
for meas in jitter_measurements:
result = float(Infiniium.query(f":MEASure:JITTer1:JITTer:{meas}?"))
status = Infiniium.query(f":MEASure:JITTer1:JITTer:{meas}:STATus?").strip()
reason = Infiniium.query(f":MEASure:JITTer1:JITTer:{meas}:STATus:REASon?").strip()
jitter_results_dict[meas] = (result, status, reason)
# Make noise measurements.
Infiniium.write(":MEASure:JITTer:NOISe:RNBandwidth WIDE")
Infiniium.write(":MEASure:JITTer:NOISe:MLOCation 50")
Infiniium.write(":MEASure:JITTer:NOISe:UNITs VOLT")
noise_results_dict = {}
Infiniium.write(f":MEASure:JITTer1:NOISe:ANALysis ON")
noise_measurements = [
["EHEight", ""],
["TI", "LEVel1"],
["TI", "LEVel0"],
]
for meas, level in noise_measurements:
if level != "":
Infiniium.write(f":MEASure:JITTer1:NOISe:{meas}:LEVel {level}")
result = float(Infiniium.query(f":MEASure:JITTer1:NOISe:{meas}?"))
status = Infiniium.query(f":MEASure:JITTer1:NOISe:{meas}:STATus?").strip()
reason = Infiniium.query(f":MEASure:JITTer1:NOISe:{meas}:STATus:REASon?").strip()
noise_results_dict[(meas, level)] = (result, status, reason)
# Print selected results.
print("Jitter measurement results:")
for meas in jitter_measurements:
(result, status, reason) = jitter_results_dict[meas]
if status != "CORR":
print(f"{meas}: {eng_s(result)}, status: {status}, reason: {reason}")
else:
print(f"{meas}: {eng_s(result)}")
print("Noise measurement results:")
for meas, level in noise_measurements:
(result, status, reason) = noise_results_dict[(meas, level)]
if level != "":
if status != "CORR":
print(
f"{meas} ({level}): {eng_V(result)}, status: {status}, reason: {reason}"
)
else:
print(f"{meas} ({level}): {eng_V(result)}")
else:
if status != "CORR":
print(f"{meas}: {eng_V(result)}, status: {status}, reason: {reason}")
else:
print(f"{meas}: {eng_V(result)}")
# Check error queue.
check_error_queue("End of program")
# Exit program.
exit_program()