125 lines
4.7 KiB
Python
125 lines
4.7 KiB
Python
from pymeasure.instruments.keithley import Keithley2400, KeithleyDMM6500
|
|
import serial.tools.list_ports
|
|
import pyvisa
|
|
import pandas as pd
|
|
from ModuleTestBox import ModuleTestBox
|
|
from time import sleep
|
|
import matplotlib.pyplot as plt
|
|
|
|
rm = pyvisa.ResourceManager()
|
|
|
|
def find_instr_device(hint):
|
|
"""Scan available serial ports and return the first port whose description
|
|
contains the given hint (case-insensitive). Raise ValueError if not found.
|
|
"""
|
|
ports = rm.list_resources()
|
|
for port in ports:
|
|
if hint.lower() in port.lower():
|
|
return port
|
|
raise ValueError(f"No valid port found for hint '{hint}'.")
|
|
|
|
def find_device(hint):
|
|
"""Scan available serial ports and return the first port whose description
|
|
contains the given hint (case-insensitive). Raise ValueError if not found.
|
|
"""
|
|
ports = serial.tools.list_ports.comports()
|
|
for port, desc, hwid in ports:
|
|
if hint.lower() in desc.lower():
|
|
return port
|
|
raise ValueError(f"No valid port found for hint '{hint}'.")
|
|
|
|
def plotData(data):
|
|
"""Plot the data contained in the given DataFrame."""
|
|
|
|
fig, ax = plt.subplots(2, 1)
|
|
ax[0].plot(data['v'], data['i_kei'], label='Keithley 2400')
|
|
ax[0].plot(data['v'], data['i_dmm'], label='Keithley DMM 6500')
|
|
# ax[0].plot(data['v'], data['i_hv'], label='HV port')
|
|
ax[0].plot(data['v'], data['i_calc'], label='Calculated')
|
|
ax[0].set_xlabel('Voltage (V)')
|
|
ax[0].set_ylabel('Current (A)')
|
|
ax[0].legend()
|
|
ax[1].plot(data['v'], data['i_kei'] - data['i_calc'], label='Difference KEI')
|
|
ax[1].plot(data['v'], data['i_dmm'] - data['i_calc'], label='Difference DMM')
|
|
# ax[1].plot(data['v'], data['i_hv'] - data['i_calc'], label='Difference HV')
|
|
ax[1].set_xlabel('Voltage (V)')
|
|
ax[1].set_ylabel('Current difference (A)')
|
|
ax[1].legend()
|
|
plt.show()
|
|
|
|
hints=["VID:PID=CAFE:4001"]
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
with Keithley2400(find_device(hint='Prolific')) as kei:
|
|
with KeithleyDMM6500(find_instr_device(hint='0x05E6::0x6500')) as dmm:
|
|
with ModuleTestBox(hints=hints, verbose=True) as hv:
|
|
print("Connected to Keithley 2400 and HV port.")
|
|
|
|
if not hv.TestConnection():
|
|
print("HV port not connected.")
|
|
exit()
|
|
print(f'Firmware: {hv.GetFirmwareVersion()}')
|
|
print(f'HV: {"locked" if hv.HV_IsLocked() else "unlocked"}')
|
|
|
|
# perform a voltage ramp measurement with kei and measure current with kei and hv to compare
|
|
# and store the results in a pandas DataFrame
|
|
nSamples = 90
|
|
vStart = 0.0
|
|
vStop = 900.0
|
|
|
|
hv.HV_SetAll(0)
|
|
|
|
# configure HV port
|
|
hv.SelectChannel(1)
|
|
hv.Bias_Enable(False)
|
|
hv.HV_Enable(True)
|
|
|
|
# perform voltage ramp measurement with kei
|
|
kei.apply_voltage(compliance_current=1.1e-5)
|
|
kei.source_voltage = vStart
|
|
kei.enable_source()
|
|
kei.measure_current(10)
|
|
kei.current_range = 10e-6
|
|
|
|
dmm.measure_current(max_current=0.000001)
|
|
dmm.current_nplc = 12
|
|
|
|
|
|
values = []
|
|
|
|
print("Starting voltage ramp measurement...")
|
|
|
|
for i in range(nSamples):
|
|
v = vStart + i * (vStop - vStart) / nSamples
|
|
kei.source_voltage = v
|
|
sleep(0.1)
|
|
i_kei = kei.current
|
|
i_dmm = dmm.current
|
|
i_hv = hv.GetI() * -1e-12
|
|
|
|
while i_dmm > 1:
|
|
i_dmm = dmm.current
|
|
i_calc = v / 102980719.7
|
|
|
|
values.append((v, i_kei, i_dmm, i_hv, i_calc))
|
|
|
|
kei.disable_source()
|
|
|
|
data = pd.DataFrame(values, columns=['v', 'i_kei', 'i_dmm', 'i_hv', 'i_calc'])
|
|
data['ppm'] = (data['i_calc'] - data['i_hv']) / data['i_calc'] * 1e6
|
|
|
|
print(data)
|
|
print(hv.GetError())
|
|
|
|
sample_cal = round(nSamples * 0.8)
|
|
print(f"Sample for calibration: {data['ppm'].iloc[sample_cal:sample_cal+50].mean()} ppm")
|
|
|
|
# save data to Excel file
|
|
data.to_excel('data.xlsx', index=False)
|
|
|
|
plotData(data)
|
|
|
|
except Exception as e:
|
|
print(f"Error during programm: {e}")
|