#------------------------------------------------------------------------- # This is a scriptcontext based driver for the NVS at SANS2. This NVS has # the nasty feauture that its terminators are command dependent. # # Mark Koennecke, April 2009 #----------------------------------------------------------------------- makesctcontroller nvssct varterm psts229.psi.ch:3007 \n 30 #makesctcontroller nvssct varterm localhost:8080 \n 30 nvssct send "\\:REM\n" nvssct debug -1 MakeSecNVS nvs tilt nvssct #---------------------------------------------------------------------------------- # handle parameters first: Most are in the list. MODE is treated special, as an # anchor for finding the status part of the reply and as the polled node used for # updating the parameter list. Date, time and com mode are omitted. #----------------------------------------------------------------------------------- set nvsparlist [list R_SPEED A_SPEED P_LOSS R_CURRENT T_ROT T_INL T_OUT F_RATE A_VAC \ V_OSC V_BCU Hz] foreach par $nvsparlist { hfactory /sics/nvs/${par} plain internal float nvssct connect /sics/nvs/${par} } #----------------------------------------------------------------- proc nvsstatus {} { sct send "\n:???\n" return nvsstatusreply } #---------------------------------------------------------------- # We purposely disregard the geterror mechanism here: it is better to # have an old value rather then no value #----------------------------------------------------------------- proc nvsstatusreply {} { global nvsparlist set reply [sct result] if {[string first ERR $reply] >= 0 \ || [string first ASCERR $reply] >= 0} { clientput "ERROR: $reply while reading NVS, parameter NOT updated" return idle } set idx [string first MODE: $reply] if {$idx < 0} { clientput "Invalid status reponse $reply received from NVS" return idle } set reply [string range $reply $idx end] set parlist [split $reply /] foreach pair $parlist { set l [split $pair :] set par [string trim [lindex $l 0]] set value [string trim [lindex $l 1]] if {[lsearch $nvsparlist $par] >= 0 || [string first MODE $par] >= 0} { catch {hupdate /sics/nvs/${par} $value} msg } } set speed [hval /sics/nvs/A_SPEED] hupdate /sics/nvs $speed return idle } #------------------------------------------------------------------------------- set path /sics/nvs/MODE hfactory $path plain internal text hsetprop $path read nvsstatus hsetprop $path nvsstatusreply nvsstatusreply nvssct poll $path 60 #================================================================================= # This section cares for driving the NVS. Please note that there are two modes: # at low speeds the NVS must be started before over 3000 RPM, a new value can be set. # If ths NVS is already at speed, this step can be saved. # Also we have to check for limits and forbidden speed regions #-------------------------------------------------------------------------------- set nvsrange [list -20 28800] set nvsforbidden [list {3600 4500} {7800 10500} {21500 23500}] #-------------------------------------------------------------------------------- proc nvscheck {} { global nvsrange nvsforbidden set target [sct target] set min [lindex $nvsrange 0] set max [lindex $nvsrange 1] if {$target < $min || $target > $max} { error "$target is out of range" } foreach range $nvsforbidden { set min [lindex $range 0] set max [lindex $range 1] if {$target > $min && $target < $max} { error "$target is in forbidden region" } } return OK } #-------------------------------------------------------------------------------- # Halting for a NVS is interpreted as: leave at current speed #-------------------------------------------------------------------------------- proc nvshalt {} { set current [hval /sics/nvs] set send [format "\r:SDR %d\n" [expr int($current)]] return nvsreply } #--------------------------------------------------------------------------------- proc nvsreply {} { set reply [sct result] if {[string first ERR $reply] >= 0 \ || [string first ASCERR $reply] >= 0} { clientput "ERROR: $reply while driving NVS" } return idle } #-------------------------------------------------------------------------------- # checking status #-------------------------------------------------------------------------------- proc nvscheckstatus {} { set mode [sct runmode] if {[string first start $mode] >= 0} { return idle } set target [sct target] set actual [hval /sics/nvs/A_SPEED] if {abs($target - $actual) < 5} { wait 20 return idle } nvssct queue /sics/nvs/MODE progress read return busy } #-------------------------------------------------------------------------------- proc nvswrite {} { set target [sct target] set actual [hval /sics/nvs/A_SPEED] if {$target < 50 } { sct send "\r:HAL\n" sct runmode halt return nvsreply } if {$actual >= 3000} { sct send [format "\r:SDR %d\n" [expr int($target)]] sct runmode normal } else { sct send "\r:SST\n" clientput "NVS started, check manually when done" sct runmode start } return nvsreply } #--------------------------------------------------------------------------------- hsetprop /sics/nvs checklimits nvscheck hsetprop /sics/nvs checkstatus nvscheckstatus hsetprop /sics/nvs halt nvshalt hsetprop /sics/nvs nvsreply nvsreply hsetprop /sics/nvs write nvswrite hsetprop /sics/nvs runmode normal nvssct write /sics/nvs nvssct queue /sics/nvs/MODE progress read nvs tilt