27
27
from warnings import warn
28
28
29
29
import numpy as np
30
-
31
30
from pymeasure .instruments import Instrument , SCPIUnknownMixin
32
- from pymeasure .instruments .validators import strict_discrete_set , truncated_range
31
+ from pymeasure .instruments .validators import truncated_range , strict_discrete_set
33
32
34
33
# Setup logging
35
34
log = logging .getLogger (__name__ )
@@ -40,23 +39,27 @@ class Keithley2600(SCPIUnknownMixin, Instrument):
40
39
"""Represents the Keithley 2600 series (channel A and B) SourceMeter"""
41
40
42
41
def __init__ (self , adapter , name = "Keithley 2600 SourceMeter" , ** kwargs ):
43
- super ().__init__ (adapter , name , ** kwargs )
44
- self .ChA = Channel (self , "a" )
45
- self .ChB = Channel (self , "b" )
42
+ super ().__init__ (
43
+ adapter ,
44
+ name ,
45
+ ** kwargs
46
+ )
47
+ self .ChA = Channel (self , 'a' )
48
+ self .ChB = Channel (self , 'b' )
46
49
47
50
@property
48
51
def next_error (self ):
49
- """Returns a tuple of an error code and message from a
50
- single error."""
51
- err = self .ask (" print(errorqueue.next())" )
52
- err = err .split (" \t " )
52
+ """ Returns a tuple of an error code and message from a
53
+ single error. """
54
+ err = self .ask (' print(errorqueue.next())' )
55
+ err = err .split (' \t ' )
53
56
# Keithley Instruments Inc. sometimes on startup
54
57
# if tab delimitated message is greater than one, grab first two as code, message
55
58
# otherwise, assign code & message to returned error
56
59
if len (err ) > 1 :
57
60
err = (int (float (err [0 ])), err [1 ])
58
61
code = err [0 ]
59
- message = err [1 ].replace ('"' , "" )
62
+ message = err [1 ].replace ('"' , '' )
60
63
else :
61
64
code = message = err [0 ]
62
65
log .info (f"ERROR { str (code )} ,{ str (message )} - len { str (len (err ))} " )
@@ -67,36 +70,6 @@ def error(self):
67
70
warn ("Deprecated to use `error`, use `next_error` instead." , FutureWarning )
68
71
return self .next_error
69
72
70
- def clear (self ):
71
- """Clears the instrument status byte"""
72
- self .write ("status.reset()" )
73
-
74
- def reset (self ):
75
- """Resets the instrument."""
76
- self .write ("*reset()" )
77
-
78
- @property
79
- def complete (self ):
80
- """This property allows synchronization between a controller and a device. The Operation Complete
81
- query places an ASCII character 1 into the device's Output Queue when all pending
82
- selected device operations have been finished.
83
- """
84
- return self .ask ("waitcomplete() print([[1]])" ).strip ()
85
-
86
- @property
87
- def status (self ):
88
- """Requests and returns the status byte and Master Summary Status bit."""
89
- return self .ask ("print(tostring(status.condition))" ).strip ()
90
-
91
- @property
92
- def id (self ):
93
- """Requests and returns the identification of the instrument."""
94
- return self .ask (
95
- "print([[Keithley Instruments, Model]]..localnode.model..[[,]]..\
96
- localnode.serialno.. [[, ]]..localnode.revision)"
97
- ).strip ()
98
-
99
-
100
73
class Channel :
101
74
def __init__ (self , instrument , channel ):
102
75
self .instrument = instrument
@@ -125,23 +98,21 @@ def check_errors(self):
125
98
return self .instrument .check_errors ()
126
99
127
100
source_output = Instrument .control (
128
- "source.output" ,
129
- "source.output=%d" ,
101
+ 'source.output' , 'source.output=%d' ,
130
102
"""Property controlling the channel output state (ON of OFF)
131
103
""" ,
132
104
validator = strict_discrete_set ,
133
- values = {" OFF" : 0 , "ON" : 1 },
134
- map_values = True ,
105
+ values = {' OFF' : 0 , 'ON' : 1 },
106
+ map_values = True
135
107
)
136
108
137
109
source_mode = Instrument .control (
138
- "source.func" ,
139
- "source.func=%d" ,
110
+ 'source.func' , 'source.func=%d' ,
140
111
"""Property controlling the channel source function (Voltage or Current)
141
112
""" ,
142
113
validator = strict_discrete_set ,
143
- values = {" voltage" : 1 , " current" : 0 },
144
- map_values = True ,
114
+ values = {' voltage' : 1 , ' current' : 0 },
115
+ map_values = True
145
116
)
146
117
147
118
measure_nplc = Instrument .control (
@@ -156,123 +127,121 @@ def check_errors(self):
156
127
###############
157
128
# Current (A) #
158
129
###############
159
- current = Instrument .measurement ("measure.i()" , """ Reads the current in Amps """ )
130
+ current = Instrument .measurement (
131
+ 'measure.i()' ,
132
+ """ Reads the current in Amps """
133
+ )
160
134
161
135
source_current = Instrument .control (
162
- "source.leveli" ,
163
- "source.leveli=%f" ,
136
+ 'source.leveli' , 'source.leveli=%f' ,
164
137
""" Property controlling the applied source current """ ,
165
138
validator = truncated_range ,
166
- values = [- 1.5 , 1.5 ],
139
+ values = [- 1.5 , 1.5 ]
167
140
)
168
141
169
142
compliance_current = Instrument .control (
170
- "source.limiti" ,
171
- "source.limiti=%f" ,
143
+ 'source.limiti' , 'source.limiti=%f' ,
172
144
""" Property controlling the source compliance current """ ,
173
145
validator = truncated_range ,
174
- values = [- 1.5 , 1.5 ],
146
+ values = [- 1.5 , 1.5 ]
175
147
)
176
148
177
149
source_current_range = Instrument .control (
178
- "source.rangei" ,
179
- "source.rangei=%f" ,
150
+ 'source.rangei' , 'source.rangei=%f' ,
180
151
"""Property controlling the source current range """ ,
181
152
validator = truncated_range ,
182
- values = [- 1.5 , 1.5 ],
153
+ values = [- 1.5 , 1.5 ]
183
154
)
184
155
185
156
current_range = Instrument .control (
186
- "measure.rangei" ,
187
- "measure.rangei=%f" ,
157
+ 'measure.rangei' , 'measure.rangei=%f' ,
188
158
"""Property controlling the measurement current range """ ,
189
159
validator = truncated_range ,
190
- values = [- 1.5 , 1.5 ],
160
+ values = [- 1.5 , 1.5 ]
191
161
)
192
162
193
163
###############
194
164
# Voltage (V) #
195
165
###############
196
- voltage = Instrument .measurement ("measure.v()" , """ Reads the voltage in Volts """ )
166
+ voltage = Instrument .measurement (
167
+ 'measure.v()' ,
168
+ """ Reads the voltage in Volts """
169
+ )
197
170
198
171
source_voltage = Instrument .control (
199
- "source.levelv" ,
200
- "source.levelv=%f" ,
172
+ 'source.levelv' , 'source.levelv=%f' ,
201
173
""" Property controlling the applied source voltage """ ,
202
174
validator = truncated_range ,
203
- values = [- 200 , 200 ],
175
+ values = [- 200 , 200 ]
204
176
)
205
177
206
178
compliance_voltage = Instrument .control (
207
- "source.limitv" ,
208
- "source.limitv=%f" ,
179
+ 'source.limitv' , 'source.limitv=%f' ,
209
180
""" Property controlling the source compliance voltage """ ,
210
181
validator = truncated_range ,
211
- values = [- 200 , 200 ],
182
+ values = [- 200 , 200 ]
212
183
)
213
184
214
185
source_voltage_range = Instrument .control (
215
- "source.rangev" ,
216
- "source.rangev=%f" ,
186
+ 'source.rangev' , 'source.rangev=%f' ,
217
187
"""Property controlling the source current range """ ,
218
188
validator = truncated_range ,
219
- values = [- 200 , 200 ],
189
+ values = [- 200 , 200 ]
220
190
)
221
191
222
192
voltage_range = Instrument .control (
223
- "measure.rangev" ,
224
- "measure.rangev=%f" ,
193
+ 'measure.rangev' , 'measure.rangev=%f' ,
225
194
"""Property controlling the measurement voltage range """ ,
226
195
validator = truncated_range ,
227
- values = [- 200 , 200 ],
196
+ values = [- 200 , 200 ]
228
197
)
229
198
230
199
####################
231
200
# Resistance (Ohm) #
232
201
####################
233
202
resistance = Instrument .measurement (
234
- "measure.r()" , """ Reads the resistance in Ohms """
203
+ 'measure.r()' ,
204
+ """ Reads the resistance in Ohms """
235
205
)
236
206
237
207
wires_mode = Instrument .control (
238
- "sense" ,
239
- "sense=%d" ,
208
+ 'sense' , 'sense=%d' ,
240
209
"""Property controlling the resistance measurement mode: 4 wires or 2 wires""" ,
241
210
validator = strict_discrete_set ,
242
- values = {"4" : 1 , "2" : 0 },
243
- map_values = True ,
211
+ values = {'4' : 1 , '2' : 0 },
212
+ map_values = True
244
213
)
245
214
246
215
#######################
247
216
# Measurement Methods #
248
217
#######################
249
218
250
219
def measure_voltage (self , nplc = 1 , voltage = 21.0 , auto_range = True ):
251
- """Configures the measurement of voltage.
220
+ """C onfigures the measurement of voltage.
252
221
:param nplc: Number of power line cycles (NPLC) from 0.001 to 25
253
222
:param voltage: Upper limit of voltage in Volts, from -200 V to 200 V
254
223
:param auto_range: Enables auto_range if True, else uses the set voltage
255
224
"""
256
- log .info (f" { self . channel } is measuring voltage." )
257
- self .write (" measure.v()" )
258
- self .write (f" measure.nplc={ nplc :f } " )
225
+ log .info ("%s is measuring voltage." % self . channel )
226
+ self .write (' measure.v()' )
227
+ self .write (' measure.nplc=%f' % nplc )
259
228
if auto_range :
260
- self .write (" measure.autorangev=1" )
229
+ self .write (' measure.autorangev=1' )
261
230
else :
262
231
self .voltage_range = voltage
263
232
self .check_errors ()
264
233
265
234
def measure_current (self , nplc = 1 , current = 1.05e-4 , auto_range = True ):
266
- """Configures the measurement of current.
235
+ """ Configures the measurement of current.
267
236
:param nplc: Number of power line cycles (NPLC) from 0.001 to 25
268
237
:param current: Upper limit of current in Amps, from -1.5 A to 1.5 A
269
238
:param auto_range: Enables auto_range if True, else uses the set current
270
239
"""
271
- log .info (f" { self . channel } is measuring current." )
272
- self .write ( "measure.i()" )
273
- self .write (f" measure.nplc={ nplc :f } " )
240
+ log .info ("%s is sourcing current." % self . channel )
241
+ self .source_mode = 'current'
242
+ self .write (' measure.nplc=%f' % nplc )
274
243
if auto_range :
275
- self .write (" measure.autorangei=1" )
244
+ self .write (' measure.autorangei=1' )
276
245
else :
277
246
self .current_range = current
278
247
self .check_errors ()
@@ -301,8 +270,9 @@ def apply_current(self, current_range=None, compliance_voltage=0.1):
301
270
self .compliance_voltage = compliance_voltage
302
271
self .check_errors ()
303
272
304
- def apply_voltage (self , voltage_range = None , compliance_current = 0.1 ):
305
- """Configures the instrument to apply a source voltage, and
273
+ def apply_voltage (self , voltage_range = None ,
274
+ compliance_current = 0.1 ):
275
+ """ Configures the instrument to apply a source voltage, and
306
276
uses an auto range unless a voltage range is specified.
307
277
The compliance current is also set.
308
278
:param compliance_current: A float in the correct range for a
@@ -319,33 +289,33 @@ def apply_voltage(self, voltage_range=None, compliance_current=0.1):
319
289
self .check_errors ()
320
290
321
291
def ramp_to_voltage (self , target_voltage , steps = 30 , pause = 0.1 ):
322
- """Ramps to a target voltage from the set voltage value over
292
+ """ Ramps to a target voltage from the set voltage value over
323
293
a certain number of linear steps, each separated by a pause duration.
324
294
:param target_voltage: A voltage in Amps
325
295
:param steps: An integer number of steps
326
- :param pause: A pause duration in seconds to wait between steps"""
296
+ :param pause: A pause duration in seconds to wait between steps """
327
297
voltages = np .linspace (self .source_voltage , target_voltage , steps )
328
298
for voltage in voltages :
329
299
self .source_voltage = voltage
330
300
time .sleep (pause )
331
301
332
302
def ramp_to_current (self , target_current , steps = 30 , pause = 0.1 ):
333
- """Ramps to a target current from the set current value over
303
+ """ Ramps to a target current from the set current value over
334
304
a certain number of linear steps, each separated by a pause duration.
335
305
:param target_current: A current in Amps
336
306
:param steps: An integer number of steps
337
- :param pause: A pause duration in seconds to wait between steps"""
307
+ :param pause: A pause duration in seconds to wait between steps """
338
308
currents = np .linspace (self .source_current , target_current , steps )
339
309
for current in currents :
340
310
self .source_current = current
341
311
time .sleep (pause )
342
312
343
313
def shutdown (self ):
344
- """Ensures that the current or voltage is turned to zero
345
- and disables the output."""
346
- log .info (f "Shutting down channel { self .channel } ." )
347
- if self .source_mode == " current" :
314
+ """ Ensures that the current or voltage is turned to zero
315
+ and disables the output. """
316
+ log .info ("Shutting down channel %s." % self .channel )
317
+ if self .source_mode == ' current' :
348
318
self .ramp_to_current (0.0 )
349
319
else :
350
320
self .ramp_to_voltage (0.0 )
351
- self .source_output = " OFF"
321
+ self .source_output = ' OFF'
0 commit comments