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 }