diff --git a/cfg/fi2_cfg.py b/cfg/fi2_cfg.py new file mode 100644 index 0000000..94b4281 --- /dev/null +++ b/cfg/fi2_cfg.py @@ -0,0 +1,100 @@ +Node('fi2.psi.ch', + 'vacuum furnace ILL Type', + 'tcp://5000', +) + +Mod('htr_io', + 'frappy_psi.tdkpower.IO', + 'powersupply communicator', + uri = 'serial:///dev/ttyUSB0', + ) + +Mod('htr', + 'frappy_psi.tdkpower.Power', + 'heater power', + io= 'htr_io', + ) + +Mod('out', + 'frappy_psi.tdkpower.Output', + 'heater output', + io = 'htr_io', + maxvolt = 5, + maxcurrent = 25, + ) + +Mod('relais', + 'frappy_psi.ionopimax.DigitalOutput', + 'relais for power output', + addr = 'o2', + ) + +Mod('T_main', + 'frappy_psi.ionopimax.CurrentInput', + 'sample temperature', + addr = 'ai4', + valuerange = (0, 1372), + value = Param(unit='degC'), + ) + + +Mod('T_extra', + 'frappy_psi.ionopimax.CurrentInput', + 'extra temperature', + addr = 'ai3', + valuerange = (0, 1372), + value = Param(unit='degC'), + + ) + +Mod('T_htr', + 'frappy_psi.ionopimax.CurrentInput', + 'heater temperature', + addr = 'ai2', + valuerange = (0, 1372), + value = Param(unit='degC'), + ) + +Mod('T_wall', + 'frappy_psi.ionopimax.VoltageInput', + 'furnace wall temperature', + addr = 'av2', + rawrange = (0, 1.5), + valuerange = (0, 150), + value = Param(unit='degC'), + ) + +Mod('T', + 'frappy_psi.picontrol.PI', + 'controlled Temperature', + input = 'T_htr', + output = 'out', + relais = 'relais', + p = 2, + i = 0.01, + ) + +Mod('interlocks', + 'frappy_psi.furnace.Interlocks', + 'interlock parameters', + input = 'T_htr', + wall_T = 'T_wall', + vacuum = 'p', + relais = 'relais', + control = 'T', + wall_limit = 50, + vacuum_limit = 0.1, + ) + +Mod('p_io', + 'frappy_psi.pfeiffer.IO', + 'pressure io', + uri='serial:///dev/ttyUSBlower', + ) + +Mod('p', + 'frappy_psi.pfeiffer.Pressure', + 'pressure reading', + io = 'p_io', + ) + diff --git a/cfg/fs_cfg.py b/cfg/fs_cfg.py new file mode 100644 index 0000000..b0f8fea --- /dev/null +++ b/cfg/fs_cfg.py @@ -0,0 +1,130 @@ +Node('fs.psi.ch', + 'small vacuum furnace', + 'tcp://5000', +) + +Mod('T', + 'frappy_psi.picontrol.PI2', + 'controlled Temperature on sample (2nd loop)', + input = 'T_sample', + output = 'T_reg', + relais = 'relais', + p = 1.2, + i = 0.005, + ) + +Mod('T_reg', + 'frappy_psi.picontrol.PI', + 'controlled Temperature on heater', + input = 'T_htr', + output = 't_out', + relais = 'relais', + p = 1, + i = 0.003, + ) + +Mod('p_reg', + 'frappy_psi.picontrol.PI', + 'controlled pressure', + input = 'p', + output = 'p_out', + relais = 'relais', + p = 1, + i = 0.005, + ) + +Mod('T_htr', + 'frappy_psi.ionopimax.CurrentInput', + 'heater temperature', + addr = 'ai4', + valuerange = (0, 1372), + value = Param(unit='degC'), + + ) + + +Mod('T_sample', + 'frappy_psi.ionopimax.CurrentInput', + 'sample temperature', + addr = 'ai3', + valuerange = (0, 1372), + value = Param(unit='degC'), + + ) + +Mod('T_extra', + 'frappy_psi.ionopimax.CurrentInput', + 'extra temperature', + addr = 'ai2', + valuerange = (0, 1372), + value = Param(unit='degC'), + + ) + + +Mod('T_wall', + 'frappy_psi.ionopimax.VoltageInput', + 'furnace wall temperature', + addr = 'av2', + rawrange = (0, 1.5), + valuerange = (0, 150), + value = Param(unit='degC'), + ) + +Mod('htr_io', + 'frappy_psi.bkpower.IO', + 'powersupply communicator', + uri = 'serial:///dev/ttyUSBupper', + ) + +Mod('htr', + 'frappy_psi.bkpower.Power', + 'heater power', + io= 'htr_io', + ) + +Mod('t_out', + 'frappy_psi.bkpower.Output', + 'heater output', + p_value = 'p_out', + io = 'htr_io', + maxvolt = 50, + maxcurrent = 2, + ) + +Mod('relais', + 'frappy_psi.ionopimax.DigitalOutput', + 'relais for power output', + addr = 'o2', + ) + +Mod('interlocks', + 'frappy_psi.furnace.Interlocks', + 'interlock parameters', + input = 'T_htr', + wall_T = 'T_wall', + htr_T = 'T_htr', + main_T = 'T_sample', + extra_T = 'T_extra', + vacuum = 'p', + relais = 'relais', + control = 'T', + wall_limit = 100, + vacuum_limit = 0.1, + ) + +Mod('p', + 'frappy_psi.ionopimax.LogVoltageInput', + 'pressure reading', + addr = 'av1', + rawrange = (1.82, 8.6), + valuerange = (5e-9, 1000), + value = Param(unit='mbar'), + ) + +Mod('vso', + 'frappy_psi.ionopimax.VoltagePower', + 'voltage power output', + target = 24, + export = False, + ) diff --git a/cfg/vf_cfg.py b/cfg/vf_cfg.py index 29819e9..13cdf18 100644 --- a/cfg/vf_cfg.py +++ b/cfg/vf_cfg.py @@ -88,16 +88,13 @@ Mod('interlocks', vacuum_limit = 0.1, ) -Mod('p_io', - 'frappy_psi.pfeiffer.IO', - 'pressure io', - uri='serial:///dev/ttyUSBlower', - ) - Mod('p', - 'frappy_psi.pfeiffer.Pressure', + 'frappy_psi.ionopimax.LogVoltageInput', 'pressure reading', - io = 'p_io', + addr = 'av1', + rawrange = (1.8, 8.6), + valuerange = (1e-7, 1000), + value = Param(unit='mbar'), ) diff --git a/frappy_psi/bkpower.py b/frappy_psi/bkpower.py index 7b2cb92..ef418b1 100644 --- a/frappy_psi/bkpower.py +++ b/frappy_psi/bkpower.py @@ -66,8 +66,9 @@ class Power(HasIO, Readable): class Output(HasIO, Writable): - value = Parameter(datatype=FloatRange(0,100,unit='%')) + value = Parameter(datatype=FloatRange(0,100,unit='%'), default=0) target = Parameter(datatype=FloatRange(0,100,unit='%')) + p_value = Parameter(datatype=FloatRange(0,100,unit='%'), default=0) maxvolt = Parameter('voltage at 100%',datatype=FloatRange(0,60,unit='V'),default=50,readonly=False) maxcurrent = Parameter('current at 100%',datatype=FloatRange(0,5,unit='A'),default=2,readonly=False) output_enable = Parameter('control on/off', BoolType(), readonly=False) @@ -78,8 +79,10 @@ class Output(HasIO, Writable): def write_target(self, target): self.write_output_enable(target != 0) - self.communicate(f'VOLT{round(max(8,target*self.maxvolt/10)):03d}') - self.communicate(f'CURR{round(target*self.maxcurrent):03d}') + self.communicate(f'VOLT{round(max(8,(target)**0.5 * self.maxvolt)):03d}') + self.communicate(f'CURR{round((target)**0.5* 10 * self.maxcurrent):03d}') + #self.communicate(f'VOLT{round(max(8,target*self.maxvolt/10)):03d}') + #self.communicate(f'CURR{round(target*self.maxcurrent):03d}') self.value = target def write_output_enable(self, value): diff --git a/frappy_psi/furnace.py b/frappy_psi/furnace.py index 1a9f78b..e157f9c 100644 --- a/frappy_psi/furnace.py +++ b/frappy_psi/furnace.py @@ -27,25 +27,51 @@ from frappy_psi.picontrol import PImixin class Interlocks(Module): input = Attached(Readable, 'the input module') - vacuum = Attached (Readable, 'the vacuum pressure') - wall_T = Attached (Readable, 'the wall temperature') + vacuum = Attached(Readable, 'the vacuum pressure') + wall_T = Attached(Readable, 'the wall temperature') + htr_T = Attached(Readable, 'the heater temperature') + main_T = Attached(Readable, 'the main temperature') + extra_T = Attached(Readable, 'the extra temperature') control = Attached(Module, 'the control module') relais = Attached(Writable, 'the interlock relais') wall_limit = Parameter('maximum wall temperature', FloatRange(0, unit='degC'), default = 50, readonly = False) vacuum_limit = Parameter('maximum vacuum pressure', FloatRange(0, unit='mbar'), default = 0.1, readonly = False) - + htr_T_limit = Parameter('maximum htr temperature', FloatRange(0, unit='degC'), + default = 530, readonly = False) + main_T_limit = Parameter('maximum main temperature', FloatRange(0, unit='degC'), + default = 530, readonly = False) + extra_T_limit = Parameter('maximum extra temperature', FloatRange(0, unit='degC'), + default = 530, readonly = False) + + def initModule(self): + super().initModule() + self._sensor_checks = [ + (self.wall_T, 'wall_limit'), + (self.main_T, 'main_T_limit'), + (self.extra_T, 'extra_T_limit'), + (self.htr_T, 'htr_T_limit'), + (self.vacuum, 'vacuum_limit'), + ] + def doPoll(self): + # TODO: check channels are valid super().doPoll() + newstatus = None if self.input.status[0] >= ERROR: - self.control.status = self.input.status - elif self.vacuum.value > self.vacuum_limit: - self.control.status = ERROR, 'bad vacuum' - elif self.wall_T.value > self.wall_limit: - self.control.status = ERROR, 'wall overheat' + newstatus = self.input.status else: + for sensor, limitname in self._sensor_checks: + if sensor.value > getattr(self, limitname): + newstatus = f'above {sensor.name} limit' + break + if sensor.status[0] >= ERROR: + newstatus = f'error at {sensor.name}: {sensor.status[1]}' return + self.control.status = newstatus + if self.control.control_active: + self.log.error('switch control off %r', self.control.status) self.control.write_control_active(False) self.relais.write_target(False) diff --git a/frappy_psi/ionopimax.py b/frappy_psi/ionopimax.py index e9a9e45..7bcf443 100644 --- a/frappy_psi/ionopimax.py +++ b/frappy_psi/ionopimax.py @@ -22,7 +22,7 @@ import os from glob import glob from frappy.core import Readable, Writable, Parameter, BoolType, StringType,\ FloatRange, Property, TupleOf, ERROR, IDLE -from frappy.errors import ConfigError +from frappy.errors import ConfigError, OutOfRangeError from math import log basepaths = '/sys/class/ionopimax', '/sys/class/ionopi' @@ -121,8 +121,8 @@ class CurrentInput(AnalogInput): result = super().read_value() if self.x > 0.021: self.status = ERROR, 'sensor broken' - else: - self.status = IDLE, '' + raise OutOfRangeError('sensor broken') + self.status = IDLE, '' return result @@ -146,3 +146,18 @@ class VoltageOutput(AnalogOutput): self.write(f'{self.addr}_mode', 'V') self.write(f'{self.addr}', '0') self.write(f'{self.addr}_enabled', '1') + + +class VoltagePower(Base, Writable): + devclass = 'power_out' + target = Parameter(datatype=FloatRange(0, 24.5, unit='V'), default=12) + addr = 'vso' + + def write_target(self, value): + if value: + self.write(self.addr, value, 1000) + self.write(f'{self.addr}_enabled', 1) + else: + self.write(f'{self.addr}_enabled', 0) + +