diff --git a/secop_psi/k2601b.py b/secop_psi/k2601b.py index 6a984e5..d1ad8bc 100644 --- a/secop_psi/k2601b.py +++ b/secop_psi/k2601b.py @@ -23,7 +23,7 @@ not tested yet""" from secop.core import Attached, BoolType, EnumType, FloatRange, \ - HasIodev, Module, Parameter, StringIO, Writable + HasIodev, Module, Parameter, StringIO, Writable, Done class K2601bIO(StringIO): @@ -31,13 +31,16 @@ class K2601bIO(StringIO): SOURCECMDS = { + 0: 'reset()' + ' smua.source.func = smua.OUTPUT_DCAMPS' + ' display.smua.measure.func = display.MEASURE_VOLTS' + ' smua.source.autorangei = 1' + ' smua.source.output = %d print("ok"")', 1: 'reset()' - 'smua.source.func = smua.OUTPUT_DCVOLTS ' - 'display.smua.measure.func = display.MEASURE_DCAMP ' - 'smua.source.autorangev = 1', - 2: 'reset()' - 'smua.source.func = smua.OUTPUT_DCAMPS ' - 'smua.source.autorangei = 1', + ' smua.source.func = smua.OUTPUT_DCVOLTS' + ' display.smua.measure.func = display.MEASURE_DCAMPS' + ' smua.source.autorangev = 1' + ' smua.source.output = %d print("ok"")', } @@ -45,9 +48,8 @@ class SourceMeter(HasIodev, Module): resistivity = Parameter('readback resistivity', FloatRange(unit='Ohm'), poll=True) power = Parameter('readback power', FloatRange(unit='W'), poll=True) - mode = Parameter('measurement mode', EnumType(off=0, current=1, voltage=2), - readonly=False, default=0) - active = Parameter('output enable', BoolType(), readonly=False, poll=True) + mode = Parameter('measurement mode', EnumType(current_off=0, voltage_off=1, current_on=2, voltage_on=3), + readonly=False, poll=True) iodevClass = K2601bIO @@ -57,20 +59,12 @@ class SourceMeter(HasIodev, Module): def read_power(self): return self.sendRecv('print(smua.measure.p())') - def read_active(self): - return self.sendRecv('print(smua.source.output)') - - def write_active(self, value): - return self.sendRecv('smua.source.output = %d print(smua.source.output)' % value) - - # for now, mode will not be read from hardware + def read_mode(self): + return float(self.sendRecv('print(smua.source.func+2*smua.source.output)')) def write_mode(self, value): - if value == 0: - self.write_active(0) - else: - self.sendRecv(SOURCECMDS[value] + ' print(0)') - return value + assert 'ok' == self.sendRecv(SOURCECMDS[value % 2] % (value >= 2)) + return self.read_mode() class Current(HasIodev, Writable): @@ -78,9 +72,12 @@ class Current(HasIodev, Writable): value = Parameter('measured current', FloatRange(unit='A'), poll=True) target = Parameter('set current', FloatRange(unit='A'), poll=True) - active = Parameter('current is controlled', BoolType(), default=False) # polled from Current/Voltage + active = Parameter('current is controlled', BoolType(), default=False) # polled by SourceMeter limit = Parameter('current limit', FloatRange(0, 2.0, unit='A'), default=2, poll=True) + def initModule(self): + self._sourcemeter.registerCallbacks(self) + def read_value(self): return self.sendRecv('print(smua.measure.i())') @@ -104,16 +101,16 @@ class Current(HasIodev, Writable): return value return self.sendRecv('smua.source.limiti = %g print(smua.source.limiti)' % value) - def read_active(self): - return self._sourcemeter.mode == 1 and self._sourcemeter.read_active() - def write_active(self, value): - if self._sourcemeter.mode != 1: - if value: - self._sourcemeter.write_mode(1) # switch to current - else: - return 0 - return self._sourcemeter.write_active(value) + if value: + self._sourcemeter.write_mode('current_on') + elif self._sourcemeter.mode == 'current_on': + self._sourcemeter.write_mode('current_off') + return self.active + + def update_mode(self, mode): + # will be called whenever the attached sourcemeters mode changes + self.active = mode == 'current_on' class Voltage(HasIodev, Writable): @@ -121,9 +118,12 @@ class Voltage(HasIodev, Writable): value = Parameter('measured voltage', FloatRange(unit='V'), poll=True) target = Parameter('set voltage', FloatRange(unit='V'), poll=True) - active = Parameter('voltage is controlled', BoolType(), poll=True) + active = Parameter('voltage is controlled', BoolType(), default=False) # polled by SourceMeter limit = Parameter('current limit', FloatRange(0, 2.0, unit='V'), default=2, poll=True) + def initModule(self): + self._sourcemeter.registerCallbacks(self) + def read_value(self): return self.sendRecv('print(smua.measure.v())') @@ -147,13 +147,13 @@ class Voltage(HasIodev, Writable): return value return self.sendRecv('smua.source.limitv = %g print(smua.source.limitv)' % value) - def read_active(self): - return self._sourcemeter.mode == 2 and self._sourcemeter.read_active() - def write_active(self, value): - if self._sourcemeter.mode != 2: - if value: - self._sourcemeter.write_mode(2) # switch to voltage - else: - return 0 - return self._sourcemeter.write_active(value) + if value: + self._sourcemeter.write_mode('voltage_on') + elif self._sourcemeter.mode == 'voltage_on': + self._sourcemeter.write_mode('voltage_off') + return self.active + + def update_mode(self, mode): + # will be called whenever the attached sourcemeters mode changes + self.active = mode == 'voltage_on'