Source code for PyExpLabSys.drivers.keithley_smu

""" Simple driver for Keithley SMU """
from __future__ import print_function
import time
import logging
from PyExpLabSys.drivers.scpi import SCPI
from PyExpLabSys.common.supported_versions import python2_and_3

python2_and_3(__file__)


[docs]class KeithleySMU(SCPI): """ Simple driver for Keithley SMU """
[docs] def __init__(self, interface, hostname='', device='', baudrate=9600): if interface == 'serial': SCPI.__init__( self, interface=interface, device=device, baudrate=baudrate, line_ending='\n', ) self.comm_dev.timeout = 2 self.comm_dev.rtscts = False self.comm_dev.xonxoff = False print(self.comm_dev) if interface == 'lan': SCPI.__init__(self, interface=interface, hostname=hostname) self.channel_names = {1: 'a', 2: 'b'}
[docs] def output_state(self, output_on=False, channel=1): """ Turn the output on or off """ if output_on is True: self.scpi_comm('smu' + self.channel_names[channel] + '.source.output = 1') else: self.scpi_comm('smu' + self.channel_names[channel] + '.source.output = 0') return output_on
[docs] def set_current_measure_range(self, current_range=None, channel=1): """ Set the current measurement range """ ch_name = 'smu' + self.channel_names[channel] + '.' if current_range is None: self.scpi_comm(ch_name + 'measure.autorangei = ' + ch_name + 'AUTORANGE_ON') else: self.scpi_comm(ch_name + 'measure.rangei = ' + str(current_range)) return True
[docs] def set_integration_time(self, nplc=None, channel=1): """ Set the measurement integration time """ ch_name = 'smu' + self.channel_names[channel] + '.' if nplc is None: self.scpi_comm(ch_name + 'measure.nplc = 1') else: self.scpi_comm(ch_name + 'measure.nplc = ' + str(nplc)) return True
[docs] def read_current(self, channel=1): """ Read the measured current """ self.scpi_comm('reading = smu' + self.channel_names[channel] + '.measure.i()') self.scpi_comm('*TRG') current_string = self.scpi_comm('print(reading)', True) try: current = float(current_string) except (ValueError, TypeError): current = None logging.error('Current string: ' + str(current_string)) return current
[docs] def read_voltage(self, channel=1): """ Read the measured voltage """ self.scpi_comm('reading = smu' + self.channel_names[channel] + '.measure.v()') self.scpi_comm('*TRG') voltage_string = self.scpi_comm('print(reading)', True) try: voltage = float(voltage_string) except (ValueError, TypeError): voltage = None logging.error('Voltage string: ' + str(voltage_string)) return voltage
def set_source_function(self, function, channel=1): scpi_string = ( 'smu' + self.channel_names[channel] + '.source.func = ' + self.channel_names[channel] + '.OUTPUT_' ) if function in ('i', 'I'): self.scpi_comm(scpi_string + 'DC_AMPS') print('Source function: Current') if function in ('v', 'V'): print('Source function: Voltage') self.scpi_comm(scpi_string + 'DC_VOLTS')
[docs] def set_current_limit(self, current, channel=1): """ Set the desired current limit """ self.scpi_comm( 'smu' + self.channel_names[channel] + '.source.limiti = ' + str(current) )
[docs] def set_voltage(self, voltage, channel=1): """ Set the desired voltage """ self.scpi_comm( 'smu' + self.channel_names[channel] + '.source.levelv = ' + str(voltage) )
[docs] def set_voltage_limit(self, voltage, channel=1): """ Set the desired voltate limit """ self.scpi_comm( 'smu' + self.channel_names[channel] + '.source.limitv = ' + str(voltage) )
[docs] def set_current(self, current, channel=1): """ Set the desired current """ self.scpi_comm( 'smu' + self.channel_names[channel] + '.source.leveli = ' + str(current) )
[docs] def iv_scan(self, v_from, v_to, steps, settle_time, channel=1): """ Perform iv_scan """ ch_name = 'smu' + self.channel_names[channel] self.scpi_comm( 'SweepVLinMeasureI(' + ch_name + ', ' + str(v_from) + ', ' + str(v_to) + ', ' + str(settle_time) + ', ' + str(steps) + ')' ) readings = self.scpi_comm( 'printbuffer(1, ' + str(steps) + ', ' + ch_name + '.nvbuffer1.readings)', True, ) sourcevalues = self.scpi_comm( 'printbuffer(1, ' + str(steps) + ', ' + ch_name + '.nvbuffer1.sourcevalues)', True, ) readings = readings.split(',') sourcevalues = sourcevalues.split(',') for i in range(0, steps): readings[i] = float(readings[i]) sourcevalues[i] = float(sourcevalues[i]) return (sourcevalues, readings)
if __name__ == '__main__': PORT = '/dev/ttyUSB0' SMU = KeithleySMU(interface='serial', device=PORT, baudrate=4800) print(SMU.comm_dev.inWaiting()) SMU.comm_dev.read(SMU.comm_dev.inWaiting()) print(SMU.read_current(2)) print(SMU.read_voltage(1)) print(SMU.read_software_version()) # print(SMU) # SMU.set_source_function('i') # SMU.output_state(True) # time.sleep(1) # SMU.set_voltage(0.00) # time.sleep(1) # print(SMU.set_voltage_limit(1)) # time.sleep(1) # SMU.set_current(0.0) # time.sleep(3) # print('Voltage: ' + str(SMU.read_voltage())) # print('Current: ' + str(SMU.read_current())) # print('-') # time.sleep(1) # SMU.output_state(False) # print(SMU.read_software_version()) # print('-') # print(SMU.read_current()) # print('-') # print(SMU.read_voltage()) # print('-') # print(SMU.iv_scan(v_from=-1.1, v_to=0, steps=10, settle_time=0))