catch the case when sensirion is not working

- add use_pressure to nv control for selecting whether nv control
  is using the flow from the sensirion sensor or the pump pressure
- this is triggered when sensirion is reading 0 (incl. stddev)
This commit is contained in:
l_samenv
2023-09-28 14:42:46 +02:00
parent 882c55e95a
commit 2c13e9b091
5 changed files with 113 additions and 78 deletions

View File

@ -8,7 +8,7 @@ proc stdConfig::ccu4flow {args} {
obj ccu4flow wr obj ccu4flow wr
prop write ccu4flow::setmode prop write ccu4flow::setmode
prop read "ccu4flow::read [silent 0 result instconfig sensirion]" prop read ccu4flow::read
prop dir 1 prop dir 1
prop enum fixed=0,controlled=1,automatic=2,close=3,open=4 prop enum fixed=0,controlled=1,automatic=2,close=3,open=4
prop filter 0 prop filter 0
@ -28,10 +28,14 @@ proc stdConfig::ccu4flow {args} {
prop lastmov 0 prop lastmov 0
prop hystpulse 0 prop hystpulse 0
prop lastist 0 prop lastist 0
set sensirion 0
foreach arg $args { foreach arg $args {
if {$arg eq "release_blocked"} { if {$arg eq "release_blocked"} {
prop release_blocked 1 prop release_blocked 1
} }
if {$arg eq "1"} {
set sensirion 1
}
} }
default 0 default 0
kids "needle valve" { kids "needle valve" {
@ -48,29 +52,35 @@ proc stdConfig::ccu4flow {args} {
node flowmax par 20 node flowmax par 20
prop label "flow maximum" prop label "flow maximum"
node flowp upd node flowp upd
prop help "flow calculated from pressure before pump"
node span upd 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 node ctrl -none
kids "control parameters" { kids "control parameters" {
node regtext upd -text node regtext upd -text
default regulate default regulate
prop label status prop label status
prop width 40 prop width 40
node prop_o par 0.05 node prop_o par 0.05
prop help {prop [sec/mbar] when opening. above 4 mbar a 10 times lower value is used} prop help {prop [sec/mbar] when opening. above 4 mbar a 10 times lower value is used}
node prop_c par 0.03 node prop_c par 0.03
prop help {prop [sec/mbar] when closing. above 4 mbar a 10 times lower value is used} prop help {prop [sec/mbar] when closing. above 4 mbar a 10 times lower value is used}
node deriv_o par 30 node deriv_o par 30
prop help {convergence target time [sec] when opening} prop help {convergence target time [sec] when opening}
node deriv_c par 30 node deriv_c par 30
prop help {convergence target time [sec] when closing} prop help {convergence target time [sec] when closing}
node minpulse_o out node minpulse_o out
default 0.05 default 0.05
prop help {minimum close pulse [sec]} prop help {minimum close pulse [sec]}
@ -92,11 +102,11 @@ proc stdConfig::ccu4flow {args} {
node tol par 0.25 node tol par 0.25
prop label tolerance prop label tolerance
prop help {valid below 3 mbar} prop help {valid below 3 mbar}
node tolhigh par 0.5 node tolhigh par 0.5
prop label tol. above 4 prop label tol. above 4
prop help {valid above 4 mbar} prop help {valid above 4 mbar}
node openpulse par 60 node openpulse par 60
prop help {time to open from completely closed to a significant opening} prop help {time to open from completely closed to a significant opening}
@ -104,7 +114,7 @@ proc stdConfig::ccu4flow {args} {
prop enum 1 prop enum 1
prop help {adjust minpulse automatically} prop help {adjust minpulse automatically}
} }
node autoflow -none node autoflow -none
kids "autoflow control parameters" { kids "autoflow control parameters" {
flow::make ccu4flow::tmts {result tt set/reg} flow::make ccu4flow::tmts {result tt set/reg}
@ -112,7 +122,7 @@ proc stdConfig::ccu4flow {args} {
node calib -none node calib -none
kids calib { kids calib {
node ln_per_min_per_mbar par 0.9 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] sct update [sct target]
} }
proc ccu4flow::read {{sensirion 0}} { proc ccu4flow::read {} {
hsetprop /cc/fa nvpath [sct] hsetprop /cc/fa nvpath [sct]
_cc updatescript /cc/fa ccu4flow::updatemode _cc updatescript /cc/fa ccu4flow::updatemode
hsetprop /cc/f nvpath [sct] hsetprop /cc/f nvpath [sct]
if {$sensirion} { hsetprop /cc/f nvctrl [sct controller]
hsetprop /nvflow flowsource flowmeter hsetprop /cc/f flowsource pressure
_cc updatescript /cc/f ccu4flow::updateflow
catch {
hsetprop /nvflow flowsource flow
hsetprop /nvflow nvpath [sct] hsetprop /nvflow nvpath [sct]
hsetprop /nvflow nvctrl [sct controller] hsetprop /nvflow nvctrl [sct controller]
_hemot updatescript /nvflow ccu4flow::updateflow _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 return unpoll
} }
@ -220,11 +228,10 @@ proc ccu4flow::updatemode {value} {
proc ccu4flow::updateflow {value} { proc ccu4flow::updateflow {value} {
# flowsource: # flowsource:
# pressref: just update nv/flowp # pressure: this is a pressure
# flowmeter: update nv/flow # flow: this is a flow from a flowmeter
# flowpress: flow from pressure
set source [silent pressure sct flowsource] set source [silent none sct flowsource]
set n [silent 9 sct filter_n] set n [silent 9 sct filter_n]
set filter [lrange "[silent $value sct filter] $value" end-$n end] set filter [lrange "[silent $value sct filter] $value" end-$n end]
sct filter $filter sct filter $filter
@ -257,9 +264,9 @@ proc ccu4flow::updateflow {value} {
} }
} }
sct filtered $flow sct filtered $flow
if {$source eq "flowmeter"} { if {$source eq "flow"} {
updateval [sct nvpath]/flow $flow updateval [sct nvpath]/flow $flow
} else { } elseif {$source eq "pressure"} {
if {$flow < -50} { if {$flow < -50} {
set flow -62.5 set flow -62.5
} else { } else {
@ -267,12 +274,10 @@ proc ccu4flow::updateflow {value} {
set fpm [hval [sct nvpath]/calib/ln_per_min_per_mbar] set fpm [hval [sct nvpath]/calib/ln_per_min_per_mbar]
set flow [expr ($flow - $off) * $fpm] set flow [expr ($flow - $off) * $fpm]
} }
if {$source eq "pressref"} { updateval_e [sct nvpath]/flowp $flow -62.5 no_sensor
hupdate [sct nvpath]/flowp $flow
return
}
updateval_e [sct nvpath]/flow $flow -62.5 no_sensor
hupdate [sct nvpath]/span $span hupdate [sct nvpath]/span $span
} else {
error "[sct] illegal flowsource: $source"
} }
[sct nvctrl] queue [sct nvpath] read ccu4flow::ctrl [sct nvctrl] queue [sct nvpath] read ccu4flow::ctrl
} }
@ -384,7 +389,11 @@ proc ccu4flow::ctrl {} {
} }
set regstate [sct regstate] set regstate [sct regstate]
set now [DoubleTime] 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 tol [hvali [sct]/ctrl/tol]
set tolhigh [hvali [sct]/ctrl/tolhigh] set tolhigh [hvali [sct]/ctrl/tolhigh]
set closestate 0 set closestate 0

View File

@ -160,29 +160,33 @@ proc hepump::set_calib {} {
hsetprop /nv off_reason "pump mode changed" hsetprop /nv off_reason "pump mode changed"
sct print "pump mode change: suspend needle valve control for 20 sec." sct print "pump mode change: suspend needle valve control for 20 sec."
} }
return idle return idle
} }
proc hepump::read {} { proc hepump::read {} {
set p [expr [silent 0 result cc f] * [silent 0.6 hvali /nv/calib/ln_per_min_per_mbar]] set p [silent 0 result nv flowp]
set f [silent 0 result nvflow] set f [silent 0 result nv flow]
if {[hvali [sct]/eco] == 0 && $p > 1 && $f > 0.5 && $f < 25} { set p_buf [silent 0 sct p_buf]
set health [expr 100 * $f / ($p / 1.2 - 0.5)] set f_buf [silent 0 sct f_buf]
set health [expr [silent $health sct health] * 0.95 + 0.05 * $health] lappend p_buf $p
sct health $health lappend f_buf $f
if {abs($health - [silent 0 hval [sct]/health]) > 1} { sct p_buf [lrange $p_buf end-30 end]
sct health_cnt 0 sct f_buf [lrange $f_buf end-30 end]
hupdate [sct]/health [format %.1f $health] set pmin [tcl::mathfunc::min {*}$p_buf]
} else { set pmax [tcl::mathfunc::max {*}$p_buf]
sct health_cnt [expr [sct health_cnt] + 1] set fmin [tcl::mathfunc::min {*}$f_buf]
if {[sct health_cnt] == 10} { set fmax [tcl::mathfunc::max {*}$f_buf]
if {$health > 100} {set health 100} if {[silent 0 hval [sct]/eco] == 0 && $pmin >= 1 && $fmin >= 0.5 && $fmin < 25} {
catch {prep0 / pump_health_update [result instrument] [format %.0f $health]} msg 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 { hupdate [sct]/health $health
# reset filter catch {prep0 / pump_health_update [result instrument] [expr min($health, 100)]} msg
hdelprop [sct] health
} }
return [hepump::set_calib] return [hepump::set_calib]
} }
@ -400,7 +404,9 @@ proc hepump::get_auto {} {
if {$auto && $oldeco != 2} { if {$auto && $oldeco != 2} {
set eco [sctval [sct parent]/eco] set eco [sctval [sct parent]/eco]
set lim [sctval [sct parent]/eco_t_lim 7] 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 set ecoset 0
} elseif {[silent 10 hval /tt/target] > $lim || [silent 10 hval /tt] > 3 * $lim} { } elseif {[silent 10 hval /tt/target] > $lim || [silent 10 hval /tt] > 3 * $lim} {
set ecoset 1 set ecoset 1

View File

@ -1,7 +1,7 @@
namespace eval nvstep { namespace eval nvstep {
} }
proc stdConfig::nvstep {} { proc stdConfig::nvstep {args} {
variable name variable name
controller syncedprot controller syncedprot
@ -9,7 +9,7 @@ proc stdConfig::nvstep {} {
obj NvStep wr obj NvStep wr
prop write nvstep::write 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 enum fixed=0,controlled=1,automatic=2,close=3,open=4
prop write nvstep::write prop write nvstep::write
prop lastpulse 0 prop lastpulse 0
@ -22,6 +22,13 @@ proc stdConfig::nvstep {} {
prop maxflow 0 prop maxflow 0
default 0 default 0
set sensirion 0
foreach arg $args {
if {$arg eq "1"} {
set sensirion 1
}
}
kids "needle value" { kids "needle value" {
node flow upd node flow upd
@ -39,6 +46,10 @@ proc stdConfig::nvstep {} {
node flowp upd node flowp upd
prop help "flow calculated from pressure before pump" 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 node ctrl -none
kids "control parameters" { kids "control parameters" {
node prop par 10 node prop par 10
@ -172,7 +183,11 @@ proc nvstep::poll {} {
hupdate [sct]/status $umsg 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 tol [hvali [sct]/ctrl/tol]
set a [sct amplitude] set a [sct amplitude]
set t [sct t_after_delay] set t [sct t_after_delay]
@ -270,29 +285,26 @@ proc nvstep::poll {} {
return idle return idle
} }
proc nvstep::read {{sensirion 0}} { proc nvstep::read {} {
hsetprop /cc/fa nvpath [sct] hsetprop /cc/fa nvpath [sct]
_cc updatescript /cc/fa nvstep::updatemode _cc updatescript /cc/fa nvstep::updatemode
hsetprop /cc/f nvpath [sct] hsetprop /cc/f nvpath [sct]
if {$sensirion} { hsetprop /cc/f nvctrl [sct controller]
hsetprop /nvflow flowsource flowmeter hsetprop /cc/f flowsource pressure
_cc updatescript /cc/f nvstep::updateflow
catch {
hsetprop /nvflow flowsource flow
hsetprop /nvflow nvpath [sct] hsetprop /nvflow nvpath [sct]
hsetprop /nvflow nvctrl [sct controller] hsetprop /nvflow nvctrl [sct controller]
_hemot updatescript /nvflow nvstep::updateflow _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 return unpoll
} }
proc nvstep::updateflow {value} { proc nvstep::updateflow {value} {
# flowsource: # flowsource:
# pressref: just update nv/flowp # pressure: this is a pressure
# flowmeter: update nv/flow # flow: this is a flow from a flowmeter
# flowpress: flow from pressure
set source [silent pressure sct flowsource] set source [silent pressure sct flowsource]
set filter [lrange "[silent $value sct filter] $value" end-9 10] set filter [lrange "[silent $value sct filter] $value" end-9 10]
@ -317,21 +329,27 @@ proc nvstep::updateflow {value} {
} }
} }
sct filtered $flow 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 updateval [sct nvpath]/flow $flow
} else { } elseif {$source eq "pressure" {
if {$flow < -50} { if {$flow < -50} {
set flow -62.5 set flow -62.5
} else { } else {
set off [hval [sct nvpath]/calib/mbar_offset] set off [hval [sct nvpath]/calib/mbar_offset]
set fpm [hval [sct nvpath]/calib/ln_per_min_per_mbar] set fpm [hval [sct nvpath]/calib/ln_per_min_per_mbar]
set flow [expr ($flow - $off) * $fpm] 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"} { updateval_e [sct nvpath]/flowp $flow -62.5 no_sensor
hupdate [sct nvpath]/flowp $flow } else {
return error "[sct] illegal flowsource: $source"
}
updateval_e [sct nvpath]/flow $flow -62.5 no_sensor
} }
[sct nvctrl] queue [sct nvpath] read nvstep::poll [sct nvctrl] queue [sct nvpath] read nvstep::poll
} }

View File

@ -61,11 +61,11 @@ proc stdConfig::sensirion {} {
proc sensirion::updateFlow {} { proc sensirion::updateFlow {} {
lassign [sct result] flow stddev lassign [sct result] flow stddev
if {$flow == 0 && $stddev == 0} { if {$flow == 0 && $stddev == 0 || [silent 0 sct simerror]} {
if {[hgetpropval /nvflow flowsource] eq "flowmeter"} { set use_pressure [silent 0 hval /nv/use_pressure]
hsetprop /nvflow flowsource flowpress if {! $use_pressure} {
hepump eco 0 hset /nv/use_pressure 1
error "invalid flow -> switched to pressure" clientput "ERROR: invalid flow -> switched to pressure"
} }
} }
sct update $flow sct update $flow

View File

@ -20,13 +20,14 @@ proc makeCCU4 {args} {
set badargs [list] set badargs [list]
set cfgdev "0" set cfgdev "0"
set hepump 0 set hepump 0
set sensirion [silent 0 result instconfig sensirion]
foreach arg $args { foreach arg $args {
switch $arg { switch $arg {
nv - nv_release_blocked { nv - nv_release_blocked {
if {$arg eq "nv_release_blocked"} { if {$arg eq "nv_release_blocked"} {
makenv nv -driver ccu4flow release_blocked makenv nv -driver ccu4flow release_blocked $sensirion
} else { } else {
makenv nv -driver ccu4flow makenv nv -driver ccu4flow $sensirion
} }
# GraphAdd cc.f mbar nv_flow red # GraphAdd cc.f mbar nv_flow red
GraphAdd nv.flow ln/min nv_flow magenta GraphAdd nv.flow ln/min nv_flow magenta
@ -117,6 +118,7 @@ proc makeCCU4 {args} {
} }
if {$hepump} { if {$hepump} {
makeHePump makeHePump
hsetprop /nv hepump /hepump
} }
set cfg [ccu4_get_device_config $cfgdev codesfile] set cfg [ccu4_get_device_config $cfgdev codesfile]
if {$cfg eq "" || [llength $badargs] > 0} { if {$cfg eq "" || [llength $badargs] > 0} {