779 lines
21 KiB
Tcl
779 lines
21 KiB
Tcl
namespace eval ccu4flow {
|
|
}
|
|
|
|
proc stdConfig::ccu4flow {args} {
|
|
variable node
|
|
|
|
controller syncedprot
|
|
|
|
obj ccu4flow wr
|
|
prop write ccu4flow::setmode
|
|
prop read ccu4flow::read
|
|
prop dir 1
|
|
prop enum fixed=0,controlled=1,automatic=2,close=3,open=4
|
|
prop filter 0
|
|
prop regstate reg
|
|
prop measured_openpulse 0
|
|
prop pulse 0
|
|
prop olddif 0
|
|
prop settime 0
|
|
prop soll 0
|
|
prop adjustdelay 10
|
|
prop maxhysteresis 1
|
|
prop hystlim 1
|
|
prop period 5
|
|
prop lastpulse 0
|
|
prop totalmin 0
|
|
prop minpulse 0
|
|
prop lastmov 0
|
|
prop hystpulse 0
|
|
prop lastist 0
|
|
set sensirion 0
|
|
foreach arg $args {
|
|
if {$arg eq "release_blocked"} {
|
|
prop release_blocked 1
|
|
}
|
|
if {$arg eq "1"} {
|
|
set sensirion 1
|
|
}
|
|
}
|
|
default 0
|
|
kids "needle valve" {
|
|
node motstat alias /cc/fm
|
|
prop enum idle,opening,closing,opened,closed,no_motor
|
|
|
|
node flow upd -secop=nvflow
|
|
|
|
node set out
|
|
default 1.0
|
|
prop check ccu4flow::checkset
|
|
prop write stdSct::complete
|
|
prop label "flow set"
|
|
|
|
node flowmax par 20
|
|
prop label "flow maximum"
|
|
|
|
node flowp upd
|
|
prop help "flow calculated from pressure before pump"
|
|
|
|
node span upd
|
|
|
|
node use_pressure par -int [expr !$sensirion]
|
|
prop enum 1
|
|
prop help "use pressure instead of flow meter for control"
|
|
|
|
node ctrl -none
|
|
kids "control parameters" {
|
|
node regtext upd -text
|
|
default regulate
|
|
prop label status
|
|
prop width 40
|
|
|
|
node prop_o par 0.05
|
|
prop help {prop [sec/mbar] when opening. above 4 mbar a 10 times lower value is used}
|
|
|
|
node prop_c par 0.03
|
|
prop help {prop [sec/mbar] when closing. above 4 mbar a 10 times lower value is used}
|
|
|
|
node deriv_o par 30
|
|
prop help {convergence target time [sec] when opening}
|
|
|
|
node deriv_c par 30
|
|
prop help {convergence target time [sec] when closing}
|
|
|
|
node minpulse_o out
|
|
default 0.05
|
|
prop help {minimum close pulse [sec]}
|
|
prop check "ccu4flow::check_minpulse 1"
|
|
prop write stdSct::complete
|
|
|
|
node minpulse_c out
|
|
default 0.05
|
|
prop help {standard close pulse [sec]}
|
|
prop check "ccu4flow::check_minpulse -1"
|
|
prop write stdSct::complete
|
|
|
|
node hystpulse_o par 0
|
|
prop help {motor pulse to overcome hysteresis when opening}
|
|
|
|
node hystpulse_c par 0
|
|
prop help {motor pulse to overcome hysteresis when closing}
|
|
|
|
node tol par 0.25
|
|
prop label tolerance
|
|
prop help {valid below 3 mbar}
|
|
|
|
node tolhigh par 0.5
|
|
prop label tol. above 4
|
|
prop help {valid above 4 mbar}
|
|
|
|
node openpulse par 60
|
|
prop help {time to open from completely closed to a significant opening}
|
|
|
|
node adjust_minpulse par 1
|
|
prop enum 1
|
|
prop help {adjust minpulse automatically}
|
|
}
|
|
|
|
node autoflow -none
|
|
kids "autoflow control parameters" {
|
|
flow::make ccu4flow::tmts {result tt set/reg}
|
|
}
|
|
node calib -none
|
|
kids calib {
|
|
node ln_per_min_per_mbar par 0.9
|
|
node mbar_offset par 0.8
|
|
}
|
|
}
|
|
}
|
|
|
|
proc ccu4flow::tmts {} {
|
|
global tt
|
|
|
|
set tm [silent 1 result tt tm]
|
|
set ts [silent $tm result tt ts]
|
|
if {$ts < $tm} {
|
|
return $ts
|
|
} else {
|
|
return $tm
|
|
}
|
|
}
|
|
|
|
proc ccu4flow::checkset {} {
|
|
set dir [hgetpropval [sct parent] dir]
|
|
# if {([sct target] - [hvali [sct]]) * $dir < 0} {
|
|
# # we probably initiate a dir change
|
|
# if {$invcnt > 0} {
|
|
# incr invcnt -1
|
|
# hsetprop [sct parent] invcnt $invcnt
|
|
# logtext invcnt -1 by set
|
|
# }
|
|
# }
|
|
if {[hvali [sct]] != [sct target]} {
|
|
hsetprop [sct parent] setchanged 1
|
|
hsetprop [sct parent] settime [DoubleTime]
|
|
}
|
|
sct update [sct target]
|
|
#hupdate /cc/fm 0
|
|
set s [hvali [sct parent]]
|
|
if {[hvali /cc/fa] == 0 || ($s != 1 && $s != 2)} {
|
|
hset [sct parent] 1
|
|
}
|
|
}
|
|
|
|
proc ccu4flow::check_minpulse {dir} {
|
|
if {$dir == [hgetpropval [sct objectPath] dir]} {
|
|
hsetprop [sct objectPath] minpulse [sct target]
|
|
}
|
|
sct update [sct target]
|
|
}
|
|
|
|
proc ccu4flow::read {} {
|
|
hsetprop /cc/fa nvpath [sct]
|
|
_cc updatescript /cc/fa ccu4flow::updatemode
|
|
hsetprop /cc/f nvpath [sct]
|
|
hsetprop /cc/f nvctrl [sct controller]
|
|
hsetprop /cc/f flowsource pressure
|
|
_cc updatescript /cc/f ccu4flow::updateflow
|
|
catch {
|
|
hsetprop /nvflow flowsource flow
|
|
hsetprop /nvflow nvpath [sct]
|
|
hsetprop /nvflow nvctrl [sct controller]
|
|
_hemot updatescript /nvflow ccu4flow::updateflow
|
|
}
|
|
return unpoll
|
|
}
|
|
|
|
proc ccu4flow::setmode {} {
|
|
sctsync {
|
|
sct update [sct target]
|
|
if {[sct target] == 3} {
|
|
# close
|
|
cc fa 0
|
|
cc mp -[hvali /cc/mot]
|
|
# set motstat to opening (until it gets updated)
|
|
hupdate /cc/fm 2
|
|
} elseif {[sct target] == 4} {
|
|
# open
|
|
cc fa 0
|
|
cc mp [hvali /cc/mot]
|
|
# set motstat to closing (until it gets updated)
|
|
hupdate /cc/fm 1
|
|
} else {
|
|
if {[sct target] == 2} {
|
|
hupdate [sct]/autoflow/suspended 0
|
|
}
|
|
cc fa [sct target]
|
|
cc mp 0
|
|
}
|
|
}
|
|
return stdSct::complete
|
|
}
|
|
|
|
proc ccu4flow::updatemode {value} {
|
|
if {$value == 3} {
|
|
set mode [hvali [sct nvpath]]
|
|
clientput "[sct parent] was offline $mode"
|
|
if {$mode >= 3} {
|
|
set mode 0
|
|
}
|
|
hset [sct] $mode
|
|
} elseif {[hvali [sct nvpath]] < 3 || $value > 0} {
|
|
if {$value ne [hvali [sct nvpath]]} {
|
|
clientput "[sct] changed to $value -> $nvpath"
|
|
}
|
|
hupdate [sct nvpath] $value
|
|
}
|
|
}
|
|
|
|
proc ccu4flow::updateflow {value} {
|
|
# flowsource:
|
|
# pressure: this is a pressure
|
|
# flow: this is a flow from a flowmeter
|
|
|
|
set source [silent none sct flowsource]
|
|
set n [silent 9 sct filter_n]
|
|
set filter [lrange "[silent $value sct filter] $value" end-$n end]
|
|
sct filter $filter
|
|
# filter out values which are within the m highest or m lowest values
|
|
# out of n+1 last values (i.e. within 5 seconds) (m was 3)
|
|
set m [silent 0 sct filter_m]
|
|
set filter [lsort -real $filter]
|
|
if {[llength $filter] < $n} {
|
|
set flow $value
|
|
set flow0 $value
|
|
set span 0
|
|
} else {
|
|
set min [expr [lindex $filter $m] - 0.1]
|
|
set max [expr [lindex $filter end-$m] + 0.1]
|
|
set mean [expr double([join $filter +]) / [llength $filter]]
|
|
set span [expr $max - $min - 0.2]
|
|
set flow [silent 0 sct filtered]
|
|
if {$max < $flow} {
|
|
# if {[sct] ne "/cc/f"} {
|
|
# clientput "[sct] fast decrease $flow $max"
|
|
# }
|
|
set flow $max
|
|
} elseif {$min > $flow} {
|
|
# if {[sct] ne "/cc/f"} {
|
|
# clientput "[sct] fast increase $flow $min"
|
|
# }
|
|
set flow $min
|
|
} else {
|
|
set flow [expr $flow * 0.98 + $mean * 0.02]
|
|
}
|
|
}
|
|
sct filtered $flow
|
|
if {$source eq "flow"} {
|
|
updateval [sct nvpath]/flow $flow
|
|
} elseif {$source eq "pressure"} {
|
|
if {$flow < -50} {
|
|
set flow -62.5
|
|
} else {
|
|
set off [hval [sct nvpath]/calib/mbar_offset]
|
|
set fpm [hval [sct nvpath]/calib/ln_per_min_per_mbar]
|
|
set flow [expr ($flow - $off) * $fpm]
|
|
}
|
|
updateval_e [sct nvpath]/flowp $flow -62.5 no_sensor
|
|
hupdate [sct nvpath]/span $span
|
|
} else {
|
|
error "[sct] illegal flowsource: $source"
|
|
}
|
|
[sct nvctrl] queue [sct nvpath] read ccu4flow::ctrl
|
|
}
|
|
|
|
proc ccu4flow::increase {val by min max} {
|
|
if {$val < $min} {
|
|
set val $min
|
|
}
|
|
set lg [expr round(log10($val) * 10 + $by) * 0.1]
|
|
set dig [expr int(1.85 - $lg)]
|
|
if {$dig < 0} {
|
|
set dig 0
|
|
}
|
|
set v [format "%.${dig}f" [expr pow(10.0, $lg)]]
|
|
if {$v > $max} {
|
|
return $max
|
|
} elseif {$v < $min} {
|
|
return $min
|
|
} else {
|
|
return $v
|
|
}
|
|
}
|
|
|
|
proc ccu4flow::trf {value} {
|
|
if {$value <= 1.0} {
|
|
return [expr $value - 1.0]
|
|
}
|
|
return [format %.2f [expr log($value)]]
|
|
}
|
|
|
|
proc ccu4flow::setstate {state {text ""}} {
|
|
upvar regstate r
|
|
if {$text eq ""} {
|
|
set text $state
|
|
}
|
|
# if {$text ne [hvali [sct]/ctrl/regtext]} {
|
|
# clientput "R $text"
|
|
# }
|
|
set r $state
|
|
hset [sct]/ctrl/regtext $text
|
|
}
|
|
|
|
proc ccu4flow::logtext args {
|
|
# clientput [concat $args]
|
|
}
|
|
|
|
proc ccu4flow::ctrl {} {
|
|
set umsg "automatic needle valve not activated - set temperature undefined"
|
|
set mode [sctval [sct]]
|
|
set oldmode $mode
|
|
# pump_is_off is defined in startup/hepump.tcl
|
|
if {[info command pump_is_off] ne "" && ($mode == 2 || $mode == 1)} {
|
|
if {[pump_is_off]} {
|
|
set mode 0
|
|
}
|
|
}
|
|
if {$mode == 2 && [sctval [sct]/autoflow/suspended]} {
|
|
set mode 1
|
|
}
|
|
switch -- $mode {
|
|
0 - 3 - 4 { # fixed, close, open
|
|
if {$oldmode == $mode} {
|
|
switch -- [hvali /cc/fm] {
|
|
2 - 4 { # closing or closed
|
|
sct update 3
|
|
}
|
|
1 - 3 { # opening or opened
|
|
sct update 4
|
|
}
|
|
default {
|
|
# sct update 0
|
|
}
|
|
}
|
|
}
|
|
logsetup [sct]/set clear
|
|
logsetup [sct]/autoflow/flowtarget clear
|
|
return idle
|
|
}
|
|
1 { # controlled
|
|
set soll [hvali [sct]/set]
|
|
# the following line is for graphic (using flowtarget as nv_set curve)
|
|
hupdate [sct]/autoflow/flowtarget $soll
|
|
}
|
|
2 { # automatic
|
|
set flowmax [hvali [sct]/flowmax]
|
|
if {$flowmax > 20} {
|
|
set flowmax 20
|
|
clientput "WARNING: reduced flowmax to $flowmax ln/min for less stress to the pump"
|
|
hupdate [sct]/flowmax $flowmax
|
|
}
|
|
flow::task /nv/autoflow [hvali [sct]/set] $flowmax
|
|
set soll [hvali [sct]/autoflow/flowset]
|
|
if {[sct soll] != $soll} {
|
|
sct soll $soll
|
|
sct settime [DoubleTime]
|
|
}
|
|
if {[hgetpropval [sct]/autoflow/getTset t_set_undefined]} {
|
|
if {[hvali [sct]/status] ne $umsg} {
|
|
clientput "ERROR: $umsg"
|
|
}
|
|
hupdate [sct]/status $umsg
|
|
}
|
|
}
|
|
}
|
|
if {[hvali [sct]/status] eq $umsg && \
|
|
([sctval [sct]] != 2 || [hgetpropval [sct]/autoflow/getTset t_set_undefined] == 0)} {
|
|
hsetprop [sct]/autoflow/getTset t_set_undefined 0
|
|
hupdate [sct]/status ""
|
|
}
|
|
set regstate [sct regstate]
|
|
set now [DoubleTime]
|
|
if {[hval [sct]/use_pressure]} {
|
|
set ist [hvali [sct]/flowp]
|
|
} else {
|
|
set ist [hvali [sct]/flow]
|
|
}
|
|
set tol [hvali [sct]/ctrl/tol]
|
|
set tolhigh [hvali [sct]/ctrl/tolhigh]
|
|
set closestate 0
|
|
if {[hvali /cc/fm] == 4} {
|
|
# n.v. is closed
|
|
if {$ist < $soll} {
|
|
if {$regstate ne "open"} {
|
|
set closestate 2
|
|
set regstate 0
|
|
}
|
|
} else {
|
|
if {[silent 0 sct release_blocked] && $ist > $soll + $tol} {
|
|
# hack for releasing n.v. at MA7
|
|
setstate closed
|
|
set closecnt [silent 1 sct closecnt]
|
|
incr closecnt
|
|
if {$closecnt > 20} {
|
|
cc mp 0.3
|
|
clientput "open pulse for blocked n.v."
|
|
set closecnt 0
|
|
}
|
|
sct closecnt $closecnt
|
|
}
|
|
return idle
|
|
}
|
|
} elseif {$ist > $soll + 80} {
|
|
# n.v. to be closed
|
|
if {$regstate ne "close" && $regstate ne "open"} {
|
|
set closestate 1
|
|
set regstate 0
|
|
}
|
|
} elseif {[hvali /cc/fm] == 3} {
|
|
# n.v. opened
|
|
if {$soll > $ist} {
|
|
hset [sct]/ctrl/regtext "fully opened"
|
|
return idle
|
|
}
|
|
}
|
|
if {[silent 1 sct closecnt] == 0 && [silent 0 sct release_blocked]} {
|
|
cc mp -0.3
|
|
clientput "close pulse for blocked n.v."
|
|
}
|
|
sct closecnt 1
|
|
if {$tol < 0.01} {
|
|
set tol 0.01
|
|
hupdate [sct]/ctrl/tol $tol
|
|
}
|
|
if {$tolhigh < $tol} {
|
|
set tolhigh $tol
|
|
hupdate [sct]/ctrl/tolhigh $tolhigh
|
|
}
|
|
set f 10.0
|
|
if {$soll > 4} {
|
|
set tol $tolhigh
|
|
set fact $f
|
|
} elseif {$soll > 3} {
|
|
set tol [expr ($soll - 3) * ($tolhigh - $tol) + $tol]
|
|
set fact [expr ($soll - 3.0) * ($f - 1.0) + 1.0]
|
|
} else {
|
|
set fact 1.0
|
|
}
|
|
if {$ist > 4} {
|
|
set fi $f
|
|
} elseif {$ist > 3} {
|
|
set fi [expr ($ist - 3) * ($f - 1.0) + 1.0]
|
|
} else {
|
|
set fi 1.0
|
|
}
|
|
if {[sct dir] > 0} {
|
|
if {$ist > [sct lastist] + 0.1 * $fi} {
|
|
sct hystpulse -1
|
|
} elseif {$ist < [sct lastist]} {
|
|
sct lastist $ist
|
|
}
|
|
} else {
|
|
if {$ist < [sct lastist] - 0.1 * $fi} {
|
|
sct hystpulse 1
|
|
} elseif {$ist > [sct lastist]} {
|
|
sct lastist $ist
|
|
}
|
|
}
|
|
set fact [expr sqrt($fi * $fact)]
|
|
|
|
set dif [expr $soll - $ist]
|
|
if {[sct dir] > 0} {
|
|
set _dir _o
|
|
} else {
|
|
set _dir _c
|
|
}
|
|
set lastim [silent 0 sct lastim]
|
|
set period [sct period]
|
|
switch $regstate {
|
|
close {
|
|
set closestate 0
|
|
if {[hvali /cc/fm] == 2} {
|
|
# still closing
|
|
} elseif {[hvali /cc/fm] != 4} {
|
|
# stopped: reg again?
|
|
setstate reg
|
|
} elseif {$dif < 0} {
|
|
# flow still too high
|
|
if {[hvali /cc/mp] != 0} {
|
|
cc mp 0
|
|
}
|
|
} elseif {[hvali [sct]/ctrl/openpulse] > 0} {
|
|
setstate open
|
|
} else {
|
|
setstate reg
|
|
}
|
|
}
|
|
open {
|
|
set closestate 0
|
|
if {$ist < [sct minflow]} {
|
|
sct minflow $ist
|
|
}
|
|
if {[hvali /cc/fm] == 1} {
|
|
# still opening
|
|
sct lastmov $now
|
|
} else {
|
|
if {$now > [sct lastmov] + $period * 2} {
|
|
set mp [silent [hvali /cc/mo] hvali /cc/mmp]
|
|
if {$mp > 0.21} {
|
|
#clientput "ccu4flow: measured open pulse $mp"
|
|
hupdate [sct]/ctrl/openpulse [expr $mp - 0.2]
|
|
} else {
|
|
#clientput "ccu4flow: open pulse unchanged"
|
|
}
|
|
sct dir -1
|
|
setstate reg
|
|
}
|
|
# stabilize
|
|
}
|
|
}
|
|
within_tolerance {
|
|
if {$dif * [sct dir] < -$tol} {
|
|
setstate reg_hyst
|
|
} elseif {$dif * [sct dir] > $tol} {
|
|
setstate reg
|
|
} elseif {$now > [silent $now sct last_out_of_tol] + 120} {
|
|
set cm [silent 0 sct corr_minpulse]
|
|
if {$cm > 0} {
|
|
#clientput "ccu4flow: save increased minpulse$_dir [sct minpulse]"
|
|
if {[hvali [sct]/ctrl/adjust_minpulse]} {
|
|
hupdate [sct]/ctrl/minpulse$_dir [sct minpulse]
|
|
}
|
|
} elseif {$cm < 0} {
|
|
#clientput "ccu4flow: clear corr_minpulse"
|
|
}
|
|
sct corr_minpulse 0
|
|
}
|
|
}
|
|
reg - reg_hyst - reg_in_tol {
|
|
if {$dif * [sct dir] < -$tol} {
|
|
# force init of reg_hyst state
|
|
sct regstate reg
|
|
setstate reg_hyst
|
|
} elseif {$dif * [sct dir] <= 0 || abs($dif) < $tol * 0.5} {
|
|
setstate within_tolerance
|
|
} elseif {$now < $lastim + $period} {
|
|
# wait
|
|
} else {
|
|
set slope [expr 0.00 + abs($dif) * $period / [hvali [sct]/ctrl/deriv$_dir]]
|
|
set totalmin ""
|
|
set ddif [format %.2f [expr -($dif - [sct olddif]) * [sct dir]]]
|
|
sct filtered_ddif [expr max(0,[silent 0 sct filtered_ddif] * 0.9 + $ddif * 0.1)]
|
|
if {$ddif < 0} {
|
|
set ddif 0
|
|
}
|
|
if {$ddif > 2 * $slope} {
|
|
sct olddif [expr $dif + [sct dir] * $slope]
|
|
#clientput "outof olddif [sct olddif]"
|
|
} else {
|
|
sct olddif [expr [sct olddif] - [sct dir] * $slope]
|
|
}
|
|
set prop [expr [hvali [sct]/ctrl/prop$_dir] / $fact]
|
|
set minpulse [sct minpulse]
|
|
set minpulse_fact [silent 1 sct minpulse_fact]
|
|
if {$minpulse_fact > 1.45} {
|
|
set minpulse_fact 0.6
|
|
}
|
|
set minpulse [expr $minpulse * $minpulse_fact]
|
|
sct minpulse_fact [expr $minpulse_fact + 0.2]
|
|
if {$ddif != 0} {
|
|
#clientput "[expr abs($dif) * $prop] - [expr abs($dif) * $prop * $ddif / $slope] d [expr $period * $dif / $ddif]"
|
|
}
|
|
set mpabs [format %.3f [expr abs($dif) * $prop * (1 - $ddif / $slope) + $minpulse]]
|
|
# hupdate [sct]/span [sct filtered_ddif]
|
|
if {$mpabs < 0} {
|
|
set mpabs 0
|
|
} elseif {$mpabs > 0} {
|
|
if {[sct filtered_ddif] > $slope} {
|
|
set mpabs 0
|
|
}
|
|
}
|
|
# if {[sct dir] > 0 && [sct olddir] <= 0} {
|
|
# }
|
|
set mp [expr $mpabs * [sct dir]]
|
|
set progress [expr [silent 0 sct progress] - 0.01]
|
|
if {$dif * [sct dir] > $progress} {
|
|
set progress [expr $dif * [sct dir]]
|
|
}
|
|
sct progress $progress
|
|
set pstep 0.2
|
|
if {$slope < $pstep} {
|
|
set pstep $slope
|
|
}
|
|
#clientput "ccu4flow: $dif ?< $progress - $pstep"
|
|
if {$dif * [sct dir] < $progress - $pstep} {
|
|
if {$now > [silent 0 sct lastprogress] + 1.5 * $period} {
|
|
#clientput "ccu4flow: progress $progress dif $dif"
|
|
sct progress [expr $dif * [sct dir]]
|
|
# we got over hysteresis
|
|
sct hstat ""
|
|
sct totalmin 0
|
|
sct hystlim 0.3
|
|
if {$regstate eq "reg_hyst"} {
|
|
setstate reg
|
|
}
|
|
} elseif {$regstate eq "reg_hyst"} {
|
|
set mp 0
|
|
}
|
|
} else {
|
|
sct lastprogress $now
|
|
}
|
|
if {[sct hystpulse] eq [sct dir]} {
|
|
if {$regstate eq "reg_hyst"} {
|
|
set hp [hvali [sct]/ctrl/hystpulse$_dir]
|
|
set mp [expr $mp + [sct dir] * $hp]
|
|
}
|
|
sct hystpulse 0
|
|
}
|
|
if {$mp == 0} {
|
|
cc mp 0
|
|
} else {
|
|
if {$ddif < 0} {
|
|
#clientput "worse $dif"
|
|
sct olddif $dif
|
|
}
|
|
if {abs($dif) < $tol} {
|
|
setstate reg_in_tol
|
|
set mp [format %.3f [expr ($minpulse / $tol + $prop) * $dif]]
|
|
if {$now > [silent $now sct last_out_of_tol] + 120} {
|
|
set cm [silent 0 sct corr_minpulse]
|
|
if {$cm > 0} {
|
|
#clientput "ccu4flow: save increased minpulse$_dir [sct minpulse]"
|
|
if {[hvali [sct]/ctrl/adjust_minpulse]} {
|
|
hupdate [sct]/ctrl/minpulse$_dir [sct minpulse]
|
|
}
|
|
} elseif {$cm < 0} {
|
|
#clientput "ccu4flow: clear corr_minpulse $cm"
|
|
}
|
|
sct corr_minpulse 0
|
|
}
|
|
} else {
|
|
sct last_out_of_tol $now
|
|
if {$regstate eq "reg_in_tol"} {
|
|
setstate reg
|
|
}
|
|
# set mpmax [sct dir]
|
|
set totalmin [sct totalmin]
|
|
set hstat [silent "" sct hstat]
|
|
if {abs($mp) > $minpulse} {
|
|
lappend hstat [expr abs($mp)]
|
|
set totalmin [expr $totalmin + abs($mp) - $minpulse]
|
|
if {$totalmin > [sct hystlim]} {
|
|
# set minpulse [format %.3f [expr $minpulse * 1.25 + 0.0003]]
|
|
set minpulse [format %.3f [expr $minpulse + 0.001]]
|
|
sct minpulse $minpulse
|
|
sct corr_minpulse 1
|
|
set h $hstat
|
|
set hstat [list]
|
|
set totalmin 0
|
|
foreach v $h {
|
|
if {$v > $minpulse} {
|
|
set totalmin [expr $totalmin + $v - $minpulse]
|
|
lappend hstat $v
|
|
}
|
|
}
|
|
# clientput "increase minpulse$_dir $minpulse totalmin $totalmin"
|
|
}
|
|
set totalmin [format %.3f $totalmin]
|
|
sct totalmin $totalmin
|
|
sct hstat $hstat
|
|
}
|
|
}
|
|
cc mp $mp
|
|
#logtext mp $mp
|
|
sct olddif $dif
|
|
sct lastpulse $now
|
|
}
|
|
#clientput "mp $mp t $totalmin"
|
|
set lastim $now
|
|
}
|
|
}
|
|
}
|
|
if {$closestate != 0} {
|
|
if {$closestate == 1} {
|
|
setstate close "close / flow too high"
|
|
} elseif {[hvali [sct]/ctrl/openpulse] > 0} {
|
|
setstate open "open / n.v. closed"
|
|
#clientput "[sct regstate] $regstate"
|
|
} else {
|
|
setstate reg
|
|
}
|
|
}
|
|
if {$regstate != [sct regstate]} {
|
|
#clientput "goto $regstate"
|
|
switch $regstate {
|
|
close {
|
|
set mp -[hvali /cc/mot]
|
|
cc mp $mp
|
|
logtext mp $mp
|
|
sct dir -1
|
|
}
|
|
open {
|
|
sct dir 1
|
|
set mft [expr [hvali /cc/f] + 1.0]
|
|
cc mft $mft
|
|
set mp [hvali [sct]/ctrl/openpulse]
|
|
set pulse $mp
|
|
set mw [expr $mp * 0.8]
|
|
if {$mw > 1} {
|
|
set mw 1
|
|
}
|
|
cc mw $mw
|
|
cc mp $mp
|
|
logtext mp $mp mft $mft
|
|
sct lastmov $now
|
|
sct minflow $ist
|
|
}
|
|
reg_hyst - reg {
|
|
if {$regstate eq "reg_hyst"} {
|
|
sct totalmin 0
|
|
sct hystlim [sct maxhysteresis]
|
|
if {$now < [sct settime] + 1} {
|
|
#clientput "ccu4flow: reg_hyst after set"
|
|
} else {
|
|
set corr [silent 0 sct corr_minpulse]
|
|
if {$corr != 0} {
|
|
set minpulse [sct minpulse]
|
|
if {$minpulse > 0 && $corr < 0} {
|
|
set minpulse [format %.3f [expr $minpulse * 0.8 - 0.0004]]
|
|
#clientput "ccu4flow: decrease minpulse$_dir $minpulse"
|
|
} elseif {$corr == 1} {
|
|
#clientput "ccu4flow: save increased minpulse$_dir $minpulse"
|
|
}
|
|
if {[hvali [sct]/ctrl/adjust_minpulse]} {
|
|
hupdate [sct]/ctrl/minpulse$_dir $minpulse
|
|
}
|
|
}
|
|
}
|
|
sct corr_minpulse -1
|
|
# } elseif {[sct regstate] eq "reg_hyst"} {
|
|
# sct hystpulse [expr -[sct dir]]
|
|
# clientput "enable hystpulse [sct hystpulse]"
|
|
# } else {
|
|
# sct hystpulse 0
|
|
}
|
|
if {$dif > 0} {
|
|
sct dir 1
|
|
set _dir _o
|
|
} else {
|
|
sct dir -1
|
|
set _dir _c
|
|
}
|
|
sct minpulse [hvali [sct]/ctrl/minpulse$_dir]
|
|
set lastim $now
|
|
sct hstat ""
|
|
sct lastpulse $now
|
|
sct progress 0
|
|
}
|
|
within_tolerance {
|
|
cc mp 0
|
|
}
|
|
}
|
|
sct regstate $regstate
|
|
}
|
|
sct setchanged 0
|
|
sct lastim [expr int($lastim / $period + 0.5) * $period]
|
|
hdelprop [sct] geterror
|
|
return idle
|
|
}
|