158 lines
5.5 KiB
Tcl
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
|
|
|
|
|