# 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 }