dotmjsc / K2450_Arb_I

Keithley 2450 Current Waveform Player
GNU General Public License v3.0
6 stars 0 forks source link

Keithley 2450 Arbitrary Current Waveform Player

This is a current waveform player for the Keithley 2450 Source Measure Unit (SMU). The features are:

The example above generates pulsed load currents on an alkaline battery to compare with simulation results of a corresponding model.

The 4-wire fixture shown can be bought here.

How to "Install"

Windows

Just get the latest windows binaries from Here. Additionally, you need a working VISA installation. I recommend Keysight VISA.

The binaries are made with PyInstaller.

Linux

It works on Linux, but you have to download the sources and install the necessary packages:

sudo pip install matplotlib
sudo pip install numpy
sudo pip install si-prefix
sudo pip install pyvisa

For Pyvisa to work properly then:

sudo pip install pyvisa-py
sudo apt-get -y install python3-usb
sudo apt-get -y install python-usb

If Pyvisa seems to work, but you can't find the USB device in the device list then try this and reboot:

# see https://stackoverflow.com/questions/66480203/pyvisa-not-listing-usb-instrument-on-linux
sudo su
echo 'SUBSYSTEM=="usb", MODE="0666", GROUP="usbusers"' >> /etc/udev/rules.d/99-com.rules

On Linux, the GUI will look ugly though.

SMU Settings

You can connect to your SMU via USB, GPIB or LAN. You should however make sure that the Command Set is "TSP".

Menu -> System -> Settings:

Using the Software

After startup, you'll be greeted with a nice graphical user interface (Here shown in usage):

Visa Instrument Selection

On startup the program automatically scans for available visa devices into the select box.

File Selection

After the PWL file is chosen or reloaded, the plot window shows the PWL waveform and the discrete steps (in red) based on the Timestep setting. Here shown with a rather long Timestep of 30ms:

Data Length: The maximum allowed number of load data points to be loaded into the SMU is 299995 (limitation of the device). You can control the number of points in the info window. If the number of points exceed this, the data will be truncated and a warning is displayed:

K2450: too many data points. Cropped to 299995!

Source Settings

The Autodelay values (as found in the Reference Manual) are:

Current range Current source autodelay (ms)
10 nA 50
100 nA 50
1 µA 3
10 µA 2
100 µA 1
1 mA 1
10 mA 1
100 mA 1
1 A 2

Measurement Settings

Miscellaneous settings and Buttons

Use without GUI

If you want to use the arbitrary current source in your own Python program, you need these three files:

Then install the needed additional packages

pip install numpy
pip install si-prefix
pip install pyvisa

A simple example:

import logging
logging.info = print  # temporarily redirect logging into Terminal

from K2450_ArbCurrentSource import K2450_ArbCurrentSource
K2450_SL = K2450_ArbCurrentSource("USB0::0x05E6::0x2450::04425317::0::INSTR")

K2450_SL.config.four_wire = True  # you can set the individual config elements manually
K2450_SL.config.load_file('default.ini')  # or you can load a configuration file

from PWL_Parser import PWL_parser
# load a pwl data file
pwl_data = PWL_parser('test_pwl.txt', K2450_SL.config.time_step)

# quick invert for load points (if needed)
def Invert(lst):
    return [-i for i in lst]

K2450_SL.load_data_points(Invert(pwl_data.values_discrete))  # load inverted data

status = K2450_SL.run_sequence(simulate=False)
if status is False:
    print('Error occurred')
else:
    print('Run finished with %d warnings' % status)

results = K2450_SL.return_results()
print(results['timestamps'])
print(results['currents'])
print(results['voltages'])

del K2450_SL

How it works

SMU Timer and Trigger Model

For n data points the program will make a source configuration list called "SOURCE LIST" with n+2 points. The first point will hold the general settings and the source level is set to 0A. The last element is set to 0A as well.

A measure configuration list named "MEAS_LIST" holds only a single item with the all measurement settings.

A trigger timer is prepared. The timer starts with a notification stimulus from a trigger block. The delay of the timer is set to the Timestep value (here: 2.5 ms).

For normal operation a trigger model is created like below:

At first the source is turned on and set to 0A (first configuration list element). The first delay block waits for the initial settling time to elapse. The trigger timer is started by stimulus from block 5. Then on each timer event a new data point from the config list is loaded. Block 9 branches to block 6 unless all data points have been loaded (count complete). Then the last data point with a value of 0A is loaded and held for 0.5s. Finally the source is turned off the model branches to idle state.

For operation with UVLO detection, the model is a little more complex:

New is block 9 that compares the last voltage measurement to a constant limit (the UVLO value). If the measurement is lower, it branches to block 15. Block 15 can only be reached by block 9 (because block 14 always branches). It displays a UVLO warning log message on the display then block 16 branches to block 13 where the source is immediately turned off.

Other noteworthy things

The OFF-Mode of the SMU is set to HIGH_Z since the "Normal" setting will not draw a small current, different to zero!

smu.source.offmode = smu.OFFMODE_HIGHZ

The automatic NPLC function calculates the remaining time for a measurement. The following is a simplified code snippet. Not shown is the handling of the autozero setting.

trigger_latency = 120e-6

# autodelay found is looked up from a table by current settings. 
# alternatively the manual delay is used
source_delay = (autodelay_found + trigger_latency)

max_measure_time = time_step - source_delay  # the maximum time for a measurement
max_measure_time = max_measure_time * 0.95  # safety factor

one_nplc = 1/linefreq  # linefreq is read from SMU

nplc = max_measure_time/one_nplc
if nplc < (one_nplc*0.01):  # the smallest setting is 0.01!
    nplc = 0.01

# nplc must definitely be floored when the parameter is passed with 2 digits precision to the SMU
def floor(a, digits=0):
    return np.true_divide(np.floor(a * 10 ** digits), 10 ** digits)

For the beeping you can let the Keithley 2450 play any melody you want. Example:

def _beep_end_ok(self):
    if self.config.beep is True:
        self._inst.write("beeper.beep(0.08, 262)")  # C4
        self._inst.write("beeper.beep(0.08, 523)")  # C5
        self._inst.write("beeper.beep(0.08, 659)")  # E5

The GUI is created with the PAGE GUI creator.

License

GNU General Public License v3.0 - See COPYING.txt