diff --git a/frappy_psi/SR.py b/frappy_psi/SR.py index 7403e4c..709de26 100644 --- a/frappy_psi/SR.py +++ b/frappy_psi/SR.py @@ -37,14 +37,11 @@ class SR_IO(StringIO): class XY(HasIO, Readable): value = Parameter('X, Y', datatype=TupleOf(FloatRange(unit='V'), FloatRange(unit='V'))) - vmode = Parameter('control mode', EnumType(both_grounded=0, A=1, B=2, A_B_diff=3), readonly=False) - range = Parameter('sensitivity value', FloatRange(0.00, 1), unit='V', default=1) - autosen_on = Parameter('is auto sensitivity on', BoolType(), readonly=False) - noise_control = Parameter('is noise control mode on', BoolType(), readonly=False) - phase = Parameter('reference phase control', FloatRange(-360, 360), unit='deg', readonly=False) - frequency = Parameter('oscill. frequen. control', FloatRange(0.001, 250e3), unit='Hz', readonly=False) - amplitude = Parameter('oscill. amplit. control', FloatRange(0.00, 5), unit='V_rms', readonly=False) - #filter = Parameter('line frequency filter', unit='Hz') + freq = Parameter('oscill. frequen. control', FloatRange(0.001, 250e3), unit='Hz', readonly=False) + amp = Parameter('oscill. amplit. control', FloatRange(0.00, 5), unit='V_rms', readonly=False) + range = Parameter('sensitivity value', FloatRange(0.00, 1), unit='V', default=1, readonly=False) + autorange = Parameter('autorange_on', EnumType('autorange', off=0, soft=1, hard=2), + readonly=False, default=0) sen_range = {name: value + 1 for value, name in enumerate( ['2nV', '5nV', '10nV', '20nV', '50nV', '100nV', '200nV', '500nV', '1uV', @@ -62,8 +59,25 @@ class XY(HasIO, Readable): tc = Parameter('time const. value', FloatRange(0.00005, 100000), unit='s', readonly=False) itc = Parameter('time const. index', EnumType('time const. index range', time_const), readonly=False) + nm = Parameter('noise mode on', BoolType(), readonly=False) + phase = Parameter('reference phase control', FloatRange(-360, 360), unit='deg', readonly=False) + vmode = Parameter('control mode', EnumType(both_grounded=0, A=1, B=2, A_B_diff=3), readonly=False) + # filter = Parameter('line frequency filter', unit='Hz') + # dac = Parameter('output DAC channel value', datatype=TupleOf(IntRange(1, 4), FloatRange(0.0, 5000, unit='mV')), + # readonly=False, initwrite=True, default=(3,0)) + # dac = Parameter('output DAC channel value', FloatRange(-10000, 10000, unit='mV'), + # readonly=False, initwrite=True, default=0) + ioClass = SR_IO + def comm(self, cmd): + reply, status, overload = self.communicate(cmd).split(';') + reply = reply.rstrip('\n') + if overload != '0': + self.status = (self.Status.WARN, f'overload {overload}') + self.status = (self.Status.IDLE, '') + return reply + def comparison(self, curr_value, new_value, value_dict): c_ind = None # closest index c_diff = None # closets difference @@ -76,54 +90,77 @@ class XY(HasIO, Readable): if abs(curr_value - new_value) < c_diff: return c_ind - def comm(self, cmd): - reply, status, overload = self.communicate(cmd).split(';') - reply = reply.rstrip('\n') - if overload != '0': - self.status = (self.Status.WARN, f'overload {overload}') - self.status = (self.Status.IDLE, '') - return reply + def read_value(self): + reply = self.comm('XY.').split(',') + x = float(reply[0]) + y = float(reply[1]) + if self.autorange == 1: # soft + if max(abs(x), abs(y)) >= 0.9 * self.range and self.irange < 27: + self.write_irange(self.irange + 1) + elif max(abs(x), abs(y)) <= 0.3 * self.range and self.irange > 1: + self.write_irange(self.irange - 1) + return x, y - def read_vmode(self): - return int(self.comm('VMODE')) + def read_freq(self): + return float(self.comm('OF.')) - def write_vmode(self, vmode): - self.comm(f'IMODE {0}') - return self.comm(f'VMODE {vmode}') + def write_freq(self, freq): + self.comm(f'OF. {freq}') + return freq - def read_autosen_on(self): - return self.comm('AUTOMATIC') + def read_autorange(self): + reply = self.comm('AUTOMATIC') + # determine hardware autorange + if reply == 1: # soft + return 2 # hard + if self.autorange == 0: # soft + return self.autorange # read autorange + return self.autorange # off - def write_autosen_on(self, autosen_on): - autosen_on_str = '1' if autosen_on else '0' - self.comm(f'AUTOMATIC {autosen_on_str}') - return self.read_autosen_on() + def write_autorange(self, value): + if value == 2: # hard + self.comm('AS') # put hardware autorange on + self.comm('AUTOMATIC. 1') + else: + self.comm('AUTOMATIC. 0') + return value + + def read_amp(self): + return float(self.comm('OA.')) + + def write_amp(self, amp): + self.comm(f'OA. {amp}') + return amp def read_irange(self): - return int(self.comm('SEN')) + reply = self.comm('SEN') + return int(reply) def write_irange(self, irange): - self.comm(f'IMODE {0}') - self.comm(f'SEN {irange}') + value = int(irange) + self.comm(f'SEN {value}') self.read_range() - return irange + return value def read_range(self): reply = self.comm('SEN.') # range value return float(reply) def write_range(self): - self.comm(f'IMODE 0') curr_value = self.read_range() new_value = self.value c_ind = self.comparison(curr_value, new_value, self.sen_range) + self.read_irange() return self.comm(f'SEN {c_ind}') - def read_noise_control(self): - return self.comm('NOISEMODE') + def read_nm(self): + reply = self.comm('NOISEMODE') + return reply - def write_noise_control(self, noise_control): - return self.comm(f'NOISEMODE {noise_control}') + def write_nm(self, value): + self.comm('NOISEMODE %d' % int(value)) + self.read_nm() + return value def read_tc(self): reply = self.comm('TC.') @@ -141,32 +178,10 @@ class XY(HasIO, Readable): c_ind = self.comparison(curr_value, new_value, self.time_const) if abs(curr_value - new_value) < c_ind: - if self.read_noise_control() == 1 and (5e-4 <= self.time_const[new_itc] <= 1e-2): + if self.read_nm() == 1 and (5e-4 <= self.time_const[new_itc] <= 1e-2): raise RangeError('not allowed with noisemode=1') return self.comm(f'TC {new_itc}') - def read_value(self): - reply = self.comm('XY.').split(',') - x = float(reply[0]) - y = float(reply[1]) - return x, y - - def write_value(self, value): - return self.comm(f'XY {value}') - - def read_frequency(self): - return float(self.comm('OF.')) - - def write_frequency(self, frequency): - return self.comm(f'OF. {frequency}') - - def read_amplitude(self): - return float(self.comm('OA.')) - - def write_amplitude(self, amplitude): - self.comm(f'OA. {amplitude}') - return self.read_amplitude() - # phase and autophase def read_phase(self): reply = self.comm('REFP.') @@ -180,3 +195,12 @@ class XY(HasIO, Readable): """auto phase""" self.read_phase() return self.comm('AQN') + + def read_vmode(self): + reply = self.comm('VMODE') + return int(reply) + + def write_vmode(self, vmode): + value = int(vmode) + self.comm(f'VMODE {value}') + return value