improvements when testing leiden
- triple current source - software loop
This commit is contained in:
20
cfg/addons/ah2700leiden_cfg.py
Normal file
20
cfg/addons/ah2700leiden_cfg.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Node('ah2700.frappy.psi.ch',
|
||||||
|
'Andeen Hagerlin 2700 Capacitance Bridge',
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('cap_io',
|
||||||
|
'frappy_psi.ah2700.Ah2700IO',
|
||||||
|
'',
|
||||||
|
uri='linse-leiden-ts:3002',
|
||||||
|
timeout=60,
|
||||||
|
)
|
||||||
|
|
||||||
|
# this creates also cap_freq and cap_loss
|
||||||
|
Mod('cap',
|
||||||
|
'frappy_psi.ah2700.Capacitance',
|
||||||
|
'capacitance',
|
||||||
|
io = 'cap_io',
|
||||||
|
loss_name='loss',
|
||||||
|
freq_name='freq',
|
||||||
|
)
|
||||||
|
|
||||||
110
cfg/main/leiden370_cfg.py
Normal file
110
cfg/main/leiden370_cfg.py
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
Node('leiden370.config.sea.psi.ch',
|
||||||
|
'''30 K - Leidendil Pulsetube with ls370''',
|
||||||
|
)
|
||||||
|
Mod('sea_main',
|
||||||
|
'frappy_psi.sea.SeaClient',
|
||||||
|
'main sea connection for leiden370.config',
|
||||||
|
config = 'leiden370.config',
|
||||||
|
service = 'main',
|
||||||
|
)
|
||||||
|
|
||||||
|
for name in ['T3K', 'Tstill', 'T50mK', 'Tmxlow', 'Tmxhigh', 'Tmxcx', 'Tblueo',
|
||||||
|
'Tpt50', 'Tpt3high', 'Tpt3low', 'Twhite', 'Tgreen']:
|
||||||
|
mname = name.replace('T','T_')
|
||||||
|
Mod(mname,
|
||||||
|
'frappy_psi.sea.SeaReadable', '',
|
||||||
|
io='sea_main',
|
||||||
|
sea_object='tt',
|
||||||
|
rel_paths=[name],
|
||||||
|
value=Param(unit='K'),
|
||||||
|
extra_modules = ['raw'],
|
||||||
|
)
|
||||||
|
Mod(name.replace('T', 'R_'),
|
||||||
|
'frappy_psi.sea.SeaReadable', '',
|
||||||
|
io='sea_main',
|
||||||
|
value=Param(unit='Ohm'),
|
||||||
|
single_module=f'{mname}.raw'
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('cmn',
|
||||||
|
'frappy_psi.sea.SeaReadable', '',
|
||||||
|
io = 'sea_main',
|
||||||
|
sea_object = 'cmn',
|
||||||
|
extra_modules = ['u1', 'u2', 'temp'],
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('T_cmn',
|
||||||
|
'frappy_psi.sea.SeaReadable', '',
|
||||||
|
io='sea_main',
|
||||||
|
value=Param(unit='K'),
|
||||||
|
single_module='cmn.temp',
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('V_fixp',
|
||||||
|
'frappy_psi.sea.SeaReadable', '',
|
||||||
|
io='sea_main',
|
||||||
|
value=Param(unit='V'),
|
||||||
|
single_module='cmn.u2',
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('V_cmn',
|
||||||
|
'frappy_psi.sea.SeaReadable', '',
|
||||||
|
io='sea_main',
|
||||||
|
value=Param(unit='V'),
|
||||||
|
single_module='cmn.u1',
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('tcs_io',
|
||||||
|
'frappy_psi.tcs.IO',
|
||||||
|
'tcs communication',
|
||||||
|
uri='linse-leiden-ts:3005',
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('still_htr',
|
||||||
|
'frappy_psi.tcs.Heater',
|
||||||
|
'still heater',
|
||||||
|
io='tcs_io',
|
||||||
|
channel=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('mix_htr',
|
||||||
|
'frappy_psi.tcs.WrappedHeater',
|
||||||
|
'mixing chamber heater',
|
||||||
|
io='tcs_io',
|
||||||
|
channel=3,
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('drive_mix',
|
||||||
|
'frappy_psi.picontrol.PIctrl',
|
||||||
|
'controlled temperature ',
|
||||||
|
input_module = 'T_mxlow',
|
||||||
|
output_module = 'mix_htr',
|
||||||
|
output_min = 0,
|
||||||
|
output_max = 0.02,
|
||||||
|
p = 5,
|
||||||
|
itime = 60,
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('drive_cmn',
|
||||||
|
'frappy_psi.picontrol.PIctrl',
|
||||||
|
'controlled temperature ',
|
||||||
|
input_module = 'T_cmn',
|
||||||
|
output_module = 'mix_htr',
|
||||||
|
output_min = 0,
|
||||||
|
output_max = 1e-3,
|
||||||
|
p = 5,
|
||||||
|
itime = 120,
|
||||||
|
)
|
||||||
|
|
||||||
|
Mod('drive_fixp',
|
||||||
|
'frappy_psi.picontrol.PI',
|
||||||
|
'controlled temperature ',
|
||||||
|
value=Param(unit='V'),
|
||||||
|
input_module = 'V_fixp',
|
||||||
|
output_module = 'drive_mix',
|
||||||
|
output_min = 0.0,
|
||||||
|
output_max = 0.01,
|
||||||
|
p = 1,
|
||||||
|
itime = 120,
|
||||||
|
)
|
||||||
|
|
||||||
213
cfg/sea/leiden370.config.json
Normal file
213
cfg/sea/leiden370.config.json
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
{"tt": {"base": "/tt", "params": [
|
||||||
|
{"path": "", "type": "int", "kids": 18},
|
||||||
|
{"path": "send", "type": "text", "readonly": false, "cmd": "tt send", "visibility": 3},
|
||||||
|
{"path": "status", "type": "text", "visibility": 3},
|
||||||
|
{"path": "autoscan", "type": "bool", "readonly": false, "cmd": "tt autoscan", "kids": 4},
|
||||||
|
{"path": "autoscan/synchronized", "type": "bool", "readonly": false, "cmd": "tt autoscan/synchronized"},
|
||||||
|
{"path": "autoscan/interval", "type": "text", "readonly": false, "cmd": "tt autoscan/interval"},
|
||||||
|
{"path": "autoscan/pause", "type": "text", "readonly": false, "cmd": "tt autoscan/pause"},
|
||||||
|
{"path": "autoscan/dwell", "type": "text", "readonly": false, "cmd": "tt autoscan/dwell"},
|
||||||
|
{"path": "T3K", "type": "float", "kids": 14},
|
||||||
|
{"path": "T3K/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt T3K/active"},
|
||||||
|
{"path": "T3K/autorange", "type": "bool", "readonly": false, "cmd": "tt T3K/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "T3K/range", "type": "text", "readonly": false, "cmd": "tt T3K/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "T3K/range_num", "type": "int"},
|
||||||
|
{"path": "T3K/excitation", "type": "text", "readonly": false, "cmd": "tt T3K/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "T3K/excitation_num", "type": "int"},
|
||||||
|
{"path": "T3K/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "T3K/pause", "type": "int", "readonly": false, "cmd": "tt T3K/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "T3K/filter", "type": "int", "readonly": false, "cmd": "tt T3K/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "T3K/dwell", "type": "int", "readonly": false, "cmd": "tt T3K/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "T3K/status", "type": "text"},
|
||||||
|
{"path": "T3K/curve", "type": "text", "readonly": false, "cmd": "tt T3K/curve", "kids": 1},
|
||||||
|
{"path": "T3K/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt T3K/curve/points", "visibility": 3},
|
||||||
|
{"path": "T3K/alarm", "type": "float", "readonly": false, "cmd": "tt T3K/alarm"},
|
||||||
|
{"path": "T3K/raw", "type": "float"},
|
||||||
|
{"path": "Tstill", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tstill/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tstill/active"},
|
||||||
|
{"path": "Tstill/autorange", "type": "bool", "readonly": false, "cmd": "tt Tstill/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tstill/range", "type": "text", "readonly": false, "cmd": "tt Tstill/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tstill/range_num", "type": "int"},
|
||||||
|
{"path": "Tstill/excitation", "type": "text", "readonly": false, "cmd": "tt Tstill/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tstill/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tstill/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tstill/pause", "type": "int", "readonly": false, "cmd": "tt Tstill/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tstill/filter", "type": "int", "readonly": false, "cmd": "tt Tstill/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tstill/dwell", "type": "int", "readonly": false, "cmd": "tt Tstill/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tstill/status", "type": "text"},
|
||||||
|
{"path": "Tstill/curve", "type": "text", "readonly": false, "cmd": "tt Tstill/curve", "kids": 1},
|
||||||
|
{"path": "Tstill/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tstill/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tstill/alarm", "type": "float", "readonly": false, "cmd": "tt Tstill/alarm"},
|
||||||
|
{"path": "Tstill/raw", "type": "float"},
|
||||||
|
{"path": "T50mK", "type": "float", "kids": 14},
|
||||||
|
{"path": "T50mK/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt T50mK/active"},
|
||||||
|
{"path": "T50mK/autorange", "type": "bool", "readonly": false, "cmd": "tt T50mK/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "T50mK/range", "type": "text", "readonly": false, "cmd": "tt T50mK/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "T50mK/range_num", "type": "int"},
|
||||||
|
{"path": "T50mK/excitation", "type": "text", "readonly": false, "cmd": "tt T50mK/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "T50mK/excitation_num", "type": "int"},
|
||||||
|
{"path": "T50mK/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "T50mK/pause", "type": "int", "readonly": false, "cmd": "tt T50mK/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "T50mK/filter", "type": "int", "readonly": false, "cmd": "tt T50mK/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "T50mK/dwell", "type": "int", "readonly": false, "cmd": "tt T50mK/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "T50mK/status", "type": "text"},
|
||||||
|
{"path": "T50mK/curve", "type": "text", "readonly": false, "cmd": "tt T50mK/curve", "kids": 1},
|
||||||
|
{"path": "T50mK/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt T50mK/curve/points", "visibility": 3},
|
||||||
|
{"path": "T50mK/alarm", "type": "float", "readonly": false, "cmd": "tt T50mK/alarm"},
|
||||||
|
{"path": "T50mK/raw", "type": "float"},
|
||||||
|
{"path": "Tmxlow", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tmxlow/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tmxlow/active"},
|
||||||
|
{"path": "Tmxlow/autorange", "type": "bool", "readonly": false, "cmd": "tt Tmxlow/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tmxlow/range", "type": "text", "readonly": false, "cmd": "tt Tmxlow/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tmxlow/range_num", "type": "int"},
|
||||||
|
{"path": "Tmxlow/excitation", "type": "text", "readonly": false, "cmd": "tt Tmxlow/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tmxlow/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tmxlow/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tmxlow/pause", "type": "int", "readonly": false, "cmd": "tt Tmxlow/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tmxlow/filter", "type": "int", "readonly": false, "cmd": "tt Tmxlow/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tmxlow/dwell", "type": "int", "readonly": false, "cmd": "tt Tmxlow/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tmxlow/status", "type": "text"},
|
||||||
|
{"path": "Tmxlow/curve", "type": "text", "readonly": false, "cmd": "tt Tmxlow/curve", "kids": 1},
|
||||||
|
{"path": "Tmxlow/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tmxlow/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tmxlow/alarm", "type": "float", "readonly": false, "cmd": "tt Tmxlow/alarm"},
|
||||||
|
{"path": "Tmxlow/raw", "type": "float"},
|
||||||
|
{"path": "Tmxhigh", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tmxhigh/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tmxhigh/active"},
|
||||||
|
{"path": "Tmxhigh/autorange", "type": "bool", "readonly": false, "cmd": "tt Tmxhigh/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tmxhigh/range", "type": "text", "readonly": false, "cmd": "tt Tmxhigh/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tmxhigh/range_num", "type": "int"},
|
||||||
|
{"path": "Tmxhigh/excitation", "type": "text", "readonly": false, "cmd": "tt Tmxhigh/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tmxhigh/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tmxhigh/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tmxhigh/pause", "type": "int", "readonly": false, "cmd": "tt Tmxhigh/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tmxhigh/filter", "type": "int", "readonly": false, "cmd": "tt Tmxhigh/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tmxhigh/dwell", "type": "int", "readonly": false, "cmd": "tt Tmxhigh/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tmxhigh/status", "type": "text"},
|
||||||
|
{"path": "Tmxhigh/curve", "type": "text", "readonly": false, "cmd": "tt Tmxhigh/curve", "kids": 1},
|
||||||
|
{"path": "Tmxhigh/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tmxhigh/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tmxhigh/alarm", "type": "float", "readonly": false, "cmd": "tt Tmxhigh/alarm"},
|
||||||
|
{"path": "Tmxhigh/raw", "type": "float"},
|
||||||
|
{"path": "Tmxcx", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tmxcx/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tmxcx/active"},
|
||||||
|
{"path": "Tmxcx/autorange", "type": "bool", "readonly": false, "cmd": "tt Tmxcx/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tmxcx/range", "type": "text", "readonly": false, "cmd": "tt Tmxcx/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tmxcx/range_num", "type": "int"},
|
||||||
|
{"path": "Tmxcx/excitation", "type": "text", "readonly": false, "cmd": "tt Tmxcx/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tmxcx/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tmxcx/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tmxcx/pause", "type": "int", "readonly": false, "cmd": "tt Tmxcx/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tmxcx/filter", "type": "int", "readonly": false, "cmd": "tt Tmxcx/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tmxcx/dwell", "type": "int", "readonly": false, "cmd": "tt Tmxcx/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tmxcx/status", "type": "text"},
|
||||||
|
{"path": "Tmxcx/curve", "type": "text", "readonly": false, "cmd": "tt Tmxcx/curve", "kids": 1},
|
||||||
|
{"path": "Tmxcx/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tmxcx/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tmxcx/alarm", "type": "float", "readonly": false, "cmd": "tt Tmxcx/alarm"},
|
||||||
|
{"path": "Tmxcx/raw", "type": "float"},
|
||||||
|
{"path": "Tblueo", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tblueo/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tblueo/active"},
|
||||||
|
{"path": "Tblueo/autorange", "type": "bool", "readonly": false, "cmd": "tt Tblueo/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tblueo/range", "type": "text", "readonly": false, "cmd": "tt Tblueo/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tblueo/range_num", "type": "int"},
|
||||||
|
{"path": "Tblueo/excitation", "type": "text", "readonly": false, "cmd": "tt Tblueo/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tblueo/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tblueo/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tblueo/pause", "type": "int", "readonly": false, "cmd": "tt Tblueo/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tblueo/filter", "type": "int", "readonly": false, "cmd": "tt Tblueo/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tblueo/dwell", "type": "int", "readonly": false, "cmd": "tt Tblueo/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tblueo/status", "type": "text"},
|
||||||
|
{"path": "Tblueo/curve", "type": "text", "readonly": false, "cmd": "tt Tblueo/curve", "kids": 1},
|
||||||
|
{"path": "Tblueo/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tblueo/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tblueo/alarm", "type": "float", "readonly": false, "cmd": "tt Tblueo/alarm"},
|
||||||
|
{"path": "Tblueo/raw", "type": "float"},
|
||||||
|
{"path": "Tpt50", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tpt50/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tpt50/active"},
|
||||||
|
{"path": "Tpt50/autorange", "type": "bool", "readonly": false, "cmd": "tt Tpt50/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tpt50/range", "type": "text", "readonly": false, "cmd": "tt Tpt50/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tpt50/range_num", "type": "int"},
|
||||||
|
{"path": "Tpt50/excitation", "type": "text", "readonly": false, "cmd": "tt Tpt50/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tpt50/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tpt50/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tpt50/pause", "type": "int", "readonly": false, "cmd": "tt Tpt50/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tpt50/filter", "type": "int", "readonly": false, "cmd": "tt Tpt50/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tpt50/dwell", "type": "int", "readonly": false, "cmd": "tt Tpt50/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tpt50/status", "type": "text"},
|
||||||
|
{"path": "Tpt50/curve", "type": "text", "readonly": false, "cmd": "tt Tpt50/curve", "kids": 1},
|
||||||
|
{"path": "Tpt50/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tpt50/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tpt50/alarm", "type": "float", "readonly": false, "cmd": "tt Tpt50/alarm"},
|
||||||
|
{"path": "Tpt50/raw", "type": "float"},
|
||||||
|
{"path": "Tpt3high", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tpt3high/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tpt3high/active"},
|
||||||
|
{"path": "Tpt3high/autorange", "type": "bool", "readonly": false, "cmd": "tt Tpt3high/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tpt3high/range", "type": "text", "readonly": false, "cmd": "tt Tpt3high/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tpt3high/range_num", "type": "int"},
|
||||||
|
{"path": "Tpt3high/excitation", "type": "text", "readonly": false, "cmd": "tt Tpt3high/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tpt3high/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tpt3high/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tpt3high/pause", "type": "int", "readonly": false, "cmd": "tt Tpt3high/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tpt3high/filter", "type": "int", "readonly": false, "cmd": "tt Tpt3high/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tpt3high/dwell", "type": "int", "readonly": false, "cmd": "tt Tpt3high/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tpt3high/status", "type": "text"},
|
||||||
|
{"path": "Tpt3high/curve", "type": "text", "readonly": false, "cmd": "tt Tpt3high/curve", "kids": 1},
|
||||||
|
{"path": "Tpt3high/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tpt3high/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tpt3high/alarm", "type": "float", "readonly": false, "cmd": "tt Tpt3high/alarm"},
|
||||||
|
{"path": "Tpt3high/raw", "type": "float"},
|
||||||
|
{"path": "Tpt3low", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tpt3low/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tpt3low/active"},
|
||||||
|
{"path": "Tpt3low/autorange", "type": "bool", "readonly": false, "cmd": "tt Tpt3low/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tpt3low/range", "type": "text", "readonly": false, "cmd": "tt Tpt3low/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tpt3low/range_num", "type": "int"},
|
||||||
|
{"path": "Tpt3low/excitation", "type": "text", "readonly": false, "cmd": "tt Tpt3low/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tpt3low/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tpt3low/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tpt3low/pause", "type": "int", "readonly": false, "cmd": "tt Tpt3low/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tpt3low/filter", "type": "int", "readonly": false, "cmd": "tt Tpt3low/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tpt3low/dwell", "type": "int", "readonly": false, "cmd": "tt Tpt3low/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tpt3low/status", "type": "text"},
|
||||||
|
{"path": "Tpt3low/curve", "type": "text", "readonly": false, "cmd": "tt Tpt3low/curve", "kids": 1},
|
||||||
|
{"path": "Tpt3low/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tpt3low/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tpt3low/alarm", "type": "float", "readonly": false, "cmd": "tt Tpt3low/alarm"},
|
||||||
|
{"path": "Tpt3low/raw", "type": "float"},
|
||||||
|
{"path": "Twhite", "type": "float", "kids": 14},
|
||||||
|
{"path": "Twhite/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Twhite/active"},
|
||||||
|
{"path": "Twhite/autorange", "type": "bool", "readonly": false, "cmd": "tt Twhite/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Twhite/range", "type": "text", "readonly": false, "cmd": "tt Twhite/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Twhite/range_num", "type": "int"},
|
||||||
|
{"path": "Twhite/excitation", "type": "text", "readonly": false, "cmd": "tt Twhite/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Twhite/excitation_num", "type": "int"},
|
||||||
|
{"path": "Twhite/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Twhite/pause", "type": "int", "readonly": false, "cmd": "tt Twhite/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Twhite/filter", "type": "int", "readonly": false, "cmd": "tt Twhite/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Twhite/dwell", "type": "int", "readonly": false, "cmd": "tt Twhite/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Twhite/status", "type": "text"},
|
||||||
|
{"path": "Twhite/curve", "type": "text", "readonly": false, "cmd": "tt Twhite/curve", "kids": 1},
|
||||||
|
{"path": "Twhite/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Twhite/curve/points", "visibility": 3},
|
||||||
|
{"path": "Twhite/alarm", "type": "float", "readonly": false, "cmd": "tt Twhite/alarm"},
|
||||||
|
{"path": "Twhite/raw", "type": "float"},
|
||||||
|
{"path": "Tgreen", "type": "float", "kids": 14},
|
||||||
|
{"path": "Tgreen/active", "type": "enum", "enum": {"inactive": 0, "active": 1}, "readonly": false, "cmd": "tt Tgreen/active"},
|
||||||
|
{"path": "Tgreen/autorange", "type": "bool", "readonly": false, "cmd": "tt Tgreen/autorange", "description": "autorange (common for all channels)"},
|
||||||
|
{"path": "Tgreen/range", "type": "text", "readonly": false, "cmd": "tt Tgreen/range", "description": "resistance range in Ohm"},
|
||||||
|
{"path": "Tgreen/range_num", "type": "int"},
|
||||||
|
{"path": "Tgreen/excitation", "type": "text", "readonly": false, "cmd": "tt Tgreen/excitation", "description": "excitation with unit, i.e. 2uV or 3pA"},
|
||||||
|
{"path": "Tgreen/excitation_num", "type": "int"},
|
||||||
|
{"path": "Tgreen/excitation_mode", "type": "enum", "enum": {"voltage": 0, "current": 1, "off": 2}},
|
||||||
|
{"path": "Tgreen/pause", "type": "int", "readonly": false, "cmd": "tt Tgreen/pause", "description": "pause time [sec] after channel change"},
|
||||||
|
{"path": "Tgreen/filter", "type": "int", "readonly": false, "cmd": "tt Tgreen/filter", "description": "filter average time [sec]"},
|
||||||
|
{"path": "Tgreen/dwell", "type": "int", "readonly": false, "cmd": "tt Tgreen/dwell", "description": "dwell time [sec]. Total time per channel: pause + filter + dwell"},
|
||||||
|
{"path": "Tgreen/status", "type": "text"},
|
||||||
|
{"path": "Tgreen/curve", "type": "text", "readonly": false, "cmd": "tt Tgreen/curve", "kids": 1},
|
||||||
|
{"path": "Tgreen/curve/points", "type": "floatvarar", "readonly": false, "cmd": "tt Tgreen/curve/points", "visibility": 3},
|
||||||
|
{"path": "Tgreen/alarm", "type": "float", "readonly": false, "cmd": "tt Tgreen/alarm"},
|
||||||
|
{"path": "Tgreen/raw", "type": "float"},
|
||||||
|
{"path": "analog2", "type": "float", "readonly": false, "cmd": "tt analog2"},
|
||||||
|
{"path": "remote", "type": "bool"},
|
||||||
|
{"path": "display", "type": "text", "readonly": false, "cmd": "tt display"}]},
|
||||||
|
|
||||||
|
"cmn": {"base": "/cmn", "params": [
|
||||||
|
{"path": "", "type": "none", "kids": 6},
|
||||||
|
{"path": "send", "type": "text", "readonly": false, "cmd": "cmn send", "visibility": 3},
|
||||||
|
{"path": "status", "type": "text", "visibility": 3},
|
||||||
|
{"path": "u1", "type": "float"},
|
||||||
|
{"path": "temp", "type": "float"},
|
||||||
|
{"path": "u2", "type": "float"},
|
||||||
|
{"path": "chan", "type": "enum", "enum": {"auto": 0, "chan1": 1, "chan2": 2}, "readonly": false, "cmd": "cmn chan"}]}}
|
||||||
@@ -34,7 +34,7 @@ from frappy.lib import formatStatusBits
|
|||||||
from frappy.core import Done, Drivable, Parameter, Property, CommonReadHandler, CommonWriteHandler
|
from frappy.core import Done, Drivable, Parameter, Property, CommonReadHandler, CommonWriteHandler
|
||||||
from frappy.io import HasIO
|
from frappy.io import HasIO
|
||||||
from frappy_psi.channelswitcher import Channel, ChannelSwitcher
|
from frappy_psi.channelswitcher import Channel, ChannelSwitcher
|
||||||
from frappy_psi.picontrol import HasConvergence
|
from frappy.ctrlby import WrapControlledBy
|
||||||
|
|
||||||
|
|
||||||
Status = Drivable.Status
|
Status = Drivable.Status
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ and this is an example cfg
|
|||||||
'controlled T',
|
'controlled T',
|
||||||
meaning=['temperature', 20],
|
meaning=['temperature', 20],
|
||||||
output_module='htr_sample',
|
output_module='htr_sample',
|
||||||
p=1,
|
p=100,
|
||||||
i=0.01,
|
i=60,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -60,79 +60,164 @@ example cfg:
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
import math
|
import math
|
||||||
|
import numpy as np
|
||||||
from frappy.core import Readable, Writable, Parameter, Attached, IDLE, Property
|
from frappy.core import Readable, Writable, Parameter, Attached, IDLE, Property
|
||||||
from frappy.lib import clamp, merge_status
|
from frappy.lib import clamp, merge_status
|
||||||
from frappy.datatypes import LimitsType, EnumType, FloatRange
|
from frappy.datatypes import LimitsType, EnumType, FloatRange
|
||||||
|
from frappy.errors import SECoPError
|
||||||
from frappy.ctrlby import HasOutputModule, WrapControlledBy
|
from frappy.ctrlby import HasOutputModule, WrapControlledBy
|
||||||
from frappy_psi.convergence import HasConvergence
|
from frappy_psi.convergence import HasConvergence
|
||||||
|
|
||||||
|
|
||||||
|
def ext_poll_value(mobj):
|
||||||
|
prev = mobj.parameters['value'].timestamp
|
||||||
|
mobj.doPoll()
|
||||||
|
if mobj.parameters['value'].timestamp <= prev:
|
||||||
|
# value was not updated
|
||||||
|
mobj.read_value()
|
||||||
|
# disable polling for the next interval
|
||||||
|
interval = mobj.pollInfo.interval
|
||||||
|
if interval:
|
||||||
|
mobj.pollInfo.last_main = (time.time() // interval) * interval
|
||||||
|
return mobj.value
|
||||||
|
|
||||||
|
|
||||||
class PImixin(HasOutputModule, Writable):
|
class PImixin(HasOutputModule, Writable):
|
||||||
p = Parameter('proportional term', FloatRange(0), readonly=False)
|
value = Parameter(unit='K', update_unchanged='always')
|
||||||
i = Parameter('integral term', FloatRange(0), readonly=False)
|
p = Parameter('proportional term', FloatRange(0), readonly=False, default=1)
|
||||||
|
i = Parameter('integral term', FloatRange(0), readonly=False, default=1)
|
||||||
|
status = Parameter(update_unchanged='never')
|
||||||
|
itime = Parameter('integration time', FloatRange(0, unit='s'), default=60, readonly=False)
|
||||||
|
control_active = Parameter(readonly=False)
|
||||||
|
|
||||||
# output_module is inherited
|
# output_module is inherited
|
||||||
output_range = Property('legacy output range', LimitsType(FloatRange()), default=(0,0))
|
output_range = Property('legacy output range', LimitsType(FloatRange()), default=(0, 0))
|
||||||
output_min = Parameter('min output', FloatRange(), default=0, readonly=False)
|
output_min = Parameter('min output', FloatRange(), default=0, readonly=False)
|
||||||
output_max = Parameter('max output', FloatRange(), default=0, readonly=False)
|
output_max = Parameter('max output', FloatRange(), default=0, readonly=False)
|
||||||
output_func = Parameter('output function',
|
input_scale = Property('input scale', FloatRange(unit='$'), default=100)
|
||||||
EnumType(lin=0, square=1), readonly=False, value=0)
|
time_scale = Property('time scale', FloatRange(unit='s'), default=60)
|
||||||
value = Parameter(unit='K')
|
overflow = Parameter('overflow', FloatRange(), default=0, readonly=False)
|
||||||
|
|
||||||
_lastdiff = None
|
_lastdiff = None
|
||||||
_lasttime = 0
|
_lasttime = 0
|
||||||
_get_range = None # a function get output range from output_module
|
_get_range = None # a function get output range from output_module
|
||||||
_overflow = 0
|
_overflow = 0
|
||||||
_cvt2int = None
|
_itime_set = None # True: 'itime' was set, False: 'i' was set
|
||||||
_cvt2ext = None
|
_history = None
|
||||||
|
__errcnt = 0
|
||||||
|
__inside_poll = False
|
||||||
|
__cache = None
|
||||||
|
|
||||||
|
# with input units K and output units %:
|
||||||
|
# units for p: % / K
|
||||||
|
# units for i: % / K / min
|
||||||
|
|
||||||
def initModule(self):
|
def initModule(self):
|
||||||
|
self.__cache = {}
|
||||||
super().initModule()
|
super().initModule()
|
||||||
if self.output_range != (0, 0): # legacy !
|
if self.output_range != (0, 0): # legacy !
|
||||||
self.output_min, self.output_max = self.output_range
|
self.output_min, self.output_max = self.output_range
|
||||||
|
self.get_range_func()
|
||||||
|
self.addCallback('value', self.__inside, 'value')
|
||||||
|
self.addCallback('status', self.__inside, 'status')
|
||||||
|
|
||||||
|
def __inside(self, value, pname):
|
||||||
|
if self.__inside_poll is not None:
|
||||||
|
self.__cache[pname] = value
|
||||||
|
|
||||||
def doPoll(self):
|
def doPoll(self):
|
||||||
super().doPoll()
|
try:
|
||||||
if not self.control_active:
|
self.__inside_poll = True
|
||||||
return
|
self.__cache = {}
|
||||||
out = self.output_module
|
now = time.time()
|
||||||
now = time.time()
|
value = self.read_value()
|
||||||
deltat = clamp(0, now-self._lasttime, 10)
|
if self._history is None:
|
||||||
self._lasttime = now
|
# initialize a fixed size array, with fake time axis to avoid errors in np.polyfit
|
||||||
diff = self.target - self.value
|
self._history = np.array([(now+i, self.value) for i in range(-9,1)])
|
||||||
if self._lastdiff is None:
|
else:
|
||||||
|
# shift fixed size array, and change last point
|
||||||
|
self._history[:-1] = self._history[1:]
|
||||||
|
self._history[-1] = (now, value)
|
||||||
|
if not self.control_active:
|
||||||
|
self._lastdiff = 0
|
||||||
|
return
|
||||||
|
self.read_status()
|
||||||
|
out = self.output_module
|
||||||
|
deltat = clamp(0, now-self._lasttime, 10)
|
||||||
|
self._lasttime = now
|
||||||
|
diff = self.target - value
|
||||||
|
if self._lastdiff is None:
|
||||||
|
self._lastdiff = diff
|
||||||
|
deltadiff = diff - self._lastdiff
|
||||||
self._lastdiff = diff
|
self._lastdiff = diff
|
||||||
deltadiff = diff - self._lastdiff
|
if diff:
|
||||||
self._lastdiff = diff
|
ref = self.itime / diff
|
||||||
output, omin, omax = self._cvt2int(out.target)
|
(slope, _), cov = np.polyfit(self._history[:, 0] - now, self._history[:, 1], 1, cov=True)
|
||||||
output += self._overflow + self.p * deltadiff + self.i * deltat * diff
|
slope_stddev = np.sqrt(max(0, cov[0, 0]))
|
||||||
if output < omin:
|
if slope * ref > 1 + 2 * slope_stddev * abs(ref):
|
||||||
self._overflow = max(omin - omax, output - omin)
|
# extrapolated value will cross target in less than itime
|
||||||
output = omin
|
if self._overflow:
|
||||||
elif output > omax:
|
self._overflow = 0
|
||||||
self._overflow = min(omax - omin, output - omax)
|
self.log.info('clear overflow')
|
||||||
output = omax
|
|
||||||
else:
|
output, omin, omax = self.cvt2int(out.target)
|
||||||
self._overflow = 0
|
output += self._overflow + (
|
||||||
out.update_target(self.name, self._cvt2ext(output))
|
self.p * deltadiff +
|
||||||
|
self.i * deltat * diff / self.time_scale) / self.input_scale
|
||||||
|
if omin <= output <= omax:
|
||||||
|
self._overflow = 0
|
||||||
|
else:
|
||||||
|
# save overflow for next step
|
||||||
|
if output < omin:
|
||||||
|
self._overflow = output - omin
|
||||||
|
output = omin
|
||||||
|
else:
|
||||||
|
self._overflow = output - omax
|
||||||
|
output = omax
|
||||||
|
out.update_target(self.name, self.cvt2ext(output))
|
||||||
|
self.__errcnt = 0
|
||||||
|
except Exception as e:
|
||||||
|
if self.control_active:
|
||||||
|
self.__errcnt += 1
|
||||||
|
if self.__errcnt > 5:
|
||||||
|
self.__errcnt = 0
|
||||||
|
self.log.warning('too many errors - switch control off')
|
||||||
|
self.write_control_active(False)
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.__inside_poll = False
|
||||||
|
self.__cache = {}
|
||||||
|
self.overflow = self._overflow
|
||||||
|
|
||||||
|
def write_overflow(self, value):
|
||||||
|
self._overflow = value
|
||||||
|
|
||||||
|
def internal_poll(self):
|
||||||
|
super().doPoll()
|
||||||
|
|
||||||
|
def internal_read_value(self):
|
||||||
|
return super().read_value()
|
||||||
|
|
||||||
|
def internal_read_status(self):
|
||||||
|
return super().read_status()
|
||||||
|
|
||||||
|
def read_value(self):
|
||||||
|
try:
|
||||||
|
return self.__cache['value']
|
||||||
|
except KeyError:
|
||||||
|
return self.internal_read_value()
|
||||||
|
|
||||||
def read_status(self):
|
def read_status(self):
|
||||||
|
try:
|
||||||
|
return self.__cache['status']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
status = IDLE, 'controlling' if self.control_active else 'inactive'
|
status = IDLE, 'controlling' if self.control_active else 'inactive'
|
||||||
if hasattr(super(), 'read_status'):
|
if hasattr(super(), 'read_status'):
|
||||||
status = merge_status(super().read_status(), status)
|
status = merge_status(self.internal_read_status(), status)
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def cvt2int_square(self, output):
|
def get_range_func(self):
|
||||||
return (math.sqrt(max(0, clamp(x, *self._get_range()))) for x in (output, self.output_min, self.output_max))
|
|
||||||
|
|
||||||
def cvt2ext_square(self, output):
|
|
||||||
return output ** 2
|
|
||||||
|
|
||||||
def cvt2int_lin(self, output):
|
|
||||||
return (clamp(x, *self._get_range()) for x in (output, self.output_min, self.output_max))
|
|
||||||
|
|
||||||
def cvt2ext_lin(self, output):
|
|
||||||
return output
|
|
||||||
|
|
||||||
def write_output_func(self, value):
|
|
||||||
out = self.output_module
|
out = self.output_module
|
||||||
if hasattr(out, 'max_target'):
|
if hasattr(out, 'max_target'):
|
||||||
if hasattr(self, 'min_target'):
|
if hasattr(self, 'min_target'):
|
||||||
@@ -147,32 +232,72 @@ class PImixin(HasOutputModule, Writable):
|
|||||||
self._get_range = lambda o=self: (o.output_min, o.output_max)
|
self._get_range = lambda o=self: (o.output_min, o.output_max)
|
||||||
if self.output_min == self.output_max == 0:
|
if self.output_min == self.output_max == 0:
|
||||||
self.output_min, self.output_max = self._get_range()
|
self.output_min, self.output_max = self._get_range()
|
||||||
self.output_func = value
|
|
||||||
self._cvt2int = getattr(self, f'cvt2int_{self.output_func.name}')
|
|
||||||
self._cvt2ext = getattr(self, f'cvt2ext_{self.output_func.name}')
|
|
||||||
|
|
||||||
# not needed, done by HasOutputModule.write_control_active
|
def cvt2int(self, output):
|
||||||
# def write_control_active(self, value):
|
return (clamp(x, *self._get_range()) for x in (output, self.output_min, self.output_max))
|
||||||
# super().write_control_active(value)
|
|
||||||
# out = self.output_module
|
def cvt2ext(self, output):
|
||||||
# if not value:
|
return output
|
||||||
# out.write_target(out.parameters['target'].datatype.default)
|
|
||||||
|
def calc_itime(self, prop, integ):
|
||||||
|
return prop * self.time_scale / integ
|
||||||
|
|
||||||
|
def write_p(self, value):
|
||||||
|
if self._itime_set:
|
||||||
|
self.i = value * self.time_scale / self.itime
|
||||||
|
elif self._itime_set is False: # means also not None
|
||||||
|
self.itime = value * self.time_scale / self.i
|
||||||
|
|
||||||
|
def write_i(self, value):
|
||||||
|
self._itime_set = False
|
||||||
|
self.itime = self.p * self.time_scale / value
|
||||||
|
|
||||||
|
def write_itime(self, value):
|
||||||
|
self._itime_set = True
|
||||||
|
self.i = self.p * self.time_scale / value
|
||||||
|
|
||||||
def set_target(self, value):
|
def set_target(self, value):
|
||||||
if not self.control_active:
|
if not self.control_active:
|
||||||
self.activate_control()
|
self.activate_control()
|
||||||
|
self.target = value
|
||||||
|
self.doPoll()
|
||||||
|
|
||||||
|
|
||||||
|
class PImixinSquare(PImixin):
|
||||||
|
"""unchecked: use square as output function"""
|
||||||
|
def cvt2int(self, output):
|
||||||
|
return (math.sqrt(max(0, 100 * clamp(x, *self._get_range())))
|
||||||
|
for x in (output, self.output_min, self.output_max))
|
||||||
|
|
||||||
|
def cvt2ext(self, output):
|
||||||
|
return output ** 2 / 100
|
||||||
|
|
||||||
|
|
||||||
class PI(HasConvergence, PImixin):
|
class PI(HasConvergence, PImixin):
|
||||||
input_module = Attached(Readable, 'the input module')
|
input_module = Attached(Readable, 'the input module')
|
||||||
|
|
||||||
def read_value(self):
|
def internal_poll(self):
|
||||||
return self.input_module.value
|
inp = self.input_module
|
||||||
|
inp.doPoll()
|
||||||
|
interval = inp.pollInfo.interval
|
||||||
|
if interval > 0:
|
||||||
|
# disable next internal poll
|
||||||
|
inp.pollInfo.last_main = (time.time() // interval) * interval
|
||||||
|
self.read_value()
|
||||||
|
self.read_status()
|
||||||
|
|
||||||
def read_status(self):
|
def internal_read_value(self):
|
||||||
return self.input_module.status
|
return self.input_module.read_value()
|
||||||
|
|
||||||
|
def internal_read_status(self):
|
||||||
|
return self.input_module.read_status()
|
||||||
|
|
||||||
|
def write_target(self, target):
|
||||||
|
super().write_target(target)
|
||||||
|
self.convergence_start()
|
||||||
|
|
||||||
|
|
||||||
|
# unchecked!
|
||||||
class PI2(PI):
|
class PI2(PI):
|
||||||
maxovershoot = Parameter('max. overshoot', FloatRange(0, 100, unit='%'), readonly=False, default=20)
|
maxovershoot = Parameter('max. overshoot', FloatRange(0, 100, unit='%'), readonly=False, default=20)
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
from frappy.core import StringIO, HasIO, Writable, Parameter, Property, FloatRange, IntRange, BoolType, \
|
from frappy.core import StringIO, HasIO, Writable, Parameter, Property, FloatRange, IntRange, BoolType, \
|
||||||
ERROR
|
ERROR
|
||||||
from frappy.errors import CommunicationFailedError, HardwareError
|
from frappy.errors import CommunicationFailedError, HardwareError
|
||||||
|
from frappy.ctrlby import WrapControlledBy
|
||||||
|
|
||||||
|
|
||||||
class IO(StringIO):
|
class IO(StringIO):
|
||||||
@@ -36,7 +37,7 @@ class Heater(HasIO, Writable):
|
|||||||
channel = Property('channel (source number)', IntRange(1, 3))
|
channel = Property('channel (source number)', IntRange(1, 3))
|
||||||
value = Parameter('current reading', FloatRange(0, 0.1, unit='A'))
|
value = Parameter('current reading', FloatRange(0, 0.1, unit='A'))
|
||||||
target = Parameter('current target value', FloatRange(0, 0.1, unit='A'), readonly=False)
|
target = Parameter('current target value', FloatRange(0, 0.1, unit='A'), readonly=False)
|
||||||
on = Parameter('turn current on/off', BoolType(), readonly=False)
|
on = Parameter('turn current on/off', BoolType(), readonly=False, default=False)
|
||||||
|
|
||||||
def query_status(self):
|
def query_status(self):
|
||||||
reply, txtvalue = self.communicate('STATUS?').split('\t')
|
reply, txtvalue = self.communicate('STATUS?').split('\t')
|
||||||
@@ -64,13 +65,14 @@ class Heater(HasIO, Writable):
|
|||||||
if reply != '0': # not as in manual
|
if reply != '0': # not as in manual
|
||||||
raise CommunicationFailedError(f'Bad reply: {reply!r}')
|
raise CommunicationFailedError(f'Bad reply: {reply!r}')
|
||||||
|
|
||||||
def read_target(self):
|
def read_value(self):
|
||||||
txtvalue = self.query_status()
|
txtvalue = self.query_status()
|
||||||
current_range = txtvalue[(self.channel - 1) * 4 + 1]
|
current_range = txtvalue[(self.channel - 1) * 4 + 1]
|
||||||
current = txtvalue[(self.channel - 1) * 4 + 1 + 1] # percent of range
|
current = txtvalue[(self.channel - 1) * 4 + 1 + 1] # percent of range
|
||||||
multipliers = {'1': 99e-6, '2': 990e-6, '3': 9900e-6, '4': 99e-3}
|
multipliers = {'1': 1e-4, '2': 1e-3, '3': 1e-2, '4': 1e-1}
|
||||||
value = float(current) / 100 * float(multipliers[current_range])
|
value = float(current) / 100 * float(multipliers[current_range])
|
||||||
return value
|
return value
|
||||||
|
|
||||||
# no measured value available
|
|
||||||
read_value = read_target
|
class WrappedHeater(WrapControlledBy, Heater):
|
||||||
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user