Measure Eye Width Over Time
This Python example, measure-eye-width-over-time-graph-results.py, demonstrates monitoring a measurement (Eye Width) over time. The resulting data is shown in a matplotlib window. If you do not wish to import the matplotlib library, comment out the draw_graph() function.
The function, monitor_eye_width(), records the data and the create_time_data() function scales the data for the correct time units: seconds, minutes, or hours.
Example Script
measure-eye-width-over-time-graph-results.py
#!python3
"""This program demonstrates an Eye Width measurement that is
monitored over time with the Eye Width measured every interval.
The draw_graph() function shows a graph of the data in a
matplotlib GUI window.
"""
# Import modules.
import pyvisa
import sys
import time
from decimal import Decimal
import matplotlib.pyplot as plt
# Global variables.
oscilloscope_visa_address = "TCPIP0::localhost::hislip0,4880::INSTR"
timeout = 20000 # 20 seconds.
meas_minutes = 1 # Monitor eye with for 1 minute.
meas_interval = 2.0 # Time in seconds between each measurement.
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()
def monitor_eye_width(meas_minutes, meas_interval):
"""Monitors the eye width for the required of minutes by
performing a measurement every interval.
meas_minutes (int).
meas_interval (float).
"""
print(f"Monitoring Eye Width. Time required: {meas_minutes * 60} seconds.")
print("Please wait...")
data_length = int((meas_minutes * 60) / meas_interval) # Number of data points.
data = [0 for x in range(data_length)]
data_pt = 0
while data_pt < data_length:
Infiniium.query(":ACQuire:SINGle;*OPC?")
reading = float(Infiniium.query(":MEASure:EYE:EWIDth?"))
width = Decimal(reading / 1e-12)
data[data_pt] = width.quantize(Decimal("0.01"))
data_pt += 1
time.sleep(meas_interval)
if data_pt % 50:
print(" .", end="")
print("\n")
return data
def create_time_data(number_of_data_points, meas_minutes, meas_interval):
"""Creates list of time data and scales it for seconds,
minutes, or hours units. The units (xunits) is returned.
The argument, number_of_data_points, is an int.
The meas_minutes argument is the total test time (int).
The meas_interval argument is the seconds (float) between data points.
"""
xunits = ""
time_data = [] # list of times for each data point
if 0 < meas_minutes < 5: # 5 minutes
time_data = [(i * meas_interval) for i in range(0, number_of_data_points)]
xunits = "seconds"
elif 5 <= meas_minutes < 180: # 5 to 180 minutes (3 hours)
time_data = [(i * meas_interval / 60) for i in range(0, number_of_data_points)]
xunits = "minutes"
else: # >= 3 hours
time_data = [
(i * meas_interval / 3600) for i in range(0, number_of_data_points)
]
xunits = "hours"
return time_data, xunits
def draw_graph(y_data, x_data, xunits, measurement, channel):
"""A matplotlib graph is created and saved to a file in the
default folder.
y_data argument is a list of Decimals of Eye Width readings.
x_data argument is corresponding time positions.
xunits is 'seconds', 'minutes', or 'hours'.
channel argument is a string. for example, 'ECHannel2_8'.
"""
print("Drawing graph.", flush=True)
fig, ax = plt.subplots()
ax.set_title(f"Graph of {measurement}")
ax.grid(visible=True, which="major", axis="both")
ax.set_xlabel(xunits.capitalize())
ax.set_ylabel(f"{measurement} (Time in ps)")
s = f"Channel {channel} {measurement} over Time"
s += f"\n (Test time: {str(round(x_data[-1], 1))} {xunits})"
fig.suptitle(s, y=0.85, fontsize=10)
if len(y_data) < 20:
ax.plot(x_data, y_data, "g.-") # Data points shown.
else:
ax.plot(x_data, y_data, "g-") # Data points hidden. Line only.
print("Graph of returned data is displayed in a separate window on PC.")
sys.stdout.flush() # Flush print message in stdout
plt.show()
# ==========================================================
# 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") # Clear display.
# Turn on CHANnel1 real-time eye.
source = "CHANnel1"
eye_source = "ECHannel1"
Infiniium.query(f":{source}:EYE:DISPlay ON;*OPC?")
# Turn on eye width measurement.
Infiniium.write(f":MEASure:EYE:EWIDth:SOURce {eye_source}")
Infiniium.write(":MEASure:EYE:EWIDth")
# Monitor the eye width over a number of minutes.
y_data = monitor_eye_width(meas_minutes, meas_interval)
pts = len(y_data) # Data points in channel. 1st row of matirx.
# Make the time data.
x_data, xunits = create_time_data(pts, meas_minutes, meas_interval)
# Plot the measurement results.
draw_graph(y_data, x_data, xunits, "Eye Width", eye_source)
# Check error queue.
check_error_queue("End of program")
# Exit program.
exit_program()