-
Notifications
You must be signed in to change notification settings - Fork 0
/
Keithley224.py
161 lines (134 loc) · 4.07 KB
/
Keithley224.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
'''
KEITHLEY 224 instrument driver
TODO: SRQ decoding
'''
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
def __del__(self):
self.operate = False
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')
@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::0::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.1
for i in numpy.arange(0.001,0.015,0.001):
instrument.current = i
time.sleep(0.1)
del instrument