214 lines
5.4 KiB
Tcl
214 lines
5.4 KiB
Tcl
# version for cryotel at boa (it is to be verified if FOCUS cryotel is different!)
|
|
|
|
namespace eval cryotelboa {} {
|
|
}
|
|
|
|
proc stdConfig::cryotelboa {} {
|
|
# controler uses std with send terminator "\r"
|
|
# 5sec comm.interval, receive terminator "\n"
|
|
# and multi line replies will be separated by ","
|
|
controller std "\r" 5 "\n" ","
|
|
# the {2} in addition to the command defines the number of expected return values
|
|
prop startcmd "SERIAL{2}"
|
|
|
|
# driver for Sunpower stirling cooler CryoTel
|
|
# serial interface is set to:
|
|
# Char Size/Stop Bits: 8/1 Input Speed: 4800
|
|
# Flow Ctrl: None Output Speed: 4800
|
|
# Parity: None Modem Control: None
|
|
|
|
|
|
obj cryo rd 0.5
|
|
prop label Temperature
|
|
prop update cryotelboa::updatemean
|
|
prop readcmd "TC{2}"
|
|
prop readfmt "TC ,%f"
|
|
|
|
kids cryotel {
|
|
|
|
node cool wr
|
|
prop label Cool
|
|
prop enum 1
|
|
prop read cryotelboa::readcool
|
|
prop write cryotelboa::writecool
|
|
|
|
node control wr
|
|
default 1
|
|
prop check cryotelboa::checkcontrol
|
|
prop enum auto_power=1,manual_power=0,controlled_T=2
|
|
prop help "recommended mode: auto_power, use coolpower or holdpower depending on T"
|
|
prop update cryotelboa::updatecontrol
|
|
prop writecmd "SET PID=%.2f"
|
|
prop readcmd "SET PID{2}"
|
|
prop readfmt "SET PID ,%f"
|
|
|
|
node set wr
|
|
prop label Setpoint
|
|
prop check cryotelboa::checkset
|
|
prop writecmd "SET TTARGET=%.2f"
|
|
prop readcmd "SET TTARGET{2}"
|
|
prop readfmt "SET TTARGET ,%f"
|
|
|
|
node setpower wr
|
|
prop check cryotelboa::checksetpower
|
|
prop writecmd "SET PWOUT=%.2f"
|
|
prop readcmd "SET PWOUT{2}"
|
|
prop readfmt "SET PWOUT ,%f"
|
|
|
|
node coolpower par 240
|
|
|
|
node holdpower par 120
|
|
|
|
node cool_threshold par 100
|
|
prop help "switch to coolpower above this value"
|
|
|
|
node hold_threshold par 95
|
|
prop help "switch to holdpower below this value"
|
|
|
|
node power rd
|
|
prop label Power
|
|
prop readcmd "P{2}"
|
|
prop readfmt "P ,%f"
|
|
|
|
node filter -none
|
|
|
|
kids filter {
|
|
# on jittery system:
|
|
# period was 180, amplitute 3, precision 0.1
|
|
node period par 10
|
|
prop help "oszillation period / sec"
|
|
|
|
node amplitude par 0.1
|
|
prop help "oszillation amplitude / K (+/-)"
|
|
|
|
node precision par 0.01
|
|
|
|
node raw upd
|
|
|
|
node intdif upd
|
|
}
|
|
}
|
|
}
|
|
|
|
proc cryotelboa::updatemean {} {
|
|
set value [stdSct::scanresult]
|
|
set cnt [silent -1 sct cnt]
|
|
if {$cnt < 0} {
|
|
sct update $value
|
|
updateval [sct]/filter/raw $value
|
|
sct cnt 0
|
|
return idle
|
|
}
|
|
incr cnt
|
|
sct sum [expr [silent 0 sct sum] + $value]
|
|
if {$cnt < 10} {
|
|
sct cnt $cnt
|
|
} else {
|
|
set raw [expr [sct sum] / $cnt]
|
|
set filtered [hvali [sct]]
|
|
sct cnt 0
|
|
sct sum 0
|
|
updateval [sct]/filter/raw $raw
|
|
|
|
# intdif is accumulating the difference raw - filtered
|
|
# filtered is corrected by +precision or -precision if abs(intdif) is over lim
|
|
set per [hval [sct]/filter/period]
|
|
set lim [expr 0.5 * [hval [sct]/filter/amplitude]]
|
|
set prec [hval [sct]/filter/precision]
|
|
# 20 = 4 * pollperiod * cnt
|
|
set damp [expr exp(-20 * $prec / $lim / $per)]
|
|
# 10 = cnt * pollperiod * 2
|
|
set intdif [expr ([hvali [sct]/filter/intdif] + ($raw - $filtered) * 10 / $per) * $damp]
|
|
if {$intdif > $lim} {
|
|
set filtered [expr (round(($filtered + $intdif - $lim)/ $prec + 1)) * $prec]
|
|
set intdif [expr $lim - $prec * 2]
|
|
} elseif {$intdif < -$lim} {
|
|
set filtered [expr (round(($filtered + $intdif + $lim)/ $prec - 1)) * $prec]
|
|
set intdif [expr -$lim + $prec * 2]
|
|
}
|
|
updateval [sct]/filter/intdif $intdif
|
|
sct update [format %.5g $filtered]
|
|
if {[hval [sct]/control] == 1} {
|
|
if {$filtered > [hval [sct]/cool_threshold] - 0.01} {
|
|
hset [sct]/setpower [hval [sct]/coolpower]
|
|
} elseif {$filtered < [hval [sct]/hold_threshold] + 0.01} {
|
|
hset [sct]/setpower [hval [sct]/holdpower]
|
|
}
|
|
}
|
|
}
|
|
return idle
|
|
}
|
|
|
|
proc cryotelboa::checkset {} {
|
|
if {[hvali [sct parent]/control] == 0} {
|
|
sct print "setpoint is effective only in controlled_T mode"
|
|
}
|
|
}
|
|
|
|
proc cryotelboa::checksetpower {} {
|
|
if {[hvali [sct parent]/control] == 2} {
|
|
sct print "setpower is effective only in manual_power mode"
|
|
}
|
|
if {[sct target] == [hvali [sct]]} {
|
|
sct write stdSct::complete
|
|
} else {
|
|
sct write stdSct::write
|
|
}
|
|
}
|
|
|
|
proc cryotelboa::visibility {mode} {
|
|
set showlist {
|
|
0 setpower
|
|
1 {coolpower holdpower cool_threshold hold_threshold}
|
|
2 set
|
|
}
|
|
foreach {m vars} $showlist {
|
|
if {$m == $mode} {
|
|
set visible true
|
|
} else {
|
|
set visible false
|
|
}
|
|
foreach var $vars {
|
|
hsetprop [sct parent]/$var visible $visible
|
|
}
|
|
}
|
|
}
|
|
|
|
proc cryotelboa::updatecontrol {} {
|
|
set value [stdSct::scanresult]
|
|
if {$value == 0 && [sctval [sct]] == 1} {
|
|
set value 1
|
|
}
|
|
sct update $value
|
|
visibility $value
|
|
return idle
|
|
}
|
|
|
|
proc cryotelboa::checkcontrol {} {
|
|
visibility [sct target]
|
|
if {[sct target] == 1} {
|
|
sct write stdSct::completeUpdate
|
|
} else {
|
|
sct write stdSct::write
|
|
}
|
|
}
|
|
|
|
proc cryotelboa::writecool {} {
|
|
set flag [expr ! [sct target]]
|
|
sct send "SET SSTOP=$flag"
|
|
sct update [sct target]
|
|
return stdSct::complete
|
|
}
|
|
|
|
proc cryotelboa::readcool {} {
|
|
sct send "SET SSTOP{2}"
|
|
return cryotelboa::updatecool
|
|
}
|
|
|
|
proc cryotelboa::updatecool {} {
|
|
lassign [split [sct result] ,] _ value
|
|
sct update [expr $value == 0]
|
|
return idle
|
|
}
|
|
|