Files
sics/tcl/nvs.tcl
2009-05-26 09:38:53 +00:00

158 lines
5.5 KiB
Tcl

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