Re: OT: I/V curve tracing made easy with Python and PyVISA

Tony Fleming

Jim (or anyone out there) can answer my question. I have Tektronix 2465 DMS
and I just purchased PC6407 RQus1, but I never used anything like this
Is there some instructional video that would show how to use it and Python
I'm learning Micro-Python on my Arduino and ESP8266/ESP32 boards - I love
Here is the video I'm learning from:

On Thu, May 16, 2019 at 11:06 AM Jim Ford <> wrote:

Thanks, Magnus, for posting. I, too, am interested in automating my test
bench using Python. This after seeing the nightmare at work of piles of
Labview code tweaked by many engineers over several decades. You know
there's a problem when tests have to pass 2 out of 3 times because of race
conditions and other nasties in the code! We asked one of the software
jocks for an Abort Test button that actually gets out of a test, but he
said "Well, it's not that simple. Which module should it jump out of, and
where should it land?" Uh, never mind...!With the VISA wrappers it
*should* be easy to write test code for both my old (mostly HP) instruments
with their GPIB interfaces and newer gear with USB. Hoping to get a GPIB
card for my garage lab computer and get programming in Python over the
summer (of which year remains to be seen!)Jim Ford Sent from my Verizon,
Samsung Galaxy smartphone
-------- Original message --------From: "magnustoelle via Groups.Io"
<> Date: 5/16/19 8:26 AM (GMT-08:00)
To: Subject: [TekScopes] OT: I/V curve tracing made
easy with Python and PyVISA Good Day to the group,this is completely
off-topic, but as several of you seemed always interested in curve-tracing
applications, let me share my excitement with you...I know that I am very
late into this, but allow me to say that I have found the use of the Python
scripting language in combination with libraries & packages such as PyVISA
very powerful.To cut a long story short: I was curious to see, if I can
replace my NI LabView projects with something simpler, less costly and more
portable between Operating Systems such as Windows, Linux etc. And after
playing with Python for a few days, it seems that Python offers such an
alternative.I still like how easy it is to generate appealing GUIs with
LabView, but even when using hierarchical designs, LabView "code" can be
hard to read and comprehend - just try to decipher your own VIs after a few
months!I have used PyVISA for
easy communication with T&M equipment and libraries such as mathlibplot for plotting and numpy for
a few math operations. The documentation and tools come for free, and there
are tons and tons of on-line training courses on Python as well as code
examples etc. which are available at 0 costs.Curve-tracing application:I
have used a GRUNDIG/digimess PN300 programmable power supply & a common NI
USB-GPIB adapter; then created some simple Python-scripts which allow the
I/V-curve tracing of two-terminal devices such as diodes and of
three-terminal devices such as transistors. For the latter, output A from
the power supply provided the Collector-Emitter sweep voltage, and output B
and a 22kOhm resistor provided the base current sweep.I have never really
had any formal education in programming/coding, but I have found it fairly
easy to create the attached PNG diagram, to save the current and voltage
data to a local file for post-processing with MS Excel etc.While this is
nothing to "write home about" - my heartful recommendation is: If you have
the interest and leisure, give Python and a stab into PyVISA a try!I am
including my simple Python code below . I am sure there are many things
which could be improved - however, please let's do not discuss
here...Cheers,MagnusP.S. I am aware that the GRUNDIG PN300 power supply is
not a precision instrument, but I have chosen it for simplicity - upgrading
to precision DMMs and more precise current/voltage sources and the like
would be easy.# Setup Digimess/GRUNDIG PN300 power supply# Testing
three-terminal electronic devices such as transistors# Set-up for
independent operation, Voltage and Currents for output A and readback
Current measurements# Set-up Voltage and Currents for output B and readback
Current measurements and turn off outputs# Hardware setup: Connect emitter
to common GND, collector to pos. terminal output A, connect base to output
B using a 22k series resistor for base currents.# Magnus Tölle, last edit:
13th May 2019# Setup: Easyinstall from first, and "easyinstall
pip" second# Install Python, pip, matplotlib, numpy, pandas, seaborn and NI
VISA from References:
# Import libraries for plottingimport matplotlib.pyplot as pltimport numpy
as np# import pandas as pd# import seaborn as sns# Import libraries for
VISA controlimport visa# Optional logging of PyVISA# visa.log_to_screen()#
Import other librariesimport time # as to allow pause between
measurementsimport csv # as to allow saving data file# For UTF Coding to
avoid encoding issues:# -*- coding: utf-8 -*-# Program runs on Windows
only:import sysimport os # Filesystem manipulation# Disable printdef
blockPrint(): sys.stdout = open(os.devnull, 'w')# Restore printdef
enablePrint(): sys.stdout = sys.__stdout__def windows_interaction():
assert ('win' in sys.platform), "This program only runs on Windows
systems." try: windows_interaction() except AssertionError as
error: print(error) print('This script was not executed')#
open resource Digimess/GRUNDIG PN300 power supplyrm =
visa.ResourceManager()# rm.list_resources()res = rm.list_resources()print
("Please connect and power-up GPIB adapter and PN300 power supply")print
("Please configure PN300 for GPIB and note address - default is address
7")PN300_GPIB_address = input("Please enter GPIB address:")print ("Please
connect DUT as follows:")print ("Emitter to common GND, collector to pos.
terminal output A, connect base to output B using a 22k series
resistor")print("Found the following equipment / resources:")print(res)
# print("Opening " + res[-1])PN300 = rm.get_instrument ('GPIB::' +
str(PN300_GPIB_address)) # Query to confirm that Digimess/GRUNDIG PN300 is
presentprint (PN300.query('*IDN?')) # Initialize and setup
Digimess/GRUNDIG PN300 power supply for constant voltage, independent
Ask user for voltage setup, current limits for output AVstartA =
input("Enter min. voltage sweep setting for output A in Volt: ")VstopA =
input("Enter max. voltage sweep setting for output A in Volt: ")VstepA =
input("Enter number of sweep steps for output A: ")VoltsA =
np.linspace(int(VstartA),int(VstopA),(int(VstepA)+1))Current_setA =
input("Enter current limit for output A in Ampere: ")Current_setA = 'ISET '
+ Current_setA# Ask user for voltage setup, current limits for output
BVstartB = input("Enter min. current sweep setting for output B in µA:
")VstopB = input("Enter max. current sweep setting for output B in µA (max.
1300µA): ")VstepB = input("Enter number of sweep steps for output B:
")Current_setB = input("Enter current limit for output B in Ampere:
")Current_setB = 'ISET ' + Current_setB# Ask user for base current resistor
valueResistor = input("Enter measured series resistor value in kOhm:
")Resistor = float(Resistor)*1E3VoltsB =
# Ask user for DUT nameDUTname = input("Enter name of the device under test
or DUT: ")# Set timeout to 10 secondsPN300.timeout = 10000# Enable outputs,
and set output A and B to 0V, inform user that measurements start
0.00')PN300.write(Current_setB)PN300.write('OUT_ON')print("Starting with
measurements now")VoltageDataA = []CurrentDataA = []CurrentDataB = []for
Voltage2 in VoltsB: PN300.write('SEL_B') PN300.write('VSET
'+(str(Voltage2))) Voltage2A = PN300.query('VOUT?')
Voltage_formatted2A = float(Voltage2A[2:7])
CurrentDataB.append(Voltage_formatted2A/Resistor) for Voltage1 in
VoltsA: PN300.write('SEL_A') PN300.write('VSET
'+(str(Voltage1))) Voltage1A = PN300.query('VOUT?')
Voltage_formatted1A = float(Voltage1A[2:7])
VoltageDataA.append(Voltage_formatted1A) # time.sleep(0.1) optional
delay time of 0.1 seconds Current1A = PN300.query('IOUT?')
Current_formatted1A = float(Current1A[2:7])
CurrentDataA.append(Current_formatted1A) print ("Emitter voltage
and current: ", Voltage1A, Current1A) print ("Base current in µA:
", (Voltage_formatted2A/Resistor*1E6))DataArrayA =
np.asarray((VoltageDataA, CurrentDataA, CurrentDataB)) # Set output A to
0V and turn outputs offPN300.write('OUT_OFF')Voltage_setA = 'VSET
0.00'PN300.write(Voltage_setA)# Notify userprint("Finished measurement and
outputs turned off")'seaborn-whitegrid')for IndexA in
range(0, int(VstepA)+1): IndexB = IndexA+1 IndexC =
linestyle='--', marker='x', markersize=8, color='g')plt.xlabel('Voltage in
Volt')plt.ylabel('Current in Ampere')plt.legend([DUTname + ' I/V curve'],
loc='best', shadow=True) Save the Data to a csv-file with the
DUT name# with appended rows for VoltageA, CurrentA, CurrentB dataNewFile =
open(DUTname+'.csv', 'w')with open(DUTname+'.csv', 'w', newline='') as fp:
wr = csv.writer(fp, dialect='excel') wr.writerow(VoltageDataA)with
open(DUTname+'.csv', 'a', newline='') as fp: wr = csv.writer(fp,
dialect='excel') wr.writerow(CurrentDataA)with open(DUTname+'.csv',
'a', newline='') as fp: wr = csv.writer(fp, dialect='excel')
wr.writerow(CurrentDataB)# Close the file - end of python

Join to automatically receive all group messages.