Requirements:
Example of use with an Agilent [90000 X Series](www.agilent.com/find/90000x-scope) Oscilloscope:
from visa import instrument # Import the instrument function from the visa module
scope = instrument("TCPIP0::130.30.240.155::inst0::INSTR") # Connect to the scope using the VISA address (see below)
scope.ask("*IDN?") # Query the IDN properties of the scope
'Agilent Technologies,MSOX93204A,MY53240105,04.60.0016'
The instrument's visa address can be found in the IO Libraries Connection Expert:
Now let's do something more interesting...
import numpy as np
import matplotlib.pyplot as plt
# Allow plots to appear inline with the IPython notebook
%pylab inline
scope.write(":TIM:SCALE 600e-12")
scope.write(":DIG") # Capture a single waveform
wfm_ascii = scope.ask(":WAV:DATA?") # Get the waveform data
wfm_ascii = wfm_ascii[:-1] # Remove a trailing ,
wfm = [float(s) for s in wfm_ascii.split(',')] # Convert the ascii list of strings to a list of floats
sa_rate = float(scope.ask(":ACQ:SRAT:ANAL?")) # Get the scope's sample rate
mem_depth = float(scope.ask(":ACQ:POIN?")) # Get the current memory depth
t = np.linspace(-mem_depth/sa_rate,mem_depth/sa_rate, len(wfm)) # Calculate the sample times of the waveform
plt.plot(t,wfm) # Plot the waveform vs sample times
Populating the interactive namespace from numpy and matplotlib
[<matplotlib.lines.Line2D at 0x7f1f690>]
How about a screenshot from the instrument to confirm the waveform data we just pulled?
scope.write("disp:data? png")
data = scope.read_raw() # Read back the raw binary data as a string
hash_idx = data.find('#') # Find the start of the image data
len_datalen = int(data[hash_idx+1]) # The 1st character after '#' indicates the length of the length field
data_start_idx = hash_idx+len_datalen+2 # The binary image data starts here
datalen = int(data[hash_idx+2:hash_idx+len_datalen+2]) # The length of the binary data
img_data = data[data_start_idx:data_start_idx+datalen] # Extract just the image binary data
from IPython.display import Image # Ipython has some nice tools to display image data.
embed = Image(img_data)
embed
A more complete example of handling binary values from an instrument coming soon... To save the screenshot to a local file:
target = open('screenshot.png','wb')
target.write(img_data)
target.close()
Example:
# First set up the connection to the RPI DLL via the Python for .NET module
import clr # Import the Common Runtime Library Python module
clr.AddReference("Agilent.Infiniium.AppFW.Remote") # Create a reference from CLR to the Compliance App DLL
from Agilent.Infiniium.AppFW.Remote import * # Import the entire compliance app namespace from the Compliance App DLL
scopeIpAddress = "130.30.240.155"
Now we're ready to start...
scope.write(":SYSTEM:LAUNCH 'N5393C PCIExpress Test App'") # Launch the compliance app using the pyvisa instrument connection
remoteObj = RemoteAteUtilities.GetRemoteAte(scopeIpAddress) # Connect to the compliance app
remoteApp = IRemoteAte(remoteObj)
If we want to take a look at the test ID's & test names currently available we can do that using the TestInfo type:
remoteApp.SetConfig("TestPoint_Transmitter", "1.0")
testsinfos = remoteApp.GetCurrentOptions("TestsInfo")
for test in testsinfos:
print test.ID, test.Name
2101 Tx, Unit Interval (PCIE 2.0, 2.5 GT/s) 2110 Tx, Template Tests (PCIE 2.0, 2.5 GT/s) 2120 Tx, Median to Max Jitter (PCIE 2.0, 2.5 GT/s) 2130 Tx, Eye-Width (PCIE 2.0, 2.5 GT/s) 2140 Tx, Peak Differential Output Voltage (Transition)(PCIE 2.0, 2.5 GT/s) 21400 Tx, Peak Differential Output Voltage (Non Transition)(PCIE 2.0, 2.5 GT/s) 2151 Tx, Rise/Fall Time (PCIE 2.0, 2.5 GT/s) 2160 Tx, Deemphasized Voltage Ratio (PCIE 2.0, 2.5 GT/s) 2170 Tx, RMS AC Peak Common Mode Output Voltage (PCIE 2.0, 2.5 GT/s) 2181 Tx, Avg DC Common Mode Voltage (PCIE 2.0, 2.5 GT/s) 2182 Tx, DC Common Mode Output Voltage Variation (PCIE 2.0, 2.5 GT/s) 2185 Tx, DC Common Mode Line Delta (PCIE 2.0, 2.5 GT/s)
Now let's select some measurements & run some tests:
remoteApp.SuppressMessages = True # Suppress the GUI prompts
remoteApp.NewProject(True) # Create a new project
# Set various Configuration Parameters
remoteApp.SetConfig("DevicePCIErev", "PCIE 2.0")
remoteApp.SetConfig("TestPoint_AddInCard", "1.0")
remoteApp.SetConfig("DataRateOpt", "2.5 GT/s")
remoteApp.SetConfig("EnableSignalCheck", "0.0")
remoteApp.SelectedTests = [2301, 2310, 2320, 2330, 2340, 2350] # Select the tests to run
remoteApp.Run() # Run the selected tests
# Set up the project save options & save it to disk
saveOptions = SaveProjectOptions()
saveOptions.BaseDirectory = "c:\\temp"
saveOptions.Name = "Demo"
saveOptions.OverwriteExisting = True
projectFullPath = remoteApp.SaveProjectCustom(saveOptions)
# Set up the project results options and then get the results
resultOptions = ResultOptions()
resultOptions.TestIds = [2301]
resultOptions.IncludeCsvData = True
customResults = remoteApp.GetResultsCustom(resultOptions)
results = customResults.CsvResults
#remoteApp.Exit(True,True) # Exit the application
# An example of how to manipulate and display results using the Pandas library
import pandas as pd
from StringIO import StringIO
df_data = pd.read_csv(StringIO(results), sep=',', header=0, quotechar = '"')
pd.set_option('display.max_colwidth', 22)
df_data
Test ID | Test Name | Measured Item | Trial 1 Value | |
---|---|---|---|---|
0 | 2301 | Add-in Card Tx, Un... | Data Lane | Lane0 |
1 | 2301 | Add-in Card Tx, Un... | Note: | Non-SSC Limits Use... |
2 | 2301 | Add-in Card Tx, Un... | Actual Value | 401.7540 |
3 | 2301 | Add-in Card Tx, Un... | #3500 UI Blocks Me... | 992144 |
4 | 2301 | Add-in Card Tx, Un... | Margin | -680.8 |
5 | 2301 | Add-in Card Tx, Un... | Min UI | 401.7430 |
6 | 2301 | Add-in Card Tx, Un... | Max UI | 401.7540 |
7 | 2301 | Add-in Card Tx, Un... | Mean UI | 401.7480 |
8 | 2301 | Add-in Card Tx, Un... | Worst Case Data Rate | 2489085360.693 |
9 | 2301 | Add-in Card Tx, Un... | Mean Data Rate | 2489122534.524 |
10 | 2301 | Add-in Card Tx, Un... | Connection Type | Chan 1,3 - Direct ... |
Similarly for Compliance Applications on FlexDCA:
from visa import *
dca = instrument("TCPIP0::130.30.240.150::inst0::INSTR")
dca.ask("*idn?")
dca.write(":SYST:LAUN 'N1012A OIF CEI 3_0'") # Launch the compliance app
Example:
import sys
sys.path.append('C:\\Program Files (x86)\\BitifEye\\ValiFrame\\PCI-Express3') # Add the location of the Valiframe dll's to the system path
import clr # Import the Common Runtime Library Python module
clr.AddReference("ValiFrameRemote") # Create a reference from CLR to the Valiframe App DLL
from BitifEye.ValiFrame.ValiFrameRemote import * # Import the entire valiframe app namespace from the DLL
my_vf_pcie = ValiFrameRemote() # Creates an instance of the ValiFrameRemote class
my_vf_pcie.InitApplication("PciExpress3") # Initialize the application
my_vf_pcie.LoadProject("my_pcie3_proj.vfp")
#my_vf_pcie.ConfigureApplication() # This method creates a GUI prompt
There are a couple of interesting things to be aware of when using .NET dll's in Python via the pythonnet module.
procedureIDs = procedureNames = [] # The variable names must be assigned to something but are overwritten in the next call
_, procedureIDs, procedureNames = my_vf_pcie.GetProcedures(procedureIDs, procedureNames)
procedureIDs = [int(id) for id in procedureIDs] # Convert to a python list of integers
procedureNames = [str(name) for name in procedureNames] # Convert to a python list of strings
procs = zip(procedureIDs, procedureNames) # Zip the id's & names together. A dictionary may also be a useful way to store these.
for proc_id,proc_name in procs:
print proc_id, proc_name
300101 Random Jitter Calibration 300103 De-Emphasis Calibration 300104 Eye Height Calibration 301101 Random Jitter Calibration 301103 De-Emphasis Calibration 301104 Eye Height Calibration 302120 Equalization Preset Calibration 302121 Equalization Custom Preset Calibration 302122 Random Jitter Calibration 302123 Sinusoidal Jitter Calibration 302125 DM Sinusoidal Interference Calibration 302126 Eye Height and Width Calibration 302127 Compliance Eye Calibration 310101 Compliance Test 311101 Compliance Test 312120 Preset Compliance Test 312121 Compliance Test 320101 Unit Interval 320102 Template Tests 320103 Median to Max Jitter 320104 Eye-Width 320105 Peak Differential Output Voltage (Transition) 320106 Peak Differential Output Voltage (NonTransition) 321140 Unit Interval 321141 Template Tests -3.5dB 321142 Peak Differential Output Voltage -3.5dB 321143 Eye-Width -3.5dB with crosstalk 321144 RMS Random Jitter -3.5dB with crosstalk 321145 Maximum Deterministic Jitter -3.5dB with crosstalk 321146 Total Jitter at BER-12 -3.5dB with crosstalk 321147 Eye-Width -3.5dB without crosstalk 321148 RMS Random Jitter -3.5dB without crosstalk 321149 Maximum Deterministic Jitter -3.5dB without crosstalk 321150 Total Jitter at BER-12 -3.5dB without crosstalk 322160 Unit Interval 322161 Template Tests 322162 Eye-Width 322163 Peak Differential Output Voltage
Valiframe often uses dialog windows to give the user information or prompt the user to make a change to the setup. There are different ways to handle this in an automation environment. Below is a basic way to suppress all dialog windows but there is a more complete example of how to handle messaging and events in Valiframe
my_vf_pcie.DialogPopUp += DialogShowEventHandler(VFDialogInformation()) # Register the Dialog event handler (suppresses all Dialogs)
eyewidth_result = str()
my_vf_pcie.RunProcedure(320104, eyewidth_result)
(True, u'<?xml version="1.0" encoding="utf-16"?>\r\n<TestResults>\r\n <Summary>\r\n <ProcedureName>Eye-Width </ProcedureName>\r\n <ProcedureID>320104</ProcedureID>\r\n <Result>Incomplete</Result>\r\n <DateTime>11/13/2013 12:32:21 PM</DateTime>\r\n </Summary>\r\n</TestResults>')
Copyright © 2011 Agilent Technologies Inc. All rights reserved.
You have a royalty-free right to use, modify, reproduce and distribute this content (and/or any modified version) in any way you find useful, provided that you agree that Agilent has no warranty, obligations or liability.