IV/CV measurements for silicon sensors.
On Windows download a pre-built executable from the release section and run it.
Install using pip in a virtual environment.
pip install https://github.com/hephy-dd/diode-measurement/archive/refs/tags/0.25.0.tar.gzBuilding a Windows executable using PyInstaller.
# Create build environment
python3 -m venv build_env
. build_env/Scripts/activate
# Install dependencies
pip install --upgrade pip
pip install -e .
pip install -r .pyinstaller/requirements.txt
# Build executable
pyinstaller ./.pyinstaller/windows_app.specAn executable will be created in dist/diode-measurement-{version}.exe
Source Meter Units
- Keithley 237
- Keithley 2410
- Keithley 2470
- Keithley 2657A
Electro Meter
- Keithley 6514
- Keithley 6517B
LCR Meter
- Agilent 4284A
- Keithley 595
- Keithley 4215-CVU
- Keysight E4980A
DMM (Temperature)
- Keithley 2700
TCU (Temperature Control Unit)
- ERS AC3 Fusion (Thermal Chuck)
Switching Matrix
- HEPHY BrandBox (HV Switch)
- Keithley 707B
- Keithley 708B
To interface instruments using a GPIB interface the NI-VISA drivers need to be installed. Interfacing instruments using TCPIP, USB or Serial port is supported out of the box by using PyVISA-py, pyusb and pyserial.
The instrument resource name inputs accept follwing formats:
| Format | Example | Result |
|---|---|---|
| <n> | 16 | GPIB::16::INSTR |
| <ip>:<port> | 0.0.0.0:1080 | TCPIP::0.0.0.0::1080::SOCKET |
| <host>:<port> | localhost:1080 | TCPIP::localhost::1080::SOCKET |
| <visa> | GPIB1::16::INSTR | GPIB1::16::INSTR |
The used plain text format consists of a header containing meta data in key and
value pairs and one or more CSV data tables with headers using \t separators.
<key>: <value>
...
<<series>[<unit>]\t...>
<<value>\t...>
...
IV measurement data consist of up to two CSV tables with the second (optional) table containing continuous measurement data.
sample: Unnamed
measurement_type: iv
voltage_begin[V]: +5.000E+00
voltage_end[V]: -1.000E+01
voltage_step[V]: +1.000E+00
waiting_time[s]: +1.000E-01
current_compliance[A]: +1.000E-06
timestamp[s] voltage[V] v_smu[V] i_smu[A] i_elm[A] i_elm2[A] temperature[degC]
1629455368.29 +5.000E+00 +5.038E+00 +4.261E-08 +3.740E-08 +NAN +NAN
1629455369.71 +4.000E+00 +4.065E+00 +7.708E-08 +9.495E-08 +NAN +NAN
1629455370.49 +3.000E+00 +3.007E+00 +3.460E-08 +6.264E-08 +NAN +NAN
... ... ... ... ... ... ...
timestamp[s] voltage[V] v_smu[V] i_smu[A] i_elm[A] i_elm2[A] temperature[degC]
1629455385.69 +3.000E+00 +3.046E+00 +3.996E-04 +7.137E-08 +NAN +NAN
1629455387.65 +3.000E+00 +3.034E+00 +7.353E-04 +3.079E-08 +NAN +NAN
1629455389.56 +3.000E+00 +3.021E+00 +9.081E-04 +1.266E-08 +NAN +NAN
... ... ... ... ... ... ...IV bias measurement data consist of up to two CSV tables with the second (optional) table containing continuous bias measurement data.
sample: Unnamed
measurement_type: iv_bias
bias_voltage[V]: +1.000E+01
voltage_begin[V]: +5.000E+00
voltage_end[V]: -1.000E+01
voltage_step[V]: +1.000E+00
waiting_time[s]: +1.000E-01
current_compliance[A]: +1.000E-06
timestamp[s] voltage[V] v_smu[V] i_smu[A] v_smu2[V] i_smu2[A] i_elm[A] i_elm2[A] temperature[degC]
1629455368.29 +5.000E+00 +5.038E+00 +4.261E-08 +1.063E+01 +3.723E-08 +3.740E-08 +NAN +NAN
1629455369.71 +4.000E+00 +4.065E+00 +7.708E-08 +1.051E+01 +6.513E-08 +9.495E-08 +NAN +NAN
1629455370.49 +3.000E+00 +3.007E+00 +3.460E-08 +1.058E+01 +2.410E-08 +6.264E-08 +NAN +NAN
... ... ... ... ... ... ... ... ...
timestamp[s] voltage[V] v_smu[V] i_smu[A] v_smu2[V] i_smu2[A] i_elm[A] i_elm2[A] temperature[degC]
1629455385.69 +3.000E+00 +3.046E+00 +3.996E-08 +1.063E+01 +2.657E-08 +7.137E-08 +NAN +NAN
1629455387.65 +3.000E+00 +3.034E+00 +7.353E-08 +1.063E+01 +6.154E-08 +3.079E-08 +NAN +NAN
1629455389.56 +3.000E+00 +3.021E+00 +9.081E-08 +1.063E+01 +8.426E-08 +1.266E-08 +NAN +NAN
... ... ... ... ... ... ... ... ...CV measurement data consist of a single CSV table containing the measurement data.
sample: Unnamed
measurement_type: cv
voltage_begin[V]: +5.000E+00
voltage_end[V]: -1.000E+01
voltage_step[V]: +1.000E+00
waiting_time[s]: +1.000E-01
current_compliance[A]: +1.000E-08
timestamp[s] voltage[V] v_smu[V] i_smu[A] c_lcr[F] c2_lcr[F] r_lcr[Ohm] temperature[degC]
1629455368.29 +5.000E+00 +5.065E+00 +4.261E-08 +3.740E-05 7.149E+08 3.459932E-01 +NAN
1629455369.71 +4.000E+00 +4.037E+00 +7.708E-08 +9.495E-05 1.109E+08 3.015286E-01 +NAN
1629455370.49 +3.000E+00 +3.043E+00 +3.460E-08 +6.264E-05 2.549E+08 2.482018E-01 +NAN
... ... ... ... ... ... ...The application provides an JSON-RPC (remote procedure call) version 2.0 interface using a TCP server.
Start notification starts a new measurement.
{"jsonrpc": "2.0", "method": "start"}Optional parameters are:
continuous(Boolean)auto_reconnect(Boolean)measurement_type(one ofiv,iv_bias,cv_diode,cv_mos)measurement_instruments(list ofsmu,smu2,elm,elm2,lcr,dmm,tcu,switch)begin_voltage(Volt)end_voltage(Volt)step_voltage(Volt),waiting_time(seconds)compliance(Ampere)waiting_time_continuous(seconds).
Note: specified values are applied to the user interface before starting a measurement.
{
"jsonrpc": "2.0",
"method": "start",
"params": {
"end_voltage": -100.0,
"step_voltage": 10.0,
"waiting_time": 1.0
}
}Stop notification stops an active measurement.
{"jsonrpc": "2.0", "method": "stop"}Change voltage notification applies only during continuous It measurement.
Required parameters are:
end_voltage(Volt)
Optional parameters are:
step_voltage(Volt, default is1.0)waiting_time(seconds, default is1.0)
{
"jsonrpc": "2.0",
"method": "change_voltage",
"params": {
"end_voltage": 100.0,
"step_voltage": 10.0,
"waiting_time": 0.25
}
}Request an application state snapshot.
{"jsonrpc": "2.0", "method": "state", "id": 0}This returns application state parameters.
{
"jsonrpc": "2.0",
"result": {
"state": "ramping",
"measurement_type": "iv",
"sample": "VPX1",
"source_voltage": 24.0,
"smu_voltage": 24.026,
"smu_current": 0.0025,
"smu2_voltage": null,
"smu2_current": null,
"elm_current": 0.0021,
"elm2_current": null,
"lcr_capacity": null,
"temperature": 24.031
},
"id": 0
}Get current instrument options using method instrument.get.
Required parameter is:
instrument(one ofsmu,smu2,elm,elm2,lcr,dmm,tcu,switch)
{
"jsonrpc": "2.0",
"method": "instrument.get",
"params": {
"instrument": "smu"
},
"id": 1
}This returns the current model's instrument options.
{
"jsonrpc": "2.0",
"result": {
"instrument": "smu",
"model": "K2410",
"options": {
"filter.enable": false,
"filter.count": 10,
"filter.mode": "REP",
"nplc": 1.0,
"route.terminals": "REAR",
"system.breakdown.protection": false,
}
},
"id": 1
}Note: option keys might change in future releases.
Update current instrument options using method instrument.update.
Required parameters are:
instrument(one ofsmu,smu2,elm,elm2,lcr,dmm,tcu,switch)options(specific to selected instrument model)
{
"jsonrpc": "2.0",
"method": "instrument.update",
"params": {
"instrument": "smu",
"options" : {
"filter.enable": true,
"filter.count": 25,
}
},
"id": 2
}This returns the current model's updated instrument options.
{
"jsonrpc": "2.0",
"result": {
"instrument": "smu",
"model": "K2410",
"options": {
"filter.enable": true,
"filter.count": 25,
"filter.mode": "REP",
"nplc": 1.0,
"route.terminals": "REAR",
"system.breakdown.protection": false,
}
},
"id": 2
}Note: option keys might change in future releases.
Following states are exposed by the state snapshot:
idleconfigurerampingcontinuousstopping
Example using netcat to start a new measurement and set a target end voltage:
echo '{"jsonrpc": "2.0", "method": "start", "params": {"end_voltage": 100.0}}' | nc localhost 4000Example using Python to query the application state from the TCP server:
import json
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect(("localhost", 4000))
request = {
"jsonrpc": "2.0",
"method": "state",
"id": None,
}
sock.sendall(json.dumps(request).encode("utf-8"))
print(sock.recv(4096).decode("utf-8"))Example using the DiodeMeasurementClient:
from rpc_client import DiodeMeasurementClient
client = DiodeMeasurementClient("localhost", 4000)
client.start(measurement_type="iv", end_voltage=100.0)
while client.current_state() != "idle":
print(client.state())
time.sleep(1)See scripts for a reference client implementation and example scripts demonstrating how to use it.
