Skip to content
Snippets Groups Projects
Commit 40afb7c8 authored by Jan Gruis's avatar Jan Gruis
Browse files

added gitignore

parent 7ef4f6fd
No related branches found
No related tags found
No related merge requests found
Showing
with 3 additions and 1026 deletions
.idea/
.ipynb_checkpoints/
__pycache__/
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}
This diff is collapsed.
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}
# this is a python file that minimizes the amount of code seen to the user
import module
import matplotlib.pyplot as plt
import pandas as pd
from datetime import datetime
import os
from sklearn.linear_model import LinearRegression
import sys
import numpy as np
from IPython.display import display, clear_output
def I_V_Measurement(start,stop,step):
device = module.HP4155a('GPIB0::17::INSTR')
device.reset()
device.inst.write(":PAGE:MEAS")
device.inst.write(":PAGE:CHAN:MODE SWEEP") #go to sweep page and prepare sweep measurement
#setup sweep
device.inst.write(":PAGE:CHAN:MODE SWEEP") #go to sweep page and prepare sweep measurement
#smu2 and smu4 are disabled
device.smu_disable_sweep(2)
device.smu_disable_sweep(4)
#smu1 is constant and common
device.smu_mode_meas(1,'COMM')
device.smu_function_sweep(1,'CONS')
#smu3 is VAR1 and V
device.smu_mode_meas(3,'V')
device.smu_function_sweep(3,'VAR1')
#define start-step-stop
device.start_value_sweep(start)
device.step_sweep(step)
device.stop_value_sweep(stop)
#start measurement
device.single_measurement()
while device.operation_completed() == False:
pass
voltage_values = device.return_data('V3')
current_values = device.return_data('I3')
# show plot
plt.plot(voltage_values,current_values)
plt.xlabel('Voltage(V)')
plt.ylabel('Current(A)')
plt.title("I-V plot")
plt.show()
#export data to csv file
#add title to the results
header = ['Voltage(V)', 'Current(A)']
data = {header[0]:voltage_values,header[1]:current_values}
df = pd.DataFrame(data)
date = str(datetime.today().replace(microsecond=0))
print(df)
#exporting the data frame in an excel file
file_name ="results.csv"
path = r"\\fileserver.cst.rwth-aachen.de\public\Datentransfer\Asonitis, Alexandros"
#r"C:\Users\user\Desktop"
directory = os.path.join(path,file_name)
df.to_csv(directory)
del device
def stress_sampling(V2_stress=10,V3_stress=3,stress_time=30,V2_sampling=10,V3_sampling=2,sampling_mode='L10',
number_of_points=21,integration_time='SHOR'):
#connect to device
device = module.HP4155a('GPIB0::17::INSTR')
device.reset()
device.stress_page()
#define smus to numbers in mode and values for stress
#mode
device.smu_mode(1,'COMM')
device.smu_mode(2,'V')
device.smu_mode(3,'V')
device.smu_mode(4,'COMM')
device.sync(4,0)
#values
device.smu_value(2,V2_stress)
device.smu_value(3,V3_stress)
#time
zeit=device.stress_time(stress_time)
device.start_stress()
while device.operation_completed() == False:
pass
#start with sampling measurement
device.measurement_mode('SAMP')
#set the mode of smus for sampling
device.smu_mode_meas(1,'COMM')
device.smu_mode_meas(2,'V')
device.smu_mode_meas(3,'V')
device.smu_mode_meas(4,'COMM')
#set the values of smu for sampling
device.constant_smu_sampling(2,V2_sampling)
device.constant_smu_sampling(3,V3_sampling)
#time log10
device.sampling_mode(sampling_mode)
#minimum initial interval
device.initial_interval('MIN')
device.number_of_points(number_of_points)
device.integration_time(integration_time)
device.single_measurement()
while device.operation_completed() == False:
pass
time_values = device.return_data('@TIME')
I3_values = device.return_data('I3')
I2_values = device.return_data('I2')
fig = plt.figure()
plt.plot(time_values,I2_values,label='I2')
plt.plot(time_values,I3_values,label='I3')
plt.xlabel('Time(s)')
plt.ylabel('Current(A)')
plt.title("stress + sampilng plot")
plt.legend()
plt.show()
del device
#prepare full measurement
def ctlm(field_name ='M00',start=-50*10**(-3),stop=50*10**(-3),step=10**(-3),comp=10,distances=(5,10,15,25,45),time='MED',innen=0):
#connect to the device
device = module.HP4155a('GPIB0::17::INSTR')
date = str(datetime.today().replace(microsecond=0))
#initilize figure
plt.figure()
plt.xlabel('Voltage(V)')
plt.ylabel('Current(A)')
plt.title("CTLM plot")
#lists for appending all data values
ctlm_voltage = []
ctlm_current = []
ctlm_resistance = []
#execute five measurements
for j in range(len(distances)):
#setup
device.reset()
device.inst.write(":PAGE:MEAS")
device.inst.write(":PAGE:CHAN:MODE SWEEP") #go to sweep page and prepare sweep measurement
#vsus and vmus are disabled
device.disable_vsu(1)
device.disable_vsu(2)
device.disable_vmu(1)
device.disable_vmu(2)
#smu1 is constant and common
device.smu_mode_meas(1,'COMM')
device.smu_function_sweep(1,'CONS')
#smu2 is constant and I
device.smu_mode_meas(2,'I')
device.smu_function_sweep(2,'CONS')
device.cons_smu_value(2,0)
#smu3 is var1 and I
device.smu_mode_meas(3,'I')
device.smu_function_sweep(3,'VAR1')
#smu4 is constant and I
device.smu_mode_meas(4,'I')
device.smu_function_sweep(4,'CONS')
device.cons_smu_value(4,0)
#select compliance of smu3
device.comp('VAR1',comp)
#compliance of smu2 and smu4 is 10V
device.const_comp(2,10)
device.const_comp(4,10)
# smu1 is common and compliance is automatically set to maximum
#define user functions
device.user_function('I','A','I3')
print(device.error())
device.user_function('V','V','V4-V2')
print(device.error())
device.user_function('R','OHM','DIFF(V,I)')
print(device.error())
#integration time
device.integration_time(time)
#define start-step-stop
device.start_value_sweep(start)
device.step_sweep(step)
device.stop_value_sweep(stop)
#start measurement
device.single_measurement()
while device.operation_completed() == False:
pass
voltage_values = device.return_data('V3')
current_values = device.return_data('I3')
voltage = device.return_data('V')
print(voltage_values)
print(current_values)
ctlm_voltage.append(voltage_values)
ctlm_current.append(current_values)
#plot results of the single measurement
#plt.plot(voltage_values,current_values,label=f"distance={distances[j]}")
plt.plot(voltage_values,current_values,label='ausgangvoltage')
plt.legend()
plt.show()
plt.figure()
plt.plot(voltage,current_values,label='Eingangsvoltage')
plt.legend()
plt.show()
#save measurement as txt file
#add title to the results
header = ['Voltage(V)', 'Current(A)','Resistance(Ohm)']
data = {header[0]:voltage_values,header[1]:current_values}#,header[2]:resisance_values}
df = pd.DataFrame(data)
print(df)
file_name = field_name+"_CTLM_"+str(j+1)+".txt"
path =r"\\fileserver.cst.rwth-aachen.de\public\Datentransfer\Asonitis, Alexandros"
directory = os.path.join(path,file_name)
#export DataFrame to text file (keep header row and index column)
f=open(directory, 'a')
f.write('title\n')
df_string = df.to_string()
f.write(df_string)
#plot diagramm
#plt.legend()
#plt.show()
#wait for confirmation from user after a measurement is done
while True:
answer = input('please press enter to continue with the next measurement or finish after the last measurement!')
if answer == "":
break
#close the connection and plot all the diagramms
del device
#tlm/ctlm final part
def tlm_final(field_name ='M00',start=-50*10**(-3),stop=50*10**(-3),step=10**(-3),comp=10,distances=(5,10,15,25,45),time='MED',innen=0):
#connect to the device
device = module.HP4155a('GPIB0::17::INSTR')
date = str(datetime.today().replace(microsecond=0))
#initialize figure
fig, (ax1, ax2) = plt.subplots(2,sharex=True,figsize=(8,6)) #the plots share the same x axis
fig.suptitle('CTLM plot')
ax1.set_title('I(V)')
ax1.set(xlabel='Voltage(V)',ylabel='Current(A)')
ax2.set_title('R(V)')
ax2.set(xlabel='Voltage(V)',ylabel='Resistance(Ohm)')
#repeat five times
for j in range(len(distances)):
#setup
device.reset()
device.inst.write(":PAGE:MEAS")
device.inst.write(":PAGE:CHAN:MODE SWEEP") #go to sweep page and prepare sweep measurement
#disable vmus and vsus
device.disable_vsu(1)
device.disable_vsu(2)
device.disable_vmu(1)
device.disable_vmu(2)
#smu1 is constant and common
device.smu_mode_meas(1,'COMM')
device.smu_function_sweep(1,'CONS')
#smu2 is constant and I
device.smu_mode_meas(2,'I')
device.smu_function_sweep(2,'CONS')
device.cons_smu_value(2,0)
#smu3 is var1 and I
device.smu_mode_meas(3,'I')
device.smu_function_sweep(3,'VAR1')
#smu4 is constant and I
device.smu_mode_meas(4,'I')
device.smu_function_sweep(4,'CONS')
device.cons_smu_value(4,0)
#select compliance of smu3
device.comp('VAR1',comp)
#compliance of smu2 and smu4 is 10V
device.const_comp(2,10)
device.const_comp(4,10)
#define user functions
device.user_function('I','A','I3')
device.user_function('V','V','V4-V2')
device.user_function('R','OHM','DIFF(V,I)')
device.user_function('VS','V','V3')
#integration time
device.integration_time(time)
#define start-step-stop
device.start_value_sweep(start)
device.step_sweep(step)
device.stop_value_sweep(stop)
#display variables
device.display_variable('X','V')
device.display_variable('Y1','I')
device.display_variable('Y2','R')
device.display_variable_min_max('X','MIN',-10)
device.display_variable_min_max('X','MAX',10)
device.display_variable_min_max('Y1','MIN',start)
device.display_variable_min_max('Y1','MAX',stop)
device.display_variable_min_max('Y2','MIN',0)
device.display_variable_min_max('Y2','MAX',200)
#start measurement
device.single_measurement()
while device.operation_completed() == False:
pass
#return data from the device
V=device.return_data('V')
I=device.return_data('I')
R=device.return_data('R')
# now we have to remove resistance values that R=inf(nan) that means that the current is zero
for i in range(len(R)):
if R[i]>10**6:
R[i]=float('NAN')
# plot the results
ax1.plot(V,I,label=f"distance={distances[j]}")
ax2.plot(V,R,label=f"distance={distances[j]}")
ax1.legend(loc='best')
ax2.legend(loc="best")
clear_output(wait=True)
fig.tight_layout()
display(fig)
#export data frame to csv(for evaluation) and txt
header = ['Voltage(V)', 'Current(A)','Resistance(Ohm)']
data = {header[0]:V,header[1]:I,header[2]:R}
df = pd.DataFrame(data)
print(df)
#export to txt
#check tlm or ctlm
if(innen==0):
#specify path and file_name
file_name = field_name+"_TLM_"+str(j+1)+".txt"
location =r"\\fileserver.cst.rwth-aachen.de\public\Datentransfer\Asonitis, Alexandros"
path= os.path.join(location,file_name)
#check if file name exists
i=1
while os.path.exists(path):
file_name = field_name+"_TLM_"+str(j+1)+"_"str(i)+".txt"
path= os.path.join(location,file_name)
i=i+1
else:
#specify path and file_name
file_name = field_name+"_CTLM_"+str(j+1)+".txt"
location =r"\\fileserver.cst.rwth-aachen.de\public\Datentransfer\Asonitis, Alexandros"
path= os.path.join(location,file_name)
#check if file name exists
i=1
while os.path.exists(path):
file_name = field_name+"_CTLM_"+str(j+1)+"_"str(i)+".txt"
path= os.path.join(location,file_name)
i=i+1
title = "measured field:"+field_name+"\ndistance:"+str(distances[j])+"\nI:"+str(start)+"A to "+str(stop)+"A with step:"+str(step)+"\n"
f=open(path, 'a')
f.write(title)
df_string = df.to_string()
f.write(df_string)
f.close()
#export to csv for evaluataion
if(innen==0):
#specify path and file_name
file_name = field_name+"_TLM_"+str(j+1)+".csv"
location =r"\\fileserver.cst.rwth-aachen.de\public\Datentransfer\Asonitis, Alexandros"
path= os.path.join(location,file_name)
#check if file name exists
i=1
while os.path.exists(path):
file_name = field_name+"_TLM_"+str(j+1)+"_"str(i)+".csv"
path= os.path.join(location,file_name)
i=i+1
else:
#specify path and file_name
file_name = field_name+"_CTLM_"+str(j+1)+".csv"
location =r"\\fileserver.cst.rwth-aachen.de\public\Datentransfer\Asonitis, Alexandros"
path= os.path.join(location,file_name)
#check if file name exists
i=1
while os.path.exists(path):
file_name = field_name+"_CTLM_"+str(j+1)+"_"str(i)+".csv"
path= os.path.join(location,file_name)
i=i+1
df.to_csv(path)
# give user confirmation to do the next measurement
while True:
answer=input("Press enter to continue or anything else to stop the programm:")
if answer=="":
break
else:
sys.exit()
import pyvisa
class HP4155a(object):
def __init__(self,adress):
self.adress = adress
self.rm = pyvisa.ResourceManager()
self.inst = self.rm.open_resource(adress)
self.inst.timeout = None
def idn(self):
return self.inst.query("*IDN?")
def __del__(self):
self.rm.close()
def reset(self):
self.inst.write("*RST")
#smu mode
def smu_mode(self,smu_number,mode):
command = f":PAGE:STR:SMU{smu_number}:MODE {mode}"
self.inst.write(command)
#smu constant value for stress measurement
def smu_value(self,smu_number,value):
command =f":PAGE:STR:SET:CONS:SMU{smu_number} {value}"
self.inst.write(command)
#set the stess time in seconds
def stress_time(self,time):
command = f":PAGE:STR:SET:DUR {time}"
self.inst.write(command)
return time
#start stress operation
def start_stress(self):
#inst.write(":PAGE:SCONtrol:STRess[:STARt]")
self.inst.write(":PAGE:SCON:STR")
#inst.write("*TRG")
#self.inst.query('*OPC?')
#stop current operation
def stop_operation(self):
self.inst.write(":PAGE:SCONtrol:STOP")
#get data from HP4155a
def get_data(self):
self.inst.write(":FORM REAL")
data = self.inst.query(":HCOPy:ITEM:ALL:DATA?")
return data
def sync(self,smu_number,s):
if s == 0:
mode = "NSYN"
else:
mode="SYNC"
command = f":PAGE:STR:SMU{smu_number}:FUNC {mode}"
self.inst.write(command)
def single_measurement(self):
self.inst.write(":PAGE:SCON:SING")
#go to stress page
def stress_page(self):
self.inst.write(":PAGE:STR")
def error(self):
return self.inst.query(":SYST:ERR?")
def operation_completed(self):
text = self.inst.query('*OPC?')
text = text.replace('\n','')
finished = bool(text)
return finished
def show_variables(self):
return self.inst.query(":DATA:CAT?")
#sweep functions
def smu_disable_sweep(self,number):
command= f":PAGE:CHAN:SMU{number}:DIS"
self.inst.write(command)
#The following function is for both sampling and sweep
def smu_mode_meas(self,number,mode):
command=f":PAGE:CHAN:SMU{number}:MODE {mode}"
self.inst.write(command)
def smu_function_sweep(self,number,function):
command=f":PAGE:CHAN:SMU{number}:FUNC {function}"
self.inst.write(command)
def start_value_sweep(self,value):
command=f":PAGE:MEAS:VAR1:START {value}"
self.inst.write(command)
def step_sweep(self,value):
command=f":PAGE:MEAS:VAR1:STEP {value}"
self.inst.write(command)
def stop_value_sweep(self,value):
command=f":PAGE:MEAS:VAR1:STOP {value}"
self.inst.write(command)
def cons_smu_value(self,smu_number,value):
command =f"PAGE:MEAS:CONS:SMU{smu_number} {value}"
self.inst.write(command)
''' smu1 is constant and common, SMU3 is controlled through the Var1(v) which has a start value, a stop value, and a step
We don't need SMU2 and SMU4
:PAGE:CHANnels[:CDEFinition]:SMU<n>:FUNCtion this command is used to define the variable of SMU3
:PAGE:CHANnels[:CDEFinition]:SMU<n>:MODE
This command sets the output MODE of SMU<n>. This command also has a query
form. It is different that the one we used for the stress setup.
:PAGE:CHANnels[:CDEFinition]:SMU<n>:DISable
Important! we dont set a value for smu1.'''
#sampling measure functions part2 first goal
''' some instructions
we need linear log10, log25 and thinned out (one function also log50 can be selected) SCPI COMMAND: :PAGE:MEASure:SAMPling:MODE
Delay time(Hold time in manual) is to be seleceted :PAGE:MEASure:SAMPling:HTIMe
Minimum initial interval :PAGE:MEASure:SAMPling:IINTerval
number of points: :PAGE:MEASure:SAMPling:POINts
integration time: :PAGE:MEASure:MSETup:ITIMe[:MODE]
'''
def sampling_mode(self,mode):
command = f"PAGE:MEAS:SAMP:MODE {mode}"
self.inst.write(command)
def delay_time(self,time):
command = f":PAGE:MEAS:SAMP:HTIM {time}"
self.inst.write(command)
def initial_interval(self,interval):
command = f":PAGE:MEAS:SAMP:IINT {interval}"
self.inst.write(command)
def number_of_points(self,number):
command = f":PAGE:MEAS:SAMP:POIN {number}"
self.inst.write(command)
#integration time is SHOR,MED,LONG
def integration_time(self,time):
command=f":PAGE:MEAS:MSET:ITIM {time}"
self.inst.write(command)
''' The smus need to be set to other values as seen in the labview script we can define the following functions
the vgs is v3 and vds is v2 (constant values) we need current-time diagramm(id,ig) v3=2V, v2=10V
then we have to save the results in a file'''
def constant_smu_sampling(self,number,value):
command =f":PAGE:MEAS:SAMP:CONS:SMU{number} {value}"
self.inst.write(command)
def measurement_mode(self,mode):
command =f":PAGE:CHAN:MODE {mode}"
self.inst.write(command)
#this is a method that returns data from a variable and converts them to a list of real numbers
def return_data(self, variable):
#send command to instrument returns a string of comma seperated values
command = f":DATA? '{variable}'"
data = self.inst.query(command)
# separate the string to a list of strings
values = data.replace("\n",",").split(",")
values.pop()
#convert the string to float numbers
for i in range(len(values)):
values[i] = float(values[i])
return values
# these are commands for the compliance
#set the power compliance for VAR1 and VAR2
def pcomp(self,variable,value):
command = f":PAGE:MEAS:{variable}:PCOM {value}"
self.inst.write(command)
#set normal compliance for VAR1 and VAR2
def comp(self,variable,value):
""" """
command = f":PAGE:MEAS:{variable}:COMP {value}"
self.inst.write(command)
# constant voltage compiance of an smu(only use if the smu is constant and the mode is not COMMON)
def const_comp(self,smu_number,value):
command = f":PAGE:MEAS:CONS:SMU{smu_number}:COMP {value}"
self.inst.write(command)
#this command disables the VSU1 and VSU2
def disable_vsu(self, vsu_number):
command = f":PAGE:CHAN:VSU{vsu_number}:DIS"
self.inst.write(command)
def disable_vmu(self,vmu_number):
command = f":PAGE:CHAN:VMU{vmu_number}:DIS"
self.inst.write(command)
#this command is for defining a new user function
def user_function(self,name,unit,expression):
command = f":PAGE:CHAN:UFUN:DEF '{name}','{unit}','{expression}'"
self.inst.write(command)
#this command is for displaying the correct variables
def display_variable(self,axis,variable):
command=f":PAGE:DISP:GRAP:{axis}:NAME '{variable}'"
self.inst.write(command)
\ No newline at end of file
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}
{
"cells": [],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}
File deleted
File deleted
File deleted
File deleted
File deleted
'''
KEITHLEY 224 instrument driver
TODO: SRQ decoding
https://www.eevblog.com/forum/testgear/keithley-224-python-code/
'''
import pyvisa
import enum
class Readout_Values:
def __init__(self):
self.raw = ""
self.current = 0.0
self.overcompliance = False
self.voltage = 0.0
self.time = 0.0
# Range Commands
RANGE_LIST = (
'R0',
'R5',
'R6',
'R7',
'R8',
'R9',
)
def get_available_devices():
rm = pyvisa.ResourceManager()
devices = rm.list_resources()
rm.close()
return devices
def _decode_values(rawdata):
splitted = rawdata.split(',')
readout = Readout_Values()
readout.raw = rawdata
for element in splitted:
if 'DCI' in element:
if element[0] is 'O':
readout.overcompliance = True
readout.current = float(element[4:])
if 'V' in element:
readout.voltage = float(element[1:])
if 'W' in element:
readout.time = float(element[1:])
return readout
def _format_e(n):
a = '%E' % n
return a.split('E')[0].rstrip('0').rstrip('.') + 'E' + a.split('E')[1]
class KEITHLEY_224(object):
class Ranges(enum.Enum):
AUTO = 0
MAN_20uA = 1
MAN_200uA = 2
MAN_2mA = 3
MAN_20mA = 4
MAN_1m01A = 5
def __init__(self, address):
self._address = address
self._rm = pyvisa.ResourceManager()
self._inst = self._rm.open_resource(address)
self._range = self.Ranges.AUTO
self.voltage = 3.0
self.current = float(1e-06)
self.time = 0.05
self.operate = False
self._inst.control_ren(1) ## +++++++++++++++++++++++
def __del__(self):
self.operate = False
self._inst.control_ren(0) ## +++++++++++++++++++++++
self._rm.close()
def get_measurement(self):
self._inst.timeout = 1000
result = _decode_values(self._inst.read())
return result
@property
def range(self):
return self._range
@range.setter
def range(self, range):
if not isinstance(range, self.Ranges):
raise TypeError('mode must be an instance of Ranges Enum')
self._range = range
self._inst.write(RANGE_LIST[self._range.value]+'X')
@property
def voltage(self):
return self._voltage
@voltage.setter
def voltage(self, voltage):
if (voltage < 1) or (voltage > 105):
raise ValueError('voltage limits: 1 to 105')
self._voltage = voltage
self._inst.write('V'+ _format_e(voltage)+'X')
@property
def current(self):
return self._current
@current.setter
def current(self, current):
if (current < -0.101) or (current > 0.101):
raise ValueError('current limits: +/- 0.101')
self._current = current
self._inst.write('I' + _format_e(current) + 'X')
# print('I' + _format_e(current) + 'X') ## +++++++++++++++++++++++
@property
def time(self):
return self._time
@time.setter
def time(self, time):
if (time < 0.05) or (time > 0.9999):
raise ValueError('time limits: 0.05 to 0.9999 sec')
self._time = time
self._inst.write('W' + _format_e(time) + 'X')
@property
def operate(self):
return self._operate
@operate.setter
def operate(self, operate):
if type(operate) is not type(True):
raise ValueError('operate takes a bool value')
self._operate = operate
if operate is True:
self._inst.write('F1X')
else:
self._inst.write('F0X')
# testing the code
if __name__ == '__main__':
import numpy
import time
## instrument = KEITHLEY_224("GPIB0::15::INSTR")
##
## meas = instrument.get_measurement()
## print('Raw data: ' + str(meas.raw))
## print('Current: ' + str(meas.current))
## print('Overcompliance: ' + str(meas.overcompliance))
## print('Voltage: ' + str(meas.voltage))
## print('Time: ' + str(meas.time))
##
## instrument.operate = True
## instrument.voltage = 15
## instrument.time = 0.5
##
## time.sleep(5)
##
## for i in numpy.arange(0.001,0.015,0.001):
## instrument.current = i
## time.sleep(5.1)
##
## meas = instrument.get_measurement()
## print('Raw data: ' + str(meas.raw))
## print('Current: ' + str(meas.current))
## print('Overcompliance: ' + str(meas.overcompliance))
## print('Voltage: ' + str(meas.voltage))
## print('Time: ' + str(meas.time) + '\n\n\n')
##
## del instrument
instrument = KEITHLEY_224("GPIB0::15::INSTR")
while True:
try:
pass
except:
del instrument
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment