├── README.md ├── KeithleyIVSweep.py ├── KeithleyIVSweepFixedGate.py └── KeithleyGateSweepFixedDrain.py /README.md: -------------------------------------------------------------------------------- 1 | # Keithley-IV-Sweep 2 | Python (PyVisa) script for IV (Current-Voltage) measurements on a Keithley 2400 (GPIB/SCIP communication). 3 | 4 | 5 | Instructions: 6 | 7 | 1. Install the necessary Python libraries (NumPy, SciPy, and MatPlotLib) and GPIB driver for Mac/Linux (http://www.ni.com/product-documentation/5458/en/) or Windows (http://www.ni.com/product-documentation/5326/en/). 8 | 9 | 2. Place the KeithleyIVSweep.py, KeithleyIVSweepFixedGate.py, and/or KeithleyGateSweepFixedGate.py files in your home (or current Python) directory. 10 | 11 | 3. From the command line (in Mac, just use Terminal), run one of the following commands (depending on file): 12 | 13 | a. 'python KeithleyIVSweep.py startV stopV stepV outputfile' 14 | b. 'python KeithleyIVSweepFixedGate.py startV stopV stepV gateV outputfile' 15 | c. 'python KeithleyGateSweepFixedDrain.py startgateV stopgateV stepgateV drainV outputfile' 16 | 17 | 4. For example, a gate from -20 V to 20 V with a step voltage of 1 V and drain voltage of 0.5 V would be obtained by running 'python KeithleyGateSweepFixedDrain.py -20 20 1 0.5 Hello.txt' where the output text file named Hello.txt would be created and stored in your home (or current Python) directory. 18 | -------------------------------------------------------------------------------- /KeithleyIVSweep.py: -------------------------------------------------------------------------------- 1 | # Keithley IV Sweep for 2400 SourceMeter 2 | 3 | # Variable intake and assignment 4 | import sys 5 | startv = sys.argv[1] 6 | stopv = sys.argv[2] 7 | stepv = sys.argv[3] 8 | filename = sys.argv[4] 9 | startvprime = float(startv) 10 | stopvprime = float(stopv) 11 | stepvprime = float(stepv) 12 | steps = (stopvprime - startvprime) / stepvprime 13 | 14 | # Import PyVisa and choose GPIB Channel 25 as Drain-Source 15 | import visa 16 | rm = visa.ResourceManager() 17 | rm.list_resources() 18 | Keithley = rm.open_resource('GPIB0::25::INSTR') 19 | Keithley.write("*RST") 20 | Keithley.timeout = 25000 21 | 22 | # Turn off concurrent functions and set sensor to current with fixed voltage 23 | Keithley.write(":SENS:FUNC:CONC OFF") 24 | Keithley.write(":SOUR:FUNC VOLT") 25 | Keithley.write(":SENS:FUNC 'CURR:DC' ") 26 | 27 | # Voltage starting, ending, and spacing values based on input 28 | Keithley.write(":SOUR:VOLT:STAR ", startv) 29 | Keithley.write(":SOUR:VOLT:STOP ", stopv) 30 | Keithley.write(":SOUR:VOLT:STEP ", stepv) 31 | Keithley.write(":SOUR:SWE:RANG AUTO") 32 | 33 | # Set compliance current (in A), sweep direction, and data acquisition 34 | Keithley.write(":SENS:CURR:PROT 1") 35 | Keithley.write(":SOUR:SWE:SPAC LIN") 36 | Keithley.write(":SOUR:SWE:POIN ", str(int(steps))) 37 | Keithley.write(":SOUR:SWE:DIR UP") 38 | Keithley.write(":TRIG:COUN ", str(int(steps))) 39 | Keithley.write(":FORM:ELEM CURR") 40 | 41 | # Set sweep mode and turn output on 42 | Keithley.write(":SOUR:VOLT:MODE SWE") 43 | Keithley.write(":OUTP ON") 44 | 45 | # Initiate sweep, collect ACSII current values, and turn output off 46 | result = Keithley.query(":READ?") 47 | yvalues = Keithley.query_ascii_values(":FETC?") 48 | Keithley.write(":OUTP OFF") 49 | Keithley.write(":SOUR:VOLT 0") 50 | 51 | # Import Pyplot, NumPy, and SciPy 52 | import matplotlib.pyplot as plt 53 | import numpy as np 54 | from scipy import stats 55 | 56 | # Create xvalues array and calculate conductance 57 | xvalues = np.arange(startvprime,stopvprime,stepvprime) 58 | slope, intercept, r_value, p_value, std_error = stats.linregress(xvalues, yvalues) 59 | 60 | # Plot values and output conductance to command line 61 | print("Conductance:", slope, "Siemens") 62 | plt.plot(xvalues,yvalues) 63 | plt.xlabel(' Drain-Source Voltage (V)') 64 | plt.ylabel(' Drain-Source Current (A)') 65 | plt.title('IV Curve') 66 | plt.show() 67 | np.savetxt(filename, (xvalues,yvalues)) 68 | -------------------------------------------------------------------------------- /KeithleyIVSweepFixedGate.py: -------------------------------------------------------------------------------- 1 | # Keithley IV Sweep for 2400 SourceMeter 2 | 3 | # Variable intake and assignment 4 | import sys 5 | startv = sys.argv[1] 6 | stopv = sys.argv[2] 7 | stepv = sys.argv[3] 8 | gatev = sys.argv[4] 9 | filename = sys.argv[5] 10 | startvprime = float(startv) 11 | stopvprime = float(stopv) 12 | stepvprime = float(stepv) 13 | steps = (stopvprime - startvprime) / stepvprime 14 | 15 | # Import PyVisa and choose GPIB Channel 25 as Drain-Source and 26 as Gate 16 | import visa 17 | rm = visa.ResourceManager() 18 | rm.list_resources() 19 | Keithley = rm.open_resource('GPIB0::25::INSTR') 20 | Keithleygate = rm.open_resource('GPIB0::26::INSTR') 21 | Keithley.write("*RST") 22 | Keithleygate.write("*RST") 23 | Keithley.timeout = 25000 24 | Keithleygate.timeout = 25000 25 | 26 | # Turn off concurrent functions and set sensor to current with fixed voltage 27 | Keithley.write(":SENS:FUNC:CONC OFF") 28 | Keithley.write(":SOUR:FUNC VOLT") 29 | Keithley.write(":SENS:FUNC 'CURR:DC' ") 30 | 31 | # Set 32 | Keithleygate.write(":SOUR:FUNC VOLT") 33 | Keithleygate.write(":SOUR:VOLT:MODE FIXED") 34 | Keithleygate.write(":SOUR:VOLT:RANG 20") 35 | Keithleygate.write(":SOUR:VOLT:LEV ", gatev) 36 | Keithleygate.write(":SENS:CURR:PROT 1") 37 | 38 | # Voltage starting, ending, and spacing values based on input 39 | Keithley.write(":SOUR:VOLT:STAR ", startv) 40 | Keithley.write(":SOUR:VOLT:STOP ", stopv) 41 | Keithley.write(":SOUR:VOLT:STEP ", stepv) 42 | Keithley.write(":SOUR:SWE:RANG AUTO") 43 | 44 | # Set compliance current (in A), sweep direction, and data acquisition 45 | Keithley.write(":SENS:CURR:PROT 1") 46 | Keithley.write(":SOUR:SWE:SPAC LIN") 47 | Keithley.write(":SOUR:SWE:POIN ", str(int(steps))) 48 | Keithley.write(":SOUR:SWE:DIR UP") 49 | Keithley.write(":TRIG:COUN ", str(int(steps))) 50 | Keithley.write(":FORM:ELEM CURR") 51 | 52 | # Set sweep mode and turn output on 53 | Keithley.write(":SOUR:VOLT:MODE SWE") 54 | Keithleygate.write(":OUTP ON") 55 | Keithley.write(":OUTP ON") 56 | 57 | # Initiate sweep, collect ACSII current values, and turn output off 58 | result = Keithley.query(":READ?") 59 | yvalues = Keithley.query_ascii_values(":FETC?") 60 | Keithley.write(":OUTP OFF") 61 | Keithleygate.write(":OUTP OFF") 62 | Keithley.write(":SOUR:VOLT 0") 63 | Keithleygate.write(":SOUR:VOLT 0") 64 | 65 | # Import Pyplot, NumPy, and SciPy 66 | import matplotlib.pyplot as plt 67 | import numpy as np 68 | from scipy import stats 69 | 70 | # Create xvalues array and calculate conductance 71 | xvalues = np.arange(startvprime,stopvprime,stepvprime) 72 | slope, intercept, r_value, p_value, std_error = stats.linregress(xvalues, yvalues) 73 | 74 | # Plot values and output conductance to command line 75 | print("Conductance:", slope, "Siemens") 76 | plt.plot(xvalues,yvalues) 77 | plt.xlabel(' Drain-Source Voltage (V)') 78 | plt.ylabel(' Drain-Source Current (A)') 79 | plt.title('IV Curve') 80 | plt.figtext(0.7, 0.2, 'Vg=' + str(gatev) + 'V', fontsize=15) 81 | plt.show() 82 | np.savetxt(filename, (xvalues,yvalues)) 83 | -------------------------------------------------------------------------------- /KeithleyGateSweepFixedDrain.py: -------------------------------------------------------------------------------- 1 | # Keithley Gate Sweep (for fixed Vds) for 2400 SourceMeter 2 | 3 | # Variable intake and assignment 4 | import sys 5 | startv = sys.argv[1] 6 | stopv = sys.argv[2] 7 | stepv = sys.argv[3] 8 | fixedv = sys.argv[4] 9 | filename = sys.argv[5] 10 | startvprime = float(startv) 11 | stopvprime = float(stopv) 12 | stepvprime = float(stepv) 13 | steps = (stopvprime - startvprime) / stepvprime 14 | 15 | # Import PyVisa and choose GPIB Channel 25 as Drain-Source and 26 as Gate 16 | import visa 17 | rm = visa.ResourceManager() 18 | rm.list_resources() 19 | Keithley = rm.open_resource('GPIB0::25::INSTR') 20 | Keithleygate = rm.open_resource('GPIB0::26::INSTR') 21 | Keithley.write("*RST") 22 | Keithleygate.write("*RST") 23 | Keithley.timeout = 25000 24 | Keithleygate.timeout = 25000 25 | 26 | # Turn off concurrent functions and set sensor to current with fixed voltage 27 | Keithleygate.write(":SENS:FUNC:CONC OFF") 28 | Keithleygate.write(":SOUR:FUNC VOLT") 29 | Keithleygate.write(":SENS:FUNC 'CURR:DC' ") 30 | 31 | # Set 32 | Keithley.write(":SOUR:FUNC VOLT") 33 | Keithley.write(":SOUR:VOLT:MODE FIXED") 34 | Keithley.write(":SOUR:VOLT:RANG 20") 35 | Keithley.write(":SOUR:VOLT:LEV ", fixedv) 36 | Keithley.write(":SENS:CURR:PROT 1") 37 | 38 | # Voltage starting, ending, and spacing values based on input 39 | Keithleygate.write(":SOUR:VOLT:STAR ", startv) 40 | Keithleygate.write(":SOUR:VOLT:STOP ", stopv) 41 | Keithleygate.write(":SOUR:VOLT:STEP ", stepv) 42 | Keithleygate.write(":SOUR:SWE:RANG AUTO") 43 | 44 | # Set compliance current (in A), sweep direction, and data acquisition 45 | Keithleygate.write(":SENS:CURR:PROT 1") 46 | Keithleygate.write(":SOUR:SWE:SPAC LIN") 47 | Keithleygate.write(":SOUR:SWE:POIN ", str(int(steps))) 48 | Keithleygate.write(":SOUR:SWE:DIR UP") 49 | Keithleygate.write(":TRIG:COUN ", str(int(steps))) 50 | Keithleygate.write(":FORM:ELEM CURR") 51 | 52 | # Set sweep mode and turn output on 53 | Keithleygate.write(":SOUR:VOLT:MODE SWE") 54 | Keithley.write(":OUTP ON") 55 | Keithleygate.write(":OUTP ON") 56 | 57 | # Initiate sweep, collect ACSII current values, and turn output off 58 | result = Keithleygate.query(":READ?") 59 | yvalues = Keithleygate.query_ascii_values(":FETC?") 60 | Keithleygate.write(":OUTP OFF") 61 | Keithley.write(":OUTP OFF") 62 | Keithleygate.write(":SOUR:VOLT 0") 63 | Keithley.write(":SOUR:VOLT 0") 64 | 65 | # Import Pyplot, NumPy, and SciPy 66 | import matplotlib.pyplot as plt 67 | import numpy as np 68 | from scipy import stats 69 | 70 | # Create xvalues array and calculate conductance 71 | xvalues = np.arange(startvprime,stopvprime,stepvprime) 72 | slope, intercept, r_value, p_value, std_error = stats.linregress(xvalues, yvalues) 73 | 74 | # Plot values and output conductance to command line 75 | print("Conductance:", slope, "Siemens") 76 | plt.plot(xvalues,yvalues) 77 | plt.xlabel(' Gate Voltage (V)') 78 | plt.ylabel(' Drain-Source Current (A)') 79 | plt.title('Gate Sweep') 80 | plt.figtext(0.7, 0.2, 'Vds=' + str(fixedv) + 'V', fontsize=15) 81 | plt.show() 82 | np.savetxt(filename, (xvalues,yvalues)) 83 | --------------------------------------------------------------------------------