Files
sea/tcl/drivers/n2fill.tcl
2022-08-18 15:04:28 +02:00

228 lines
5.7 KiB
Tcl

namespace eval n2fill {} {
}
proc stdConfig::n2fillCommon {} {
obj N2Fill wr 1 read -int
default -1
prop write n2fill::write
prop read n2fill::handler
prop off n2fill::off
prop on n2fill::on
prop enum initializing=-1
prop label "LN2 filling state"
kids "LN2 fill settings" {
node upper upd
node lower upd
node threshold par 90
node limit par 200
node tmo1 par 300
node tmo2 par 1800
}
}
proc stdConfig::n2fill {} {
if {[silent 0 result n2_new] == 0} {
controller std "" 2 "\r" ";"
prop readfmt "%x+ ;%x+ "
prop resolution 1.0
prop readCmd "a0a1{2}"
prop offCmd "O00"
prop onCmd "O03"
prop pulseCmd "O02"
n2fillCommon
return "LN2 fill prototype with old taskit RS232-ADC (12bit)"
}
controller std "\r" 2
prop readfmt ":0404%4x%4x%*2x"
prop resolution 26.214
prop readCmd ":0400000002.."
if {[result n2_new] == 2} {
prop offCmd ":10000000030600FF00FF0006.."
prop onCmd ":10000000030600FF00FF0005.."
prop pulseCmd ":10000000030600FF00FF0004.."
} else {
prop offCmd ":100000000306000700070000.."
prop onCmd ":100000000306000700070003.."
prop pulseCmd ":100000000306000700070002.."
}
n2fillCommon
return "LN2 fill prototype with taskit RS232-ADC16"
}
proc n2fill::handler {} {
sct send [sct readCmd]
return n2fill::update
}
proc n2fill::convert {sensor raw} {
set millivolt [expr $raw / [sct resolution]]
if {$millivolt < 30} {
hupdate [sct]/status "LN2 sensor unplugged"
hsetprop [sct]/$sensor geterror "LN2 sensor unplugged"
return 0
}
if {$millivolt < 150 || $millivolt > 1500} {
hupdate [sct]/status "illegal LN2 sensor reading: $millivolt mV"
hsetprop [sct]/$sensor geterror "illegal LN2 sensor reading: $millivolt mV"
return 0
}
set t [expr 68 * (5000.0 / $millivolt - 1.0) * 0.25 + 26.8]
hupdate [sct]/$sensor $t
hdelprop [sct]/$sensor geterror
return $t
}
proc n2fill::update {} {
set res [scan "[sct result]|0" "[sct readfmt]|%d" upper lower null]
if {$res != 3} {
error "bad response to '[sct send]': '[sct result]'"
}
set upper [convert upper $upper]
set lower [convert lower $lower]
set lim [hvali [sct]/limit]
set thr [hvali [sct]/threshold]
set state [hvali [sct]]
if {$upper > $lim || $lower > $lim} {
if {$state < 3} {
hupdate [sct]/status "sensor warm"
sct update 4
sct enum fill=3,inactive (sensor warm)=4
return off
} elseif {$state == 4} {
hupdate [sct]/status "sensor warm"
sct update $state
return idle
}
} elseif {[string equal "sensor warm" [result hvali [sct]/status]]} {
hupdate [sct]/status ""
}
if {$upper < $thr && $lower > $thr} {
if {$state < 4} {
hupdate [sct]/status "sensor upside down"
sct update 4
sct enum fill=3,inactive (sensor upside down)=4
return off
} else {
sct update $state
return idle
}
} elseif {[string equal "sensor upside down" [result hvali [sct]/status]]} {
hupdate [sct]/status ""
}
switch -- $state {
-1 { # initializing
sct update 4
sct enum watching=0,fill=1,inactive=4
[sct controllerName] poll [sct] 10
hupdate [sct]/status "automatic LN2 filling off"
return off
}
0 { # watching
if {$lower > $thr} {
clientput "start N2 fill"
sct update 1
sct enum watching=0,fill (starting)=1,inactive=4
sct starttime [clock seconds]
[sct controllerName] poll [sct] 2
return on
}
}
1 { # filling until lower or upper is cold
if {[clock seconds] > [sct starttime] + [hvali [sct]/tmo1]} {
if {$lower < $thr} {
sct update 2
sct enum watching=0,fill=2,inactive=4
return on
}
clientput "stop N2 fill (lower sensor not cold quick enough)"
hupdate [sct]/status "lower sensor not cold quick enough"
sct update 4
sct enum fill=3,inactive (lower sensor not cold quick enough)=4
return off
} else {
if {$upper < $thr} {
clientput "finished N2 fill"
sct update 0
sct enum watching=0,fill=1,inactive=4
return off
}
}
sct update $state
return on
}
2 - 3 { # filling until upper is cold
if {[clock seconds] > [sct starttime] + [hvali [sct]/tmo2]} {
clientput "stop N2 fill (fill timeout)"
hupdate [sct]/status "fill timeout"
sct update 4
sct enum filling=2,inactive (fill timeout)=4
return off
} elseif {$upper < $thr} {
clientput "finished N2 fill"
sct update 0
sct enum watching=0,fill=1,inactive=4
return off
}
sct update $state
return on
}
}
sct update $state
return idle
}
proc n2fill::off {} {
[sct controllerName] poll [sct] 10
sct send [sct offCmd]
return stdSct::complete
}
proc n2fill::on {} {
sct send [sct onCmd]
return n2fill::pulse
}
proc n2fill::pulse {} {
sct send [sct pulseCmd]
return stdSct::complete
}
proc n2fill::write {} {
hupdate [sct]/status ""
switch [sct target] {
# watching
0 {
sct update [sct target]
sct enum watching=0,fill=3,inactive=4
[sct controllerName] poll [sct] 10
return off
}
# inactive
4 {
sct update 4
sct enum watching=0,fill=3,inactive=4
hupdate [sct]/status "automatic LN2 filling off"
return off
}
1 - 2 - 3 {
sct starttime [clock seconds]
[sct controllerName] poll [sct] 2
if {[hvali [sct]] < 3} {
sct update 1
sct enum watching=0,fill=1,inactive=4
} else {
sct update 3
sct enum watching=0,fill=3,inactive=4
}
return read
}
}
return idle
}