180 lines
4.7 KiB
Tcl
180 lines
4.7 KiB
Tcl
# new version modified Aug 2018.
|
|
#
|
|
# for next cooldown:
|
|
# - test offset feature (this is something like integral part in PI control)
|
|
# - reg is max(MagTop - 100, target)
|
|
|
|
proc makeN2cool {{temp "tcoil ta"} {topTemp "tcoil tc"}} {
|
|
makeobject n2coolPar array logged
|
|
n2coolPar makeitem temp $temp
|
|
n2coolPar makeitem topTemp $topTemp
|
|
n2coolPar makeitem state inactive
|
|
n2coolPar makeitem istate 0
|
|
|
|
# date and hour when to finish (set to tomorrow at start)
|
|
n2coolPar makeitem day [clock format [expr [clock seconds] + 24*3600] -format %d]
|
|
n2coolPar makeitem time 6
|
|
n2coolPar makeitem last 0
|
|
n2coolPar makeitem target 85
|
|
|
|
n2coolPar makeitem interval 600
|
|
n2coolPar makeitem maxDif 100
|
|
# filtered temperature
|
|
n2coolPar makeitem tfil 0
|
|
# regulation temperature
|
|
n2coolPar makeitem reg 0
|
|
n2coolPar makeitem offset 0
|
|
n2coolPar makeitem prop 3
|
|
|
|
obj_list makeitem n2coolPar "LN2 cooldown parameters"
|
|
Layout n2cool
|
|
|
|
makenv n2valve n2cool_ccu -controller _lnv -port ma15-ts:3004
|
|
}
|
|
|
|
proc n2coolLayout args {
|
|
RadioGroup n2cool [result n2coolPar state]
|
|
Label "LN2 cooldown (plug valve to CCU on MA15 rack)"
|
|
NoNewline
|
|
RadioButton inactive
|
|
NoNewline
|
|
RadioButton start
|
|
Newline
|
|
RadioButton opened
|
|
NoNewline
|
|
RadioButton closed
|
|
Newline
|
|
Tip "Name of bottom coil sensor temperature (MagBot)"
|
|
Input "coil sensor" "n2coolPar temp"
|
|
Tip "Name of top coil sensor temperature (MagTop)"
|
|
Input "coil sensor" "n2coolPar topTemp"
|
|
Input "coil sensor target" "n2coolPar target"
|
|
Newline
|
|
Tip "finish day \[day of month\]"
|
|
Input "finish day" "n2coolPar day"
|
|
Tip "finish hour \[decimal fractions possible\]"
|
|
Input "finish hour" "n2coolPar time"
|
|
Newline
|
|
Tip "max. difference MagTop - MagBot"
|
|
Input "max dif" "n2coolPar maxDif"
|
|
Tip "regulation interval"
|
|
Input "interval" "n2coolPar interval"
|
|
Tip "Kelvin / min."
|
|
Input "prop" "n2coolPar prop"
|
|
Input "T_reg" "n2coolPar reg"
|
|
Input "T_offset" "n2coolPar offset"
|
|
}
|
|
|
|
#
|
|
# Automatic N2 Precooling for Cryomagnets (tested for MA15 only)
|
|
#
|
|
#Typical usage:
|
|
# sicscron 1 n2cool
|
|
#
|
|
# the temperature of MagBot is regulated at the maximum of MagTop - maxDif and
|
|
# target
|
|
# Every 10 minutes (interval) the valve is opened and closed again
|
|
# it is closed again after a time proportional to the the difference between
|
|
# T_filtered and T_reg - offset. This time is calculated live from T_filtered.
|
|
# The valve is then kept closed until the next 10 min interval.
|
|
#
|
|
proc n2cool {{arg none}} {
|
|
switch $arg {
|
|
start {
|
|
if {[result n2coolPar istate] != 0} {
|
|
error "started already"
|
|
}
|
|
n2coolPar state start
|
|
n2coolPar day [clock format [expr [clock seconds] + 24*3600] -format %d]
|
|
n2coolPar last 0
|
|
sicscron 1 n2cool
|
|
return
|
|
}
|
|
inactive {
|
|
clientput "close and finish"
|
|
n2coolPar state inactive
|
|
n2valve 2
|
|
n2coolPar istate 0
|
|
return
|
|
}
|
|
none { }
|
|
default {
|
|
clientput "ERROR: n2cool $arg not allowed"
|
|
error stop
|
|
return
|
|
}
|
|
}
|
|
|
|
if {[result n2coolPar state] eq "inactive"} {
|
|
error stop
|
|
}
|
|
set now [clock seconds]
|
|
|
|
set today [clock format $now -format %d]
|
|
set seconds [expr $now - [clock scan 00:00]]
|
|
if {$today == [result n2coolPar day] && $seconds/3600.0 > [result n2coolPar time]} {
|
|
n2coolPar state inactive
|
|
n2valve 2
|
|
n2coolPar istate 0
|
|
clientput "finished at [clock format $now]"
|
|
error stop
|
|
}
|
|
|
|
set state [result n2coolPar state]
|
|
set oldState $state
|
|
set t [result [result n2coolPar temp]]
|
|
set ttop [result [result n2coolPar topTemp]]
|
|
set last [result n2coolPar last]
|
|
|
|
set offset [result n2coolPar offset]
|
|
set tfil [result n2coolPar tfil]
|
|
set interval [result n2coolPar interval]
|
|
set target [result n2coolPar target]
|
|
set maxDif [result n2coolPar maxDif]
|
|
set reg [format %.1f [expr max($ttop - $maxDif, $target)]]
|
|
n2coolPar reg $reg
|
|
set prop [result n2coolPar prop]
|
|
if {$tfil == 0} {
|
|
n2coolPar tfil $t
|
|
} else {
|
|
set w [expr 2.0 / $interval]
|
|
set tfil [expr $tfil + ($t - $tfil) * $w]
|
|
n2coolPar tfil $tfil
|
|
if {$now > $last + $interval} {
|
|
n2coolPar last $now
|
|
if {$tfil > $reg - $offset} {
|
|
n2valve 1
|
|
n2coolPar state opened
|
|
clientput open
|
|
} else {
|
|
n2valve 0
|
|
n2coolPar state closed
|
|
}
|
|
} elseif {$tfil < $reg + double($now - $last) / 60.0 * $prop - $offset} {
|
|
if {[sctval /n2valve] != 0} {
|
|
n2coolPar offset [expr 0.5 * ($offset + $tfil - $reg)]
|
|
clientput close
|
|
n2valve 0
|
|
n2coolPar state closed
|
|
}
|
|
}
|
|
}
|
|
switch [result n2coolPar state] {
|
|
opened {
|
|
n2valve 1
|
|
n2coolPar istate 1
|
|
}
|
|
closed - closedFast {
|
|
n2coolPar istate 2
|
|
}
|
|
inactive {
|
|
n2coolPar istate 0
|
|
clientput "n2cool deactivated"
|
|
error stop
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
publishLazy n2cool
|