diff --git a/cfg/fi_cfg.py b/cfg/fi_cfg.py index 5cf68c1..6d6f566 100644 --- a/cfg/fi_cfg.py +++ b/cfg/fi_cfg.py @@ -6,7 +6,7 @@ Node('fi.psi.ch', Mod('htr_io', 'frappy_psi.tdkpower.IO', 'powersupply communicator', - uri='serial:///dev/ttyUSB0', + uri='serial:///dev/ttyUSB0?baudrate=9600', ) Mod('htr', @@ -16,7 +16,7 @@ Mod('htr', ) Mod('out', - 'frappy_psi.bkpower.Output', + 'frappy_psi.tdkpower.Output', 'heater output', io='htr_io', maxvolt=8, @@ -54,7 +54,7 @@ Mod('T', 'frappy_psi.furnace.PI', 'controlled Temperature', input='T_htr', - output='out', + output='htr', relais='relais', p=2, i=0.01, diff --git a/frappy_psi/picontrol.py b/frappy_psi/picontrol.py index 47c59ae..4c52098 100644 --- a/frappy_psi/picontrol.py +++ b/frappy_psi/picontrol.py @@ -60,7 +60,7 @@ example cfg: import time import math -from frappy.core import Readable, Writable, Parameter, Attached, IDLE +from frappy.core import Readable, Writable, Parameter, Attached, IDLE, Property from frappy.lib import clamp from frappy.datatypes import LimitsType, EnumType, BoolType, FloatRange from frappy.mixins import HasOutputModule @@ -71,8 +71,9 @@ class PImixin(HasOutputModule, Writable): p = Parameter('proportional term', FloatRange(0), readonly=False) i = Parameter('integral term', FloatRange(0), readonly=False) # output_module is inherited - output_range = Parameter('min output', - LimitsType(FloatRange()), default=(0, 0), readonly=False) + output_range = Property('legacy output range', LimitsType(FloatRange()), default=(0,0)) + output_min = Parameter('min output', FloatRange(), default=0, readonly=False) + output_max = Parameter('max output', FloatRange(), default=0, readonly=False) output_func = Parameter('output function', EnumType(lin=0, square=1), readonly=False, default=0) value = Parameter(unit='K') @@ -80,6 +81,11 @@ class PImixin(HasOutputModule, Writable): _lasttime = 0 _clamp_limits = None + def initModule(self): + super().initModule() + if self.output_range != (0, 0): # legacy ! + self.output_min, self.output_max = self.output_range + def doPoll(self): super().doPoll() if self._clamp_limits is None: @@ -93,8 +99,8 @@ class PImixin(HasOutputModule, Writable): self._clamp_limits = lambda v, o=out: clamp(v, 0, o.read_limit()) else: self._clamp_limits = lambda v: v - if self.output_range == (0.0, 0.0): - self.output_range = (0, self._clamp_limits(float('inf'))) + if self.output_min == 0 and self.output_max == 0: + self.output_max = self._clamp_limits(float('inf')) if not self.control_active: return self.status = IDLE, 'controlling' @@ -114,7 +120,7 @@ class PImixin(HasOutputModule, Writable): if self.output_func == 'square': output = output ** 2 output = self._clamp_limits(output) - out.update_target(self.name, clamp(output, *self.output_range)) + out.update_target(self.name, clamp(output, self.output_min, self.output_max)) def write_control_active(self, value): if not value: @@ -125,61 +131,6 @@ class PImixin(HasOutputModule, Writable): self.activate_control() -# quick fix by Marek: -class PIobsolete(Writable): - """temporary, but working version from Marek""" - input = Attached(Readable, 'the input module') - output = Attached(Writable, 'the output module') - output_max = Parameter('max output value', FloatRange(0), readonly=False) - p = Parameter('proportional term', FloatRange(0), readonly=False) - i = Parameter('integral term', FloatRange(0), readonly=False) - control_active = Parameter('control flag', BoolType(), readonly=False, default=False) - value = Parameter(unit='K') - tlim = Parameter('max Temperature', FloatRange(0), readonly=False) - _lastdiff = None - _lasttime = 0 - _lastvalue = 0 - - def doPoll(self): - super().doPoll() - if not self.control_active: - return - self.value = self.input.value - self.status = IDLE, 'controlling' - now = time.time() - deltat = min(10.0, now-self._lasttime) - self._lasttime = now - if self.value != self._lastvalue: - diff = self.target - self.value # calculate the difference to target - self._lastvalue = self.value - # else ? (diff is undefined!) - if self.value > self.tlim: - self.write_control_active(False) - return - if self._lastdiff is None: - self._lastdiff = diff - deltadiff = diff - self._lastdiff # calculate the change in deltaT - self._lastdiff = diff - output = self.output.target - output += self.p * deltadiff + self.i * deltat * diff - if output > self.output_max: - output = self.output_max - elif output < 0: - output = 0 - self.output.write_target(output) - - def write_control_active(self, value): - if not value: - self.output.write_target(0) - - def write_target(self, value): - self.control_active = True - - -# proposal for replacing above PI class, inheriting from PImixin -# additional features: -# - is a Drivable, using the convergence criteria from HasConvergence -# - tries to determine the output limits automatically # unchecked! class PI(HasConvergence, PImixin): @@ -190,3 +141,18 @@ class PI(HasConvergence, PImixin): def read_status(self): return self.input_module.status + + +class PI2(PI): + maxovershoot = Parameter('max. overshoot', FloatRange(0, 100, unit='%'), readonly=False, default=20) + + def doPoll(self): + self.output_max = self.target * (1 + 0.01 * self.maxovershoot) + self.output_min = self.target * (1 - 0.01 * self.maxovershoot) + super().doPoll() + + def write_target(self, target): + if not self.control_active: + self.output.write_target(target) + super().write_target(target) + diff --git a/frappy_psi/tdkpower.py b/frappy_psi/tdkpower.py index 8361422..9c62c0f 100644 --- a/frappy_psi/tdkpower.py +++ b/frappy_psi/tdkpower.py @@ -24,10 +24,11 @@ from frappy.datatypes import BoolType, EnumType, FloatRange class IO(StringIO): - end_of_line = ('OK\r', '\r') + end_of_line = '\r' default_settings = {'baudrate': 9600} + identification = [('ADR 0', 'OK'), ('IDN?', r'LAMBDA,GEN8-400')] + - class Power(HasIO, Readable): value = Parameter(datatype=FloatRange(0,3300,unit='W'))