diff --git a/tcl/drivers/ccu4flow.tcl b/tcl/drivers/ccu4flow.tcl index 7405c73..56c32ea 100644 --- a/tcl/drivers/ccu4flow.tcl +++ b/tcl/drivers/ccu4flow.tcl @@ -8,7 +8,7 @@ proc stdConfig::ccu4flow {args} { obj ccu4flow wr prop write ccu4flow::setmode - prop read "ccu4flow::read [silent 0 result instconfig sensirion]" + prop read ccu4flow::read prop dir 1 prop enum fixed=0,controlled=1,automatic=2,close=3,open=4 prop filter 0 @@ -28,10 +28,14 @@ proc stdConfig::ccu4flow {args} { 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" { @@ -48,29 +52,35 @@ proc stdConfig::ccu4flow {args} { 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]} @@ -92,11 +102,11 @@ proc stdConfig::ccu4flow {args} { 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} @@ -104,7 +114,7 @@ proc stdConfig::ccu4flow {args} { prop enum 1 prop help {adjust minpulse automatically} } - + node autoflow -none kids "autoflow control parameters" { flow::make ccu4flow::tmts {result tt set/reg} @@ -112,7 +122,7 @@ proc stdConfig::ccu4flow {args} { node calib -none kids calib { node ln_per_min_per_mbar par 0.9 - node mbar_offset par 0.5 + node mbar_offset par 0.8 } } } @@ -158,21 +168,19 @@ proc ccu4flow::check_minpulse {dir} { sct update [sct target] } -proc ccu4flow::read {{sensirion 0}} { +proc ccu4flow::read {} { hsetprop /cc/fa nvpath [sct] _cc updatescript /cc/fa ccu4flow::updatemode hsetprop /cc/f nvpath [sct] - if {$sensirion} { - hsetprop /nvflow flowsource flowmeter + 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 - hsetprop /cc/f flowsource pressref - } else { - hsetprop /cc/f nvctrl [sct controller] - hsetprop /cc/f flowsource flowpress } - _cc updatescript /cc/f ccu4flow::updateflow return unpoll } @@ -220,11 +228,10 @@ proc ccu4flow::updatemode {value} { proc ccu4flow::updateflow {value} { # flowsource: - # pressref: just update nv/flowp - # flowmeter: update nv/flow - # flowpress: flow from pressure + # pressure: this is a pressure + # flow: this is a flow from a flowmeter - set source [silent pressure sct flowsource] + 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 @@ -257,9 +264,9 @@ proc ccu4flow::updateflow {value} { } } sct filtered $flow - if {$source eq "flowmeter"} { + if {$source eq "flow"} { updateval [sct nvpath]/flow $flow - } else { + } elseif {$source eq "pressure"} { if {$flow < -50} { set flow -62.5 } else { @@ -267,12 +274,10 @@ proc ccu4flow::updateflow {value} { set fpm [hval [sct nvpath]/calib/ln_per_min_per_mbar] set flow [expr ($flow - $off) * $fpm] } - if {$source eq "pressref"} { - hupdate [sct nvpath]/flowp $flow - return - } - updateval_e [sct nvpath]/flow $flow -62.5 no_sensor + 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 } @@ -384,7 +389,11 @@ proc ccu4flow::ctrl {} { } set regstate [sct regstate] set now [DoubleTime] - set ist [hvali [sct]/flow] + 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 diff --git a/tcl/drivers/hepump.tcl b/tcl/drivers/hepump.tcl index 5f0a952..fe86974 100644 --- a/tcl/drivers/hepump.tcl +++ b/tcl/drivers/hepump.tcl @@ -160,29 +160,33 @@ proc hepump::set_calib {} { hsetprop /nv off_reason "pump mode changed" sct print "pump mode change: suspend needle valve control for 20 sec." } - return idle + return idle } proc hepump::read {} { - set p [expr [silent 0 result cc f] * [silent 0.6 hvali /nv/calib/ln_per_min_per_mbar]] - set f [silent 0 result nvflow] - if {[hvali [sct]/eco] == 0 && $p > 1 && $f > 0.5 && $f < 25} { - set health [expr 100 * $f / ($p / 1.2 - 0.5)] - set health [expr [silent $health sct health] * 0.95 + 0.05 * $health] - sct health $health - if {abs($health - [silent 0 hval [sct]/health]) > 1} { - sct health_cnt 0 - hupdate [sct]/health [format %.1f $health] - } else { - sct health_cnt [expr [sct health_cnt] + 1] - if {[sct health_cnt] == 10} { - if {$health > 100} {set health 100} - catch {prep0 / pump_health_update [result instrument] [format %.0f $health]} msg - } + set p [silent 0 result nv flowp] + set f [silent 0 result nv flow] + set p_buf [silent 0 sct p_buf] + set f_buf [silent 0 sct f_buf] + lappend p_buf $p + lappend f_buf $f + sct p_buf [lrange $p_buf end-30 end] + sct f_buf [lrange $f_buf end-30 end] + set pmin [tcl::mathfunc::min {*}$p_buf] + set pmax [tcl::mathfunc::max {*}$p_buf] + set fmin [tcl::mathfunc::min {*}$f_buf] + set fmax [tcl::mathfunc::max {*}$f_buf] + if {[silent 0 hval [sct]/eco] == 0 && $pmin >= 1 && $fmin >= 0.5 && $fmin < 25} { + set hmax [expr round(100 * $fmax / ($pmin - 0.4))] + set hmin [expr round(100 * $fmin / ($pmax - 0.4))] + set health [silent 100 hval [sct]/health] + if {$hmax < $health} { + set health $hmax + } elseif {$hmin > $health} { + set health $hmin } - } else { - # reset filter - hdelprop [sct] health + hupdate [sct]/health $health + catch {prep0 / pump_health_update [result instrument] [expr min($health, 100)]} msg } return [hepump::set_calib] } @@ -400,7 +404,9 @@ proc hepump::get_auto {} { if {$auto && $oldeco != 2} { set eco [sctval [sct parent]/eco] set lim [sctval [sct parent]/eco_t_lim 7] - if {[silent 10 hval /tt/target] < $lim && [silent 10 hval /tt] < 2 * $lim} { + if {[silent 0 result nv use_pressure]} { + set ecoset 0 + } elseif {[silent 10 hval /tt/target] < $lim && [silent 10 hval /tt] < 2 * $lim} { set ecoset 0 } elseif {[silent 10 hval /tt/target] > $lim || [silent 10 hval /tt] > 3 * $lim} { set ecoset 1 diff --git a/tcl/drivers/nvstep.tcl b/tcl/drivers/nvstep.tcl index 67541d3..c257f67 100644 --- a/tcl/drivers/nvstep.tcl +++ b/tcl/drivers/nvstep.tcl @@ -1,7 +1,7 @@ namespace eval nvstep { } -proc stdConfig::nvstep {} { +proc stdConfig::nvstep {args} { variable name controller syncedprot @@ -9,7 +9,7 @@ proc stdConfig::nvstep {} { obj NvStep wr prop write nvstep::write - prop read "nvstep::read [silent 0 result instconfig sensirion]" + prop read nvstep::read prop enum fixed=0,controlled=1,automatic=2,close=3,open=4 prop write nvstep::write prop lastpulse 0 @@ -22,6 +22,13 @@ proc stdConfig::nvstep {} { prop maxflow 0 default 0 + set sensirion 0 + foreach arg $args { + if {$arg eq "1"} { + set sensirion 1 + } + } + kids "needle value" { node flow upd @@ -39,6 +46,10 @@ proc stdConfig::nvstep {} { node flowp upd prop help "flow calculated from pressure before pump" + 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 prop par 10 @@ -172,7 +183,11 @@ proc nvstep::poll {} { hupdate [sct]/status $umsg } } - set ist [hvali [sct]/flow] + if {[hval [sct]/use_pressure]} { + set ist [hvali [sct]/flowp] + } else { + set ist [hvali [sct]/flow] + } set tol [hvali [sct]/ctrl/tol] set a [sct amplitude] set t [sct t_after_delay] @@ -270,29 +285,26 @@ proc nvstep::poll {} { return idle } -proc nvstep::read {{sensirion 0}} { +proc nvstep::read {} { hsetprop /cc/fa nvpath [sct] _cc updatescript /cc/fa nvstep::updatemode hsetprop /cc/f nvpath [sct] - if {$sensirion} { - hsetprop /nvflow flowsource flowmeter + hsetprop /cc/f nvctrl [sct controller] + hsetprop /cc/f flowsource pressure + _cc updatescript /cc/f nvstep::updateflow + catch { + hsetprop /nvflow flowsource flow hsetprop /nvflow nvpath [sct] hsetprop /nvflow nvctrl [sct controller] _hemot updatescript /nvflow nvstep::updateflow - hsetprop /cc/f flowsource pressref - } else { - hsetprop /cc/f nvctrl [sct controller] - hsetprop /cc/f flowsource flowpress } - _cc updatescript /cc/f nvstep::updateflow return unpoll } proc nvstep::updateflow {value} { # flowsource: - # pressref: just update nv/flowp - # flowmeter: update nv/flow - # flowpress: flow from pressure + # pressure: this is a pressure + # flow: this is a flow from a flowmeter set source [silent pressure sct flowsource] set filter [lrange "[silent $value sct filter] $value" end-9 10] @@ -317,21 +329,27 @@ proc nvstep::updateflow {value} { } } sct filtered $flow - if {$source eq "flowmeter"} { + if {$source eq "flow"} { + if {$flow < 1} { + # avoid negative flow values, but it smooth] + set flow [expr exp($flow - 1)] + } updateval [sct nvpath]/flow $flow - } else { + } 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] + if {$flow < 1} { + # avoid negative flow values, but keep it smooth] + set flow [expr exp($flow - 1)] + } } - if {$source eq "pressref"} { - hupdate [sct nvpath]/flowp $flow - return - } - updateval_e [sct nvpath]/flow $flow -62.5 no_sensor + updateval_e [sct nvpath]/flowp $flow -62.5 no_sensor + } else { + error "[sct] illegal flowsource: $source" } [sct nvctrl] queue [sct nvpath] read nvstep::poll } diff --git a/tcl/drivers/sensirion.tcl b/tcl/drivers/sensirion.tcl index 3806849..6e8438e 100644 --- a/tcl/drivers/sensirion.tcl +++ b/tcl/drivers/sensirion.tcl @@ -61,11 +61,11 @@ proc stdConfig::sensirion {} { proc sensirion::updateFlow {} { lassign [sct result] flow stddev - if {$flow == 0 && $stddev == 0} { - if {[hgetpropval /nvflow flowsource] eq "flowmeter"} { - hsetprop /nvflow flowsource flowpress - hepump eco 0 - error "invalid flow -> switched to pressure" + if {$flow == 0 && $stddev == 0 || [silent 0 sct simerror]} { + set use_pressure [silent 0 hval /nv/use_pressure] + if {! $use_pressure} { + hset /nv/use_pressure 1 + clientput "ERROR: invalid flow -> switched to pressure" } } sct update $flow diff --git a/tcl/startup/ccu4make.tcl b/tcl/startup/ccu4make.tcl index 2143b2a..1a12085 100644 --- a/tcl/startup/ccu4make.tcl +++ b/tcl/startup/ccu4make.tcl @@ -20,13 +20,14 @@ proc makeCCU4 {args} { set badargs [list] set cfgdev "0" set hepump 0 + set sensirion [silent 0 result instconfig sensirion] foreach arg $args { switch $arg { nv - nv_release_blocked { if {$arg eq "nv_release_blocked"} { - makenv nv -driver ccu4flow release_blocked + makenv nv -driver ccu4flow release_blocked $sensirion } else { - makenv nv -driver ccu4flow + makenv nv -driver ccu4flow $sensirion } # GraphAdd cc.f mbar nv_flow red GraphAdd nv.flow ln/min nv_flow magenta @@ -117,6 +118,7 @@ proc makeCCU4 {args} { } if {$hepump} { makeHePump + hsetprop /nv hepump /hepump } set cfg [ccu4_get_device_config $cfgdev codesfile] if {$cfg eq "" || [llength $badargs] > 0} {