From 6ac3938b78bc630744f7721597485156736da70c Mon Sep 17 00:00:00 2001 From: l_samenv Date: Mon, 3 Jul 2023 17:11:07 +0200 Subject: [PATCH] flamedil as of 2023-07-03 --- cfg/addons/flamesample_cfg.py | 3 +-- frappy_psi/ls372.py | 44 ++++++++++++++++++++++++----------- frappy_psi/parmod.py | 31 ++++++++++++------------ 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/cfg/addons/flamesample_cfg.py b/cfg/addons/flamesample_cfg.py index f6dc823..5b2a03f 100644 --- a/cfg/addons/flamesample_cfg.py +++ b/cfg/addons/flamesample_cfg.py @@ -45,8 +45,7 @@ Mod('ts', value=Param(unit='K'), low='ts_low', high='ts_high', - min_high=1.3, + min_high=0.6, max_low=1.7, tolerance=0.1, - disable_other=False, ) diff --git a/frappy_psi/ls372.py b/frappy_psi/ls372.py index 06a6069..ad2b062 100644 --- a/frappy_psi/ls372.py +++ b/frappy_psi/ls372.py @@ -207,8 +207,17 @@ class ResChannel(Channel): STATUS_MASK = 0x3f # mask T_OVER and T_UNDER def communicate(self, command): + # TODO: remove this and change to query return self.switcher.communicate(command) + def query(self, command): + return parse(self.switcher.communicate(command)) + + def change(self, command, *args): + cmd, _, qarg = command.partition(' ') + args = ','.join([qarg] + [f'{a:g}' for a in args]) + return parse(self.switcher.communicate(f'{command}?{qarg};{command} {args}')) + def read_status(self): if not self.enabled: return [self.Status.DISABLED, 'disabled'] @@ -361,6 +370,7 @@ class TemperatureChannel(ResChannel): class TemperatureLoop(HasConvergence, TemperatureChannel, Drivable): + loop = Property('lakshore loop', IntRange(0, 1), default=0) # TODO: implemented specific issues of loop 1 target = Parameter('setpoint', FloatRange(0, unit='$')) control_active = Parameter('we are controlling', BoolType(), default=0) minheater = Parameter('minimal heater current', FloatRange(0, 0.01, unit='A'), readonly=False, default=0) @@ -373,7 +383,7 @@ class TemperatureLoop(HasConvergence, TemperatureChannel, Drivable): def control_off(self): """switch control off""" self._control_active = False - self.communicate(f'RANGE 0,0;RANGE?0') + self.communicate(f'RANGE {self.loop},0;RANGE?{self.loop}') self.read_control_active() def min_percent(self): @@ -384,21 +394,21 @@ class TemperatureLoop(HasConvergence, TemperatureChannel, Drivable): def set_htrrng(self): if self._control_active: newhtr = int(self.htrrng) if self._control_active else 0 - htrrng = int(self.communicate('RANGE?0')) + htrrng = int(self.communicate(f'RANGE?{self.loop}')) if htrrng != newhtr: if newhtr: self.log.info('switched heater on %d', newhtr) - self.communicate(f'RANGE 0,{newhtr};RANGE?0') + self.communicate(f'RANGE {self.loop},{newhtr};RANGE?{self.loop}') if self.minheater: self.log.info('underflow open loop') self._underflow = True - self.communicate(f'OUTMODE 0,2,{self.channel},0,0,1,3;*OPC?') - self.communicate(f'MOUT {self.min_percent()};*OPC?') + self.communicate(f'OUTMODE {self.loop},2,{self.channel},0,0,1,3;*OPC?') + self.communicate(f'MOUT {self.loop}{self.min_percent()};*OPC?') elif self._underflow: self.log.info('switch to control after underflow') self._underflow = False - self.communicate(f'OUTMODE 0,5,{self.channel},0,0,1,3;*OPC?') - self.communicate(f'SETP 0,{self.target};SETP?0') + self.communicate(f'OUTMODE {self.loop},5,{self.channel},0,0,1,3;*OPC?') + self.communicate(f'SETP {self.loop},{self.target};*OPC?') def read_control_active(self): self.set_htrrng() @@ -406,23 +416,31 @@ class TemperatureLoop(HasConvergence, TemperatureChannel, Drivable): def read_target(self): if self._control_active: - return float(self.communicate('SETP?0')) + return float(self.communicate('SETP?{self.loop}')) return 0 def write_htrrng(self, value): if self._control_active: - self.communicate('RANGE 0,{int(value)};*OPC?') + self.communicate('RANGE {self.loop},{int(value)};*OPC?') return value def write_target(self, target): outmode = (5, self.channel, 0, 0, 1, 3) - prev = parse(self.communicate('OUTMODE?0')) + prev = parse(self.communicate('OUTMODE?{self.loop}')) if outmode != prev: - self.communicate('OUTMODE 0, %g,%g,%g,%g,%g,%g;*OPC?' % tuple(outmode)) - self.communicate('MOUT 0,{self.min_percent()};*OPC?') + self.communicate('OUTMODE {self.loop}, %g,%g,%g,%g,%g,%g;*OPC?' % tuple(outmode)) + self.communicate('MOUT {self.loop},{self.min_percent()};*OPC?') for chan in self.switcher.channels.values(): chan._control_active = False self._control_active = True self.read_control_active() self.convergence_start() - return float(self.communicate(f'SETP 0,{target};SETP?0')) + return float(self.communicate(f'SETP {self.loop},{target};SETP?{self.loop}')) + + #def write_ctrlpars(self, ctrlpars): + # p, i, d = self.change(f'PID {self.loop}', ctrlpars['p'], ctrlpars['i'], ctrlpars['d']) + # return {'p': p, 'i': i, 'd': d} + + #def read_ctrlpars(self): + # p, i, d = self.query(f'PID? {self.loop}') + # return {'p': p, 'i': i, 'd': d} diff --git a/frappy_psi/parmod.py b/frappy_psi/parmod.py index 3ddc27d..b76d0a0 100644 --- a/frappy_psi/parmod.py +++ b/frappy_psi/parmod.py @@ -130,7 +130,7 @@ def set_enabled(modobj, value): modobj.write_enabled(value) -def get_value(self, obj, default): +def get_value(obj, default): """get the value of given module. if not valid, return the limit (min_high or max_low)""" if not getattr(obj, 'enabled', True): return default @@ -151,28 +151,29 @@ class SwitchDriv(HasConvergence, Drivable): def doPoll(self): super().doPoll() if not self.isBusy(): - low = self.get_value(self.low, self.max_low) - high = self.get_value(self.high, self.min_high) + low = get_value(self.low, self.max_low) + high = get_value(self.high, self.min_high) low_valid = low < self.max_low high_valid = high > self.min_high - if low_valid > high_valid: - self.write_selected(self.selected.low) - elif high_valid > low_valid: - self.write_selected(self.selected.high) - if high_valid or low_valid: - set_enabled(self.low, low_valid) - set_enabled(self.high, high_valid) - else: # both invalid: measure both! - set_enabled(self.low, True) - set_enabled(self.high, True) + if high_valid and high > self.max_low: + if not low_valid: + set_enabled(self.low, False) + return + if low_valid and low < self.min_high: + if not high_valid: + set_enabled(self.high, False) + return + set_enabled(self.low, True) + set_enabled(self.high, True) def read_value(self): return self.low.value if self.selected == self.selected.low else self.high.value def read_status(self): status = self.low.status if self.selected == self.selected.low else self.high.status - # merge with convergence status - return merge_status(status, super().read_status()) + if status[0] >= ERROR: + return status + return super().read_status() # convergence status def read_target(self): if self.selected == self.selected.low: