fixes on small furnace

This commit is contained in:
zolliker 2025-04-08 17:12:00 +02:00
parent ad76a5d752
commit 6a2aece383
6 changed files with 293 additions and 22 deletions

100
cfg/fi2_cfg.py Normal file
View File

@ -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',
)

130
cfg/fs_cfg.py Normal file
View File

@ -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,
)

View File

@ -88,16 +88,13 @@ Mod('interlocks',
vacuum_limit = 0.1, vacuum_limit = 0.1,
) )
Mod('p_io',
'frappy_psi.pfeiffer.IO',
'pressure io',
uri='serial:///dev/ttyUSBlower',
)
Mod('p', Mod('p',
'frappy_psi.pfeiffer.Pressure', 'frappy_psi.ionopimax.LogVoltageInput',
'pressure reading', 'pressure reading',
io = 'p_io', addr = 'av1',
rawrange = (1.8, 8.6),
valuerange = (1e-7, 1000),
value = Param(unit='mbar'),
) )

View File

@ -66,8 +66,9 @@ class Power(HasIO, Readable):
class Output(HasIO, Writable): 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='%')) 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) 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) maxcurrent = Parameter('current at 100%',datatype=FloatRange(0,5,unit='A'),default=2,readonly=False)
output_enable = Parameter('control on/off', BoolType(), readonly=False) output_enable = Parameter('control on/off', BoolType(), readonly=False)
@ -78,8 +79,10 @@ class Output(HasIO, Writable):
def write_target(self, target): def write_target(self, target):
self.write_output_enable(target != 0) self.write_output_enable(target != 0)
self.communicate(f'VOLT{round(max(8,target*self.maxvolt/10)):03d}') self.communicate(f'VOLT{round(max(8,(target)**0.5 * self.maxvolt)):03d}')
self.communicate(f'CURR{round(target*self.maxcurrent):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 self.value = target
def write_output_enable(self, value): def write_output_enable(self, value):

View File

@ -29,23 +29,49 @@ class Interlocks(Module):
input = Attached(Readable, 'the input module') input = Attached(Readable, 'the input module')
vacuum = Attached(Readable, 'the vacuum pressure') vacuum = Attached(Readable, 'the vacuum pressure')
wall_T = Attached(Readable, 'the wall temperature') 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') control = Attached(Module, 'the control module')
relais = Attached(Writable, 'the interlock relais') relais = Attached(Writable, 'the interlock relais')
wall_limit = Parameter('maximum wall temperature', FloatRange(0, unit='degC'), wall_limit = Parameter('maximum wall temperature', FloatRange(0, unit='degC'),
default = 50, readonly = False) default = 50, readonly = False)
vacuum_limit = Parameter('maximum vacuum pressure', FloatRange(0, unit='mbar'), vacuum_limit = Parameter('maximum vacuum pressure', FloatRange(0, unit='mbar'),
default = 0.1, readonly = False) 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): def doPoll(self):
# TODO: check channels are valid
super().doPoll() super().doPoll()
newstatus = None
if self.input.status[0] >= ERROR: if self.input.status[0] >= ERROR:
self.control.status = self.input.status newstatus = 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'
else: 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 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.control.write_control_active(False)
self.relais.write_target(False) self.relais.write_target(False)

View File

@ -22,7 +22,7 @@ import os
from glob import glob from glob import glob
from frappy.core import Readable, Writable, Parameter, BoolType, StringType,\ from frappy.core import Readable, Writable, Parameter, BoolType, StringType,\
FloatRange, Property, TupleOf, ERROR, IDLE FloatRange, Property, TupleOf, ERROR, IDLE
from frappy.errors import ConfigError from frappy.errors import ConfigError, OutOfRangeError
from math import log from math import log
basepaths = '/sys/class/ionopimax', '/sys/class/ionopi' basepaths = '/sys/class/ionopimax', '/sys/class/ionopi'
@ -121,7 +121,7 @@ class CurrentInput(AnalogInput):
result = super().read_value() result = super().read_value()
if self.x > 0.021: if self.x > 0.021:
self.status = ERROR, 'sensor broken' self.status = ERROR, 'sensor broken'
else: raise OutOfRangeError('sensor broken')
self.status = IDLE, '' self.status = IDLE, ''
return result return result
@ -146,3 +146,18 @@ class VoltageOutput(AnalogOutput):
self.write(f'{self.addr}_mode', 'V') self.write(f'{self.addr}_mode', 'V')
self.write(f'{self.addr}', '0') self.write(f'{self.addr}', '0')
self.write(f'{self.addr}_enabled', '1') 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)