# 17tf 17 Tesla magnet of ted forgan & co. namespace eval 17tf { } proc stdConfig::17tf {} { variable name if {[controller std "\n" 10 "\n"]} { controllerDesc "17tf controller" prop write 17tf::write } pollperiod 5 5 obj 17tf wr -drive prop read 17tf::read prop write 17tf::writemf prop checklimits 17tf::checklimits prop halt 17tf::halt prop status idle prop label "set field" kids "17tf parameters" { # node setfield out # prop newline 1 node target upd node output upd node voltage upd node heater upd node setrate out prop newline 1 node ramprate upd node abort out prop newline 1 prop enum 1 default 0 prop write 17tf::abort node setunits out prop label setunits prop enum A/s,T/min,T/hour prop lineend 0 node units upd node persistent upd node psustatus -text upd prop newline 1 node setpause -text out prop label setpause prop enum ON=ON,OFF=OFF prop lineend 0 node pausestatus -text upd node ignoretbl -text out prop label ignoretbl prop enum ON=ON,OFF=OFF prop lineend 0 node tblstatus -text upd node ready -text upd node setpersmode -text out prop write 17tf::writepersmode prop label setpersmode prop enum ON=ON,OFF=OFF prop lineend 0 default "" node persmode -text upd node persistmode -text upd node sensA upd node sensB upd node set1 out prop newline 1 node setpoint1 upd node set2 out prop newline 1 node setpoint2 upd node setpid -text out prop newline 1 prop width 40 default "" node L1pid -text upd node L2pid -text upd node L1power upd node L2power upd node setrange&mout -text out prop newline 1 default "" node L1range upd prop newline 1 node L2range upd node L1mout upd node L2mout upd node setctrl -text out prop newline 1 default "" node L1ctrl -text upd prop newline 1 node L2ctrl -text upd node setzon -text out prop label setzon prop enum ON=ON,OFF=OFF prop lineend 0 node zone -text upd node tcstatus -text upd prop newline 1 node setposition out prop newline 1 node nv upd node setpressure out prop newline 1 node pressure -text upd node valvestatus -text upd node helevel upd node nlevel upd node sethefrequency out prop label sethefrequency prop enum slow,fast,off prop lineend 0 node hefrequency upd node attoangle upd node attamp upd node attfreq upd } return "17tf forgan and co cryomagnet" } proc 17tf::copy_update {to args} { set val "" foreach from $args { if {[string length $from] == 1} { append val $from } else { append val [hvali [sct]/$from] } } hupdate [sct]/$to $val } proc 17tf::read {} { #in getstatus, the value of dummy1 is missing, read it separately sct send "dummy1" return 17tf::update1 } proc 17tf::update1 {} { hupdate [sct]/persmode [lindex [split [sct result] :] 2] copy_update setpersmode persmode sct send "getstatus" return 17tf::update } proc 17tf::update {} { set res [sct result] if {[string range $res 0 12] ne "getstatus:OK:"} { error [string range $res 0 13] } set res [string range $res 13 end] set list [split $res \;] foreach par $list { if {$par ne ""} { set nam [lindex $par 0] set val [join [lrange $par 1 end]] if {[scan $val "%fT,%fA" fld amp] == 2} { set val $fld } # clientput "|$nam|$val|" hupdate [sct]/$nam $val } } set swheater [hvali [sct]/heater] if {$swheater == 0} { set field [hvali [sct]/output] } elseif {$swheater == 1} { set field 0 } else { set field [hvali [sct]/persistent] } if {[sct status] eq "run"} { # we are driving, check for finish if {abs($field - [sct target]) < 0.001} { sct status idle } elseif {[hvali [sct]/ready] eq "ON"} { # ready might be ON for a short time after setfield? if {[sct try] == 0} { sct try 1 } else { sct status idle } } else { sct try 1 } } sct update $field #buggy: copy_update ignoretbl tblstatus copy_update setpause pausestatus copy_update setrate ramprate copy_update setunits units copy_update ignoretbl tblstatus copy_update set1 setpoint1 copy_update set2 setpoint2 copy_update setzon zone # copy_update setposition nv # hupdate [sct]/setpressure [lindex [split [hvali [sct]/pressure] ,]] 0] # copy_update setpressure pressure copy_update sethefrequency hefrequency copy_update setpid L1pid \; L2Pid copy_update setrange&mout L1range , L1mout \; L2range , L2mout copy_update setctrl L1ctrl \; L2ctrl hupdate [sct]/abort 0 return idle } proc 17tf::writemf {} { if {[silent 0 sct writestatus] eq "start"} { # initiated by a run/drive command sct status run } sct try 0 sct abortim [clock seconds] sct send "ready" return 17tf::writemf2 } proc 17tf::writemf2 {} { if {[sct result] ne "ready:OK:ON"} { if {[clock seconds] >= [sct abortim]} { set try [sct try] incr try if {$try > 12} { sct print "can not abort running field - too many tries" return idle } sct try $try # send abort command every 5 seconds sct abortim [expr [clock seconds] + 5] sct send "abort" return 17tf::writemf3 } # ask ready flag continuously during 5 seconds sct send "ready" return 17tf::writemf2 } sct try 0 sct print "run [sct objectName] to [sct target]" sct send "setfield [sct target]" return 17tf::complete } proc 17tf::writemf3 {} { sct send "ready" return 17tf::writemf2 } proc 17tf::checklimits {} { if {abs([sct target]) > 17} { error "illegal target value" } } proc 17tf::halt {} { sct send abort sct print "abort running [sct objectName]" sct status error return 17tf::haltcomplete } proc 17tf::haltcomplete {} { return idle } proc 17tf::write {} { set name [lindex [split [sct] /] end] sct send "$name [sct target]" sct update [sct target] return 17tf::complete } proc 17tf::writepersmode {} { sct send "dummy2 [sct target]" sct update [sct target] return 17tf::complete } proc 17tf::complete {} { set res [split [sct result] ":"] if {[lindex $res 0] ne [lindex [split [sct send]] 0] && [lindex $res 1] ne "OK"} { error "bad return value: [sct result]" } return idle } proc 17tf::abort {} { sct send abort sct update 1 return stdSct::complete }