Keithley 224 python code - Page 1
Forum section: electronics / testgear

author: justanothername
author_rank: Regular Contributor
timestamp: May 11, 2020, 02:17:05 pm
content: Here is a quick python code I threw together to interface the Keithley 224 programmable current source over GPIB.If you need SRQ decoding, I can add it, just ask.Code:'''KEITHLEY 224 instrument driverTODO: SRQ decoding'''import pyvisaimport enumclass Readout_Values:def __init__(self):self.raw = ""self.current = 0.0self.overcompliance = Falseself.voltage = 0.0self.time = 0.0# Range CommandsRANGE_LIST = ('R0','R5','R6','R7','R8','R9',)def get_available_devices():rm = pyvisa.ResourceManager()devices = rm.list_resources()rm.close()return devicesdef _decode_values(rawdata):splitted = rawdata.split(',')readout = Readout_Values()readout.raw = rawdatafor element in splitted:if 'DCI' in element:if element is 'O':readout.overcompliance = Truereadout.current = float(element[4:])if 'V' in element:readout.voltage = float(element[1:])if 'W' in element:readout.time = float(element[1:])return readoutdef _format_e(n):a = '%E' % nreturn a.split('E').rstrip('0').rstrip('.') + 'E' + a.split('E')class KEITHLEY_224(object):class Ranges(enum.Enum):AUTO = 0MAN_20uA = 1MAN_200uA = 2MAN_2mA = 3MAN_20mA = 4MAN_1m01A = 5def __init__(self, address):self._address = addressself._rm = pyvisa.ResourceManager()self._inst = self._rm.open_resource(address)self._range = self.Ranges.AUTOself.voltage = 3.0self.current = float(1e-06)self.time = 0.05self.operate = Falsedef __del__(self):self.operate = Falseself._rm.close()def get_measurement(self):self._inst.timeout = 1000result = _decode_values(self._inst.read())return result@propertydef range(self):return self._range@range.setterdef range(self, range):if not isinstance(range, self.Ranges):raise TypeError('mode must be an instance of Ranges Enum')self._range = rangeself._inst.write(RANGE_LIST[self._range.value]+'X')@propertydef voltage(self):return self._voltage@voltage.setterdef voltage(self, voltage):if (voltage < 1) or (voltage > 105):raise ValueError('voltage limits: 1 to 105')self._voltage = voltageself._inst.write('V'+ _format_e(voltage)+'X')@propertydef current(self):return self._current@current.setterdef current(self, current):if (current < -0.101) or (current > 0.101):raise ValueError('current limits: +/- 0.101')self._current = currentself._inst.write('I' + _format_e(current) + 'X')@propertydef time(self):return self._time@time.setterdef time(self, time):if (time < 0.05) or (time > 0.9999):raise ValueError('time limits: 0.05 to 0.9999 sec')self._time = timeself._inst.write('W' + _format_e(time) + 'X')@propertydef operate(self):return self._operate@operate.setterdef operate(self, operate):if type(operate) is not type(True):raise ValueError('operate takes a bool value')self._operate = operateif operate is True:self._inst.write('F1X')else:self._inst.write('F0X')# testing the codeif __name__ == '__main__':import numpyimport timeinstrument = 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 = Trueinstrument.voltage = 15instrument.time = 0.1for i in numpy.arange(0.001,0.015,0.001):instrument.current = itime.sleep(0.1)del instrument