Make instance data properties of a params node instead of namespace global variables
This is to allow multiple instance of the same device type without clashing of persistent data r3248 | dcl | 2011-08-22 11:30:20 +1000 (Mon, 22 Aug 2011) | 3 lines
This commit is contained in:
@@ -25,6 +25,10 @@
|
||||
# Workaround: use 2 copies of this source code which are identical except for
|
||||
# the literal name of the proc add_ls336 vs.340 and the
|
||||
# namespace eval ::scobj::ls336 vs 340
|
||||
# Remediation: Move all of the "global" variables into properties of the "params"
|
||||
# node so they can exist as "instance" variables and not clash for multiple
|
||||
# instances of identical devices (e.g. two Lakeshore 336 temperature controllers)
|
||||
#
|
||||
# ----------------------------------------------------------------------------*/
|
||||
|
||||
# Notes
|
||||
@@ -45,6 +49,21 @@
|
||||
|
||||
# Default temperature controller parameters
|
||||
namespace eval ::scobj::ls336 {
|
||||
# Convenience function to replace global variables with properties of the "params" node.
|
||||
proc set_param { tc_root param value } {
|
||||
hsetprop $tc_root/params $param "$value"
|
||||
}
|
||||
# Convenience function to replace global variables with properties of the "params" node.
|
||||
proc get_param { tc_root param } {
|
||||
if { ![hpropexists $tc_root/params $param] } {
|
||||
broadcast "Getting non-existent parameter $param"
|
||||
return ""
|
||||
}
|
||||
set result "[SplitReply [hgetprop $tc_root/params $param]]"
|
||||
return $result
|
||||
}
|
||||
# Initialize instance-local "global" variables. Needed since replacing with per-instance properties.
|
||||
proc init_params { tc_root } {
|
||||
# Some global variables that are useful as default initilisation values or for tracking
|
||||
# Name of the scriptcontext object created from calling this driver - an instrument may use more than one
|
||||
# What Lakeshore model are we dealing with? 336 or 340?
|
||||
@@ -55,49 +74,47 @@ namespace eval ::scobj::ls336 {
|
||||
# Variables that are identical to node names but are needed internally as well
|
||||
# temperature difference between setpoint and actual temperature at which the
|
||||
# heater changes from idle to driving
|
||||
set ls336_driveTolerance1 2
|
||||
set ls336_driveTolerance2 2
|
||||
set_param $tc_root ls336_driveTolerance1 2
|
||||
set_param $tc_root ls336_driveTolerance2 2
|
||||
# Next 2 parameters are supported by LS model 340 only
|
||||
# ctrl loop 1 settle parameter, threshold=allowable band around setpoint (0,..,100)
|
||||
set ls340_settleThr 30
|
||||
set_param $tc_root ls340_settleThr 30
|
||||
# ctrl loop 1 settle parameter, settle time in seconds
|
||||
set ls340_settleTime 30
|
||||
set_param $tc_root ls340_settleTime 30
|
||||
# default Heater Range (0,..,5) zero is off, hence the least dangerous
|
||||
set ls336_range 0
|
||||
set_param $tc_root ls336_range 0
|
||||
# upper and lower temperature limit in Kelvin
|
||||
set ls336_upperlimit 500.0
|
||||
set ls336_lowerlimit 4.0
|
||||
set_param $tc_root ls336_upperlimit 500.0
|
||||
set_param $tc_root ls336_lowerlimit 4.0
|
||||
# temperature units are Kelvin
|
||||
set ls336_tempUnits "K"
|
||||
set_param $tc_root ls336_tempUnits "K"
|
||||
# ls336 status byte
|
||||
# enable extra logging - can produce huge stout****.log file in /usr/local/sics/log/
|
||||
set ls336_verbose 0
|
||||
set_param $tc_root ls336_verbose 0
|
||||
# a list of available sensors (not all may be connected/active)
|
||||
set this_sensorlist [list A B C D]
|
||||
set_param $tc_root this_sensorlist [list A B C D]
|
||||
# a list of controler loops
|
||||
set this_controlerlist [list 1 2]
|
||||
set_param $tc_root this_controlerlist [list 1 2]
|
||||
# set device ID to unknown
|
||||
# set self-test result to unknown
|
||||
set this_selfTestResult -1
|
||||
set_param $tc_root this_selfTestResult -1
|
||||
# status of input channels - unknown at startup
|
||||
set ls336_sampleSensor "UNKNOWN"
|
||||
set timeInSecsSince2000 0
|
||||
set_param $tc_root ls336_sampleSensor "UNKNOWN"
|
||||
set_param $tc_root timeInSecsSince2000 0
|
||||
|
||||
set alarm_Limit_LoA $ls336_lowerlimit
|
||||
set alarm_Limit_LoB $ls336_lowerlimit
|
||||
set alarm_Limit_LoC $ls336_lowerlimit
|
||||
set alarm_Limit_LoD $ls336_lowerlimit
|
||||
set alarm_Limit_HiA $ls336_upperlimit
|
||||
set alarm_Limit_HiB $ls336_upperlimit
|
||||
set alarm_Limit_HiC $ls336_upperlimit
|
||||
set alarm_Limit_HiD $ls336_upperlimit
|
||||
set checkAlarmLimitsA 1
|
||||
set checkAlarmLimitsB 1
|
||||
set checkAlarmLimitsC 1
|
||||
set checkAlarmLimitsD 1
|
||||
|
||||
set tc_dfltURL ca5-[instname]
|
||||
array set moxaPortMap {1 4001 2 4002 3 4003 4 4004}
|
||||
set_param $tc_root alarm_Limit_LoA [get_param $tc_root ls336_lowerlimit]
|
||||
set_param $tc_root alarm_Limit_LoB [get_param $tc_root ls336_lowerlimit]
|
||||
set_param $tc_root alarm_Limit_LoC [get_param $tc_root ls336_lowerlimit]
|
||||
set_param $tc_root alarm_Limit_LoD [get_param $tc_root ls336_lowerlimit]
|
||||
set_param $tc_root alarm_Limit_HiA [get_param $tc_root ls336_upperlimit]
|
||||
set_param $tc_root alarm_Limit_HiB [get_param $tc_root ls336_upperlimit]
|
||||
set_param $tc_root alarm_Limit_HiC [get_param $tc_root ls336_upperlimit]
|
||||
set_param $tc_root alarm_Limit_HiD [get_param $tc_root ls336_upperlimit]
|
||||
set_param $tc_root checkAlarmLimitsA 1
|
||||
set_param $tc_root checkAlarmLimitsB 1
|
||||
set_param $tc_root checkAlarmLimitsC 1
|
||||
set_param $tc_root checkAlarmLimitsD 1
|
||||
}
|
||||
|
||||
########### Initialisation #############################
|
||||
|
||||
@@ -113,8 +130,8 @@ proc ls336_init {sct_controller tc_root} {
|
||||
# Define a constant time offset for later logging of data with timStamp
|
||||
# counting from 1st Jan 2000 00:00hrs
|
||||
# clock command does not work in tcl8.5 ?!
|
||||
set ::scobj::ls336::timeInSecsSince2000 [clock scan 20000101T000000A]
|
||||
# set ::scobj::ls336::timeInSecsSince2000 1000
|
||||
set_param $tc_root timeInSecsSince2000 [clock scan 20000101T000000A]
|
||||
# set_param $tc_root timeInSecsSince2000 1000
|
||||
# set the communication protocol: terminator <CR>, bps 9600 baud, 7 data bits +
|
||||
# 1 stop bit + odd parity bit
|
||||
# Query the device ID - are we talking to a Lakeshore 340 or 336?
|
||||
@@ -135,22 +152,22 @@ proc ls336_init {sct_controller tc_root} {
|
||||
# $sct_controller queue $tc_root/other/statusByte progress read
|
||||
# Was the self-test successful?
|
||||
$sct_controller queue $tc_root/other/selftest progress read
|
||||
set ::scobj::ls336::this_selfTestResult [hval $tc_root/other/selftest]
|
||||
if {$::scobj::ls336::this_selfTestResult == 0} {
|
||||
set_param $tc_root this_selfTestResult [hval $tc_root/other/selftest]
|
||||
if {[get_param $tc_root this_selfTestResult] == 0} {
|
||||
puts "sct_lakeshore336.tcl: Lakeshore 336 self-test ok."
|
||||
} else {
|
||||
puts "sct_lakeshore336.tcl: The Lakeshore 336 failed its self-test."
|
||||
}
|
||||
# Set the default upper and lower temperature alarm limits in Kelvin
|
||||
foreach iSensor $::scobj::ls336::this_sensorlist {
|
||||
foreach iSensor [get_param $tc_root this_sensorlist] {
|
||||
hsetprop $tc_root/input/alarm_Limits_$iSensor units "K"
|
||||
hsetprop $tc_root/input/alarm_Limits_$iSensor units "K"
|
||||
}
|
||||
# Set the default heater range (1,..,5)
|
||||
# Set the default settle parameters
|
||||
# Set the default tolerances for the setpoint temperatures
|
||||
hset $tc_root/control/tolerance1 $::scobj::ls336::ls336_driveTolerance1
|
||||
hset $tc_root/control/tolerance2 $::scobj::ls336::ls336_driveTolerance2
|
||||
hset $tc_root/control/tolerance1 [get_param $tc_root ls336_driveTolerance1]
|
||||
hset $tc_root/control/tolerance2 [get_param $tc_root ls336_driveTolerance2]
|
||||
} message ]} {
|
||||
return -code error "in ls336_init: $message"
|
||||
}
|
||||
@@ -177,7 +194,7 @@ proc getValue {tc_root nextState cmd idx} {
|
||||
# we are reading from a pseudo-node where there is no direct representation
|
||||
# in the device
|
||||
# puts "getValue(InpSample)"
|
||||
#sct send $cmd$::scobj::ls336::ls336_term
|
||||
#sct send $cmd[get_param $tc_root ls336_term]
|
||||
} elseif { 0 == [string compare -length 7 $cmd "CRVHDR?"] } {
|
||||
# In the case of calCurveHdr we need an extra parameter with the command sent
|
||||
set nodename $tc_root/input/inpCalCurve_$idx
|
||||
@@ -205,7 +222,7 @@ proc getValue {tc_root nextState cmd idx} {
|
||||
# rdValue is the default nextState for getValue() and setValue()
|
||||
# @param idx indicates which control loop or which input channel the command belongs to
|
||||
# @return idle Always returns system state idle - command sequence completed.
|
||||
proc rdValue {tcroot rdCmd idx} {
|
||||
proc rdValue {tc_root rdCmd idx} {
|
||||
if {[ catch {
|
||||
set data [sct result]
|
||||
# puts "rdValue(): result is $data"
|
||||
@@ -224,7 +241,7 @@ proc getValue {tc_root nextState cmd idx} {
|
||||
}
|
||||
}
|
||||
if {$idx == "A" || $idx == "B" || $idx == "C" || $idx == "D"} {
|
||||
set nodename $tcroot/input/calCurveHdr_$idx
|
||||
set nodename $tc_root/input/calCurveHdr_$idx
|
||||
hset $nodename "noCurve"
|
||||
}
|
||||
}
|
||||
@@ -264,14 +281,14 @@ proc getValue {tc_root nextState cmd idx} {
|
||||
set aT "T"
|
||||
set timeString $ayear$amonth$aday$aT$ahour$amin$asec$aA
|
||||
set timeInSecs [clock scan $timeString]
|
||||
set timeInSecs [expr {$timeInSecs - $::scobj::ls336::timeInSecsSince2000}]
|
||||
hset $tcroot/sensor/timStamp $timeInSecs
|
||||
set timeInSecs [expr {$timeInSecs - [get_param $tc_root timeInSecsSince2000]}]
|
||||
hset $tc_root/sensor/timStamp $timeInSecs
|
||||
if {1==0} {
|
||||
# if we could write a string value to NXsensor, then this date-time format would be nicer...
|
||||
set sColon ":"
|
||||
set sSpace " "
|
||||
set isoTimeString $ayear$amonth$aday$sSpace$ahour$sColon$amin$sColon$asec
|
||||
hset $tcroot/sensor/timStamp $isoTimeString
|
||||
hset $tc_root/sensor/timStamp $isoTimeString
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,7 +306,7 @@ proc getValue {tc_root nextState cmd idx} {
|
||||
# It is preceeded by a call to getValue() and a replacement for rdValue.
|
||||
# @param idx indicates which control loop or which input channel the command belongs to
|
||||
# @return idle Always returns system state idle - command sequence completed.
|
||||
proc rdAlarmVal {tcroot rdCmd iSensor} {
|
||||
proc rdAlarmVal {tc_root rdCmd iSensor} {
|
||||
if {[ catch {
|
||||
set data [sct result]
|
||||
switch -glob -- $data {
|
||||
@@ -318,24 +335,24 @@ proc rdAlarmVal {tcroot rdCmd iSensor} {
|
||||
|
||||
switch $iSensor {
|
||||
"A" {
|
||||
set ::scobj::ls336::checkAlarmLimitsA $onOff
|
||||
if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoA $loVal}
|
||||
if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiA $hiVal}
|
||||
set_param $tc_root checkAlarmLimitsA $onOff
|
||||
if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoA $loVal}
|
||||
if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiA $hiVal}
|
||||
}
|
||||
"B" {
|
||||
set ::scobj::ls336::checkAlarmLimitsB $onOff
|
||||
if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoB $loVal}
|
||||
if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiB $hiVal}
|
||||
set_param $tc_root checkAlarmLimitsB $onOff
|
||||
if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoB $loVal}
|
||||
if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiB $hiVal}
|
||||
}
|
||||
"C" {
|
||||
set ::scobj::ls336::checkAlarmLimitsC $onOff
|
||||
if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoC $loVal}
|
||||
if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiC $hiVal}
|
||||
set_param $tc_root checkAlarmLimitsC $onOff
|
||||
if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoC $loVal}
|
||||
if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiC $hiVal}
|
||||
}
|
||||
"D" {
|
||||
set ::scobj::ls336::checkAlarmLimitsD $onOff
|
||||
if {$loVal >= 0} {set ::scobj::ls336::alarm_Limit_LoD $loVal}
|
||||
if {$hiVal >= 0} {set ::scobj::ls336::alarm_Limit_HiD $hiVal}
|
||||
set_param $tc_root checkAlarmLimitsD $onOff
|
||||
if {$loVal >= 0} {set_param $tc_root alarm_Limit_LoD $loVal}
|
||||
if {$hiVal >= 0} {set_param $tc_root alarm_Limit_HiD $hiVal}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,7 +371,7 @@ proc rdAlarmVal {tcroot rdCmd iSensor} {
|
||||
# function is called for the CSET* and OUTMODE* commands.
|
||||
# @param idx indicates which control channel the command acts upon
|
||||
# @return idle Always returns system state idle - command sequence completed.
|
||||
proc rdCfgValue {tcroot rdCmd idx} {
|
||||
proc rdCfgValue {tc_root rdCmd idx} {
|
||||
if {[ catch {
|
||||
set data [sct result]
|
||||
switch -glob -- $data {
|
||||
@@ -403,15 +420,15 @@ proc rdAlarmVal {tcroot rdCmd iSensor} {
|
||||
append ctrl_Loop_Txt $mode
|
||||
# puts "rdCfgValue() idx: $idx, data: $data, output: $idx, ctrl_Loop_Txt: $ctrl_Loop_Txt"
|
||||
# puts "rdCfgValue setting ls336_input4CtrlLp idx:$idx, input:$input, myInp:$myInp"
|
||||
set nodename $tcroot/sensor/ctrl_Loop_$idx
|
||||
set nodename $tc_root/sensor/ctrl_Loop_$idx
|
||||
hset $nodename $ctrl_Loop_Txt
|
||||
# Keep track of which inputs are used for the control loops
|
||||
# puts "rdCfgValue() idx: $idx, data: $data, input:$input, ctrl_Loop_Txt: $ctrl_Loop_Txt"
|
||||
switch $idx {
|
||||
"1" {hsetprop $tcroot/sensor/ctrl_Loop_1 ls336_input4CtrlLp1 $input}
|
||||
"2" {hsetprop $tcroot/sensor/ctrl_Loop_2 ls336_input4CtrlLp2 $input}
|
||||
"3" {hsetprop $tcroot/sensor/ctrl_Loop_3 ls336_input4CtrlLp3 $input}
|
||||
"4" {hsetprop $tcroot/sensor/ctrl_Loop_4 ls336_input4CtrlLp4 $input}
|
||||
"1" {hsetprop $tc_root/sensor/ctrl_Loop_1 ls336_input4CtrlLp1 $input}
|
||||
"2" {hsetprop $tc_root/sensor/ctrl_Loop_2 ls336_input4CtrlLp2 $input}
|
||||
"3" {hsetprop $tc_root/sensor/ctrl_Loop_3 ls336_input4CtrlLp3 $input}
|
||||
"4" {hsetprop $tc_root/sensor/ctrl_Loop_4 ls336_input4CtrlLp4 $input}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -430,7 +447,7 @@ proc rdAlarmVal {tcroot rdCmd iSensor} {
|
||||
# It is preceeded by a call to getValue() and is a replacement for rdValue().
|
||||
# @param iSensor indicates which input channel the command belongs to
|
||||
# @return idle Always returns system state idle - command sequence completed.
|
||||
proc rdBitValue {tcroot rdCmd iSensor} {
|
||||
proc rdBitValue {tc_root rdCmd iSensor} {
|
||||
if {[ catch {
|
||||
set data [sct result]
|
||||
switch -glob -- $data {
|
||||
@@ -497,7 +514,7 @@ proc rdBitValue {tcroot rdCmd iSensor} {
|
||||
# with the message from RDGST? if the input is invalid.
|
||||
# @param idx indicates which input channel the command acts upon
|
||||
# @return idle Always returns system state idle - command sequence completed.
|
||||
proc rdInpValue {tcroot rdCmd idx} {
|
||||
proc rdInpValue {tc_root rdCmd idx} {
|
||||
if {[ catch {
|
||||
set data [sct result]
|
||||
switch -glob -- $data {
|
||||
@@ -510,8 +527,8 @@ proc rdBitValue {tcroot rdCmd iSensor} {
|
||||
# update only once per poll cycle needed
|
||||
# Read the sics node sampleSensor to
|
||||
# determine which input represents the sample temperature
|
||||
set nodename $tcroot/sensor/sampleSensor
|
||||
set ::scobj::ls336::ls336_sampleSensor [hval $nodename]
|
||||
set nodename $tc_root/sensor/sampleSensor
|
||||
set_param $tc_root ls336_sampleSensor [hval $nodename]
|
||||
}
|
||||
if { $data != [sct oldval] } {
|
||||
sct oldval $data
|
||||
@@ -522,19 +539,19 @@ proc rdBitValue {tcroot rdCmd iSensor} {
|
||||
|
||||
# RDGST? is 'ok' or 'UNKNOWN' -> it is okay to show the Kelvin reading we have
|
||||
set value $data
|
||||
if {$idx == $::scobj::ls336::ls336_sampleSensor} {
|
||||
hset $tcroot/sensor/Tsample $value
|
||||
if {$idx == [get_param $tc_root ls336_sampleSensor]} {
|
||||
hset $tc_root/sensor/Tsample $value
|
||||
}
|
||||
# Switch command did not work reliably below, hence a less elegant but
|
||||
# functional if-elseif-else contruct is implemented instead
|
||||
if {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_1 ls336_input4CtrlLp1]} {
|
||||
hset $tcroot/sensor/ctrlLp1_value $value
|
||||
} elseif {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_2 ls336_input4CtrlLp2]} {
|
||||
hset $tcroot/sensor/ctrlLp2_value $value
|
||||
} elseif {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_3 ls336_input4CtrlLp3]} {
|
||||
hset $tcroot/sensor/ctrlLp3_value $value
|
||||
} elseif {$idx == [hgetpropval $tcroot/sensor/ctrl_Loop_4 ls336_input4CtrlLp4]} {
|
||||
hset $tcroot/sensor/ctrlLp4_value $value
|
||||
if {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_1 ls336_input4CtrlLp1]} {
|
||||
hset $tc_root/sensor/ctrlLp1_value $value
|
||||
} elseif {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_2 ls336_input4CtrlLp2]} {
|
||||
hset $tc_root/sensor/ctrlLp2_value $value
|
||||
} elseif {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_3 ls336_input4CtrlLp3]} {
|
||||
hset $tc_root/sensor/ctrlLp3_value $value
|
||||
} elseif {$idx == [hgetpropval $tc_root/sensor/ctrl_Loop_4 ls336_input4CtrlLp4]} {
|
||||
hset $tc_root/sensor/ctrlLp4_value $value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -555,9 +572,9 @@ proc rdBitValue {tcroot rdCmd iSensor} {
|
||||
# for reasoning).
|
||||
# @param CtrlLoopIdx indicates which control loop the command acts upon
|
||||
# @return idle Always returns system state idle - command sequence completed.
|
||||
proc inTolerance {tcroot rdCmd CtrlLoopIdx} {
|
||||
proc inTolerance {tc_root rdCmd CtrlLoopIdx} {
|
||||
if {[ catch {
|
||||
set tc_root $tcroot
|
||||
set tc_root $tc_root
|
||||
set data [sct result]
|
||||
set oldvalue [sct oldval]
|
||||
switch -glob -- $data {
|
||||
@@ -616,10 +633,10 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} {
|
||||
set nodename $tc_root/sensor/sensorValue$iSensor
|
||||
set temp [hval $nodename]
|
||||
set diff [expr {abs($setpt - $temp)}]
|
||||
# $::scobj::ls336::ls336_driveTolerance = 0.2 Kelvin
|
||||
set tol $::scobj::ls336::ls336_driveTolerance1
|
||||
# [get_param $tc_root ls336_driveTolerance] = 0.2 Kelvin
|
||||
set tol [get_param $tc_root ls336_driveTolerance1]
|
||||
if {$CtrlLoopIdx == 2} {
|
||||
set tol $::scobj::ls336::ls336_driveTolerance2
|
||||
set tol [get_param $tc_root ls336_driveTolerance2]
|
||||
}
|
||||
# if $diff > $tol
|
||||
if {$intol==0} {
|
||||
@@ -627,10 +644,10 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} {
|
||||
hset $nodename "drive"
|
||||
if {$CtrlLoopIdx == 1} {
|
||||
hset $tc_root/status "busy"
|
||||
if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename drive; hset $tc_root/status busy"}
|
||||
if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename drive; hset $tc_root/status busy"}
|
||||
} else {
|
||||
hset $tc_root/status_Ctrl_Lp2 "busy"
|
||||
if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename drive; hset $tc_root/status_Ctrl_Lp2 busy"}
|
||||
if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename drive; hset $tc_root/status_Ctrl_Lp2 busy"}
|
||||
}
|
||||
} else {
|
||||
set nodename $tc_root/sensor/setpoint$CtrlLoopIdx
|
||||
@@ -639,10 +656,10 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} {
|
||||
hset $nodename "monitor"
|
||||
if {$CtrlLoopIdx == 1} {
|
||||
hset $tc_root/status "idle"
|
||||
if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename idle; hset $tc_root/status monitor"}
|
||||
if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename idle; hset $tc_root/status monitor"}
|
||||
} else {
|
||||
hset $tc_root/status_Ctrl_Lp2 "idle"
|
||||
if {$::scobj::ls336::ls336_verbose==1} {puts "hset $nodename idle; hset $tc_root/status_Ctrl_Lp2 monitor"}
|
||||
if {[get_param $tc_root ls336_verbose]==1} {puts "hset $nodename idle; hset $tc_root/status_Ctrl_Lp2 monitor"}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -666,7 +683,7 @@ proc inTolerance {tcroot rdCmd CtrlLoopIdx} {
|
||||
# @brief rdCalValue()) does what rdValue() does plus it resets the value /input/calCurveHdr_$idx forcing that node to refresh
|
||||
# @param idx indicates which control loop or which input channel the command belongs to
|
||||
# @return idle Always returns system state idle - command sequence completed.
|
||||
proc rdCrvValue {tcroot rdCmd idx} {
|
||||
proc rdCrvValue {tc_root rdCmd idx} {
|
||||
if {[ catch {
|
||||
set data [sct result]
|
||||
switch -glob -- $data {
|
||||
@@ -681,7 +698,7 @@ proc rdCrvValue {tcroot rdCmd idx} {
|
||||
sct utime readtime
|
||||
# The calibration curve has changed.
|
||||
# Set the curve header name to unknown, thus forcing the respective node to refresh
|
||||
set tc_root $tcroot
|
||||
set tc_root $tc_root
|
||||
set nodename $tc_root/input/calCurveHdr_$idx
|
||||
hset $nodename "request refresh"
|
||||
#puts "hset $nodename request refresh"
|
||||
@@ -771,7 +788,7 @@ proc setPoint {tc_root nextState cmd whichCtrlLoop} {
|
||||
if {[ catch {
|
||||
#puts "executing setPoint ($tc_root $nextState $cmd $whichCtrlLoop)"
|
||||
#broadcast setPoint "executing setPoint ($tc_root $nextState $cmd $whichCtrlLoop)"
|
||||
set ns ::scobj::lh45
|
||||
set ns "[namespace current]"
|
||||
set par [sct target]
|
||||
|
||||
# determine the corresponding input sensor
|
||||
@@ -916,13 +933,13 @@ proc sendCmd {tc_root nextState cmd {idx ""}} {
|
||||
# @brief determines which input sensor corresponds to this control loop or output
|
||||
# @param CtrlLoopIdx the control loop (valid values 1,2) or output (1,2,3,4)
|
||||
# @return iSensor returns A,B,C or D or None or Unknown
|
||||
proc getCorrespondingInputSensor {tcroot CtrlLoopIdx} {
|
||||
proc getCorrespondingInputSensor {tc_root CtrlLoopIdx} {
|
||||
# LS 336, device command outMode_*
|
||||
if {$CtrlLoopIdx < 1 || $CtrlLoopIdx > 4} {
|
||||
set iSensor "UNKOWN"
|
||||
return $iSensor
|
||||
}
|
||||
set nodename $tcroot/control/outMode_$CtrlLoopIdx
|
||||
set nodename $tc_root/control/outMode_$CtrlLoopIdx
|
||||
set data [hval $nodename]
|
||||
set input [::scobj::ls336::getValFromString $data 1 ","]
|
||||
switch -glob -- $input {
|
||||
@@ -963,28 +980,28 @@ proc checktol {tc_root currtime timecheck iLoop iSensor} {
|
||||
}
|
||||
set lotemp [expr {$setpt - $tol}]
|
||||
set hitemp [expr {$setpt + $tol}]
|
||||
if {$::scobj::ls336::ls336_verbose==1} {
|
||||
if {[get_param $tc_root ls336_verbose]==1} {
|
||||
puts "checktol(): setpt $isetp=$setpt lotemp=$lotemp, current $sensorValue=$temp, hitemp=$hitemp, tol=$tol, iLoop=$iLoop, timecheck=$timecheck, currtime=$currtime"
|
||||
}
|
||||
if { $temp < $lotemp || $temp > $hitemp} {
|
||||
hset $tc_root/emon/isInTolerance_Lp$iLoop "outsideTolerance"
|
||||
if {$::scobj::ls336::ls336_verbose==1} {puts "hset $tc_root/emon/isInTolerance_Lp$iLoop outsideTolerance"}
|
||||
if {[get_param $tc_root ls336_verbose]==1} {puts "hset $tc_root/emon/isInTolerance_Lp$iLoop outsideTolerance"}
|
||||
if {$iLoop==1} { sct utime timecheck }
|
||||
if {$iLoop==2} { sct utime timecheck2 }
|
||||
return 0
|
||||
} else {
|
||||
set timeout $::scobj::ls336::ls340_settleTime
|
||||
set timeout [get_param $tc_root ls340_settleTime]
|
||||
set elapsedTime [expr {$currtime - $timecheck}]
|
||||
if {$elapsedTime > $timeout} {
|
||||
hset $tc_root/emon/isInTolerance_Lp$iLoop "inTolerance"
|
||||
if {$::scobj::ls336::ls336_verbose==1} {
|
||||
if {[get_param $tc_root ls336_verbose]==1} {
|
||||
puts "hset $tc_root/emon/isInTolerance_Lp$iLoop inTolerance (elapsedTime=$elapsedTime greater than settleTime=$timeout)"
|
||||
}
|
||||
return 1
|
||||
} else {
|
||||
# Temperature has not been within tolerance for enough time - (overshoots, oscillations,..)
|
||||
hset $tc_root/emon/isInTolerance_Lp$iLoop "outsideTolerance"
|
||||
if {$::scobj::ls336::ls336_verbose==1} {
|
||||
if {[get_param $tc_root ls336_verbose]==1} {
|
||||
puts "hset $tc_root/emon/isInTolerance_Lp$iLoop outsideTolerance (elapsedTime=$elapsedTime less than settleTime=$timeout)"
|
||||
}
|
||||
return 0
|
||||
@@ -1007,29 +1024,29 @@ proc check {tc_root whichCtrlLoop} {
|
||||
# determine the corresponding input sensor
|
||||
set whichSensor [getCorrespondingInputSensor $tc_root $whichCtrlLoop]
|
||||
# puts "check(): whichCtrlLoop=$whichCtrlLoop whichSensor= $whichSensor"
|
||||
set lolimit $::scobj::ls336::alarm_Limit_LoA
|
||||
set hilimit $::scobj::ls336::alarm_Limit_HiA
|
||||
set bCheckLimits $::scobj::ls336::checkAlarmLimitsA
|
||||
set lolimit [get_param $tc_root alarm_Limit_LoA]
|
||||
set hilimit [get_param $tc_root alarm_Limit_HiA]
|
||||
set bCheckLimits [get_param $tc_root checkAlarmLimitsA]
|
||||
switch $whichSensor {
|
||||
"A" {
|
||||
set lolimit $::scobj::ls336::alarm_Limit_LoA
|
||||
set hilimit $::scobj::ls336::alarm_Limit_HiA
|
||||
set bCheckLimits $::scobj::ls336::checkAlarmLimitsA
|
||||
set lolimit [get_param $tc_root alarm_Limit_LoA]
|
||||
set hilimit [get_param $tc_root alarm_Limit_HiA]
|
||||
set bCheckLimits [get_param $tc_root checkAlarmLimitsA]
|
||||
}
|
||||
"B" {
|
||||
set lolimit $::scobj::ls336::alarm_Limit_LoB
|
||||
set hilimit $::scobj::ls336::alarm_Limit_HiB
|
||||
set bCheckLimits $::scobj::ls336::checkAlarmLimitsB
|
||||
set lolimit [get_param $tc_root alarm_Limit_LoB]
|
||||
set hilimit [get_param $tc_root alarm_Limit_HiB]
|
||||
set bCheckLimits [get_param $tc_root checkAlarmLimitsB]
|
||||
}
|
||||
"C" {
|
||||
set lolimit $::scobj::ls336::alarm_Limit_LoC
|
||||
set hilimit $::scobj::ls336::alarm_Limit_HiC
|
||||
set bCheckLimits $::scobj::ls336::checkAlarmLimitsC
|
||||
set lolimit [get_param $tc_root alarm_Limit_LoC]
|
||||
set hilimit [get_param $tc_root alarm_Limit_HiC]
|
||||
set bCheckLimits [get_param $tc_root checkAlarmLimitsC]
|
||||
}
|
||||
"D" {
|
||||
set lolimit $::scobj::ls336::alarm_Limit_LoD
|
||||
set hilimit $::scobj::ls336::alarm_Limit_HiD
|
||||
set bCheckLimits $::scobj::ls336::checkAlarmLimitsD
|
||||
set lolimit [get_param $tc_root alarm_Limit_LoD]
|
||||
set hilimit [get_param $tc_root alarm_Limit_HiD]
|
||||
set bCheckLimits [get_param $tc_root checkAlarmLimitsD]
|
||||
}
|
||||
default {
|
||||
error "sct_ls336.tcl check(): Can't set setpoint. No valid input sensor specified for this output control loop."
|
||||
@@ -1508,7 +1525,7 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p
|
||||
#puts "createing node for: $scobj_hpath $cmdGroup $varName $readable $writable $pollEnabled $drivable $idx $dataType $permission $rdCmd $rdFunc $wrCmd $wrFunc"
|
||||
# It is a command that is supported by the device
|
||||
if {[ catch {
|
||||
set ns ::scobj::ls336
|
||||
set ns "[namespace current]"
|
||||
set nodeName "$scobj_hpath/$cmdGroup/$varName"
|
||||
if {1 > [string length $cmdGroup]} {
|
||||
set nodeName "$scobj_hpath/$varName"
|
||||
@@ -1564,23 +1581,27 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p
|
||||
# @return nothing (well, the sct object)
|
||||
proc mk_sct_lakeshore_336 {sct_controller klasse tempobj tol1 tol2 verbose} {
|
||||
if {[ catch {
|
||||
set ::scobj::ls336::ls336_driveTolerance1 $tol1
|
||||
set ::scobj::ls336::ls336_driveTolerance2 $tol2
|
||||
set ::scobj::ls336::ls336_verbose $verbose
|
||||
set ns ::scobj::ls336
|
||||
|
||||
# terminator string for serial communication (empty for ls340, taken care of with the COMM command)
|
||||
#set CR "\r"
|
||||
#set LF "\n"
|
||||
#Wombat uses only CR not CRLF
|
||||
#set ::scobj::ls336::ls336_term "" ! obsolete
|
||||
|
||||
MakeSICSObj $tempobj SCT_OBJECT
|
||||
sicslist setatt $tempobj klass $klasse
|
||||
sicslist setatt $tempobj long_name $tempobj
|
||||
# Create a base node for all the state machines of this sics object
|
||||
set scobj_hpath /sics/$tempobj
|
||||
|
||||
# Initialise the per-instance "global" parameters
|
||||
hfactory $scobj_hpath/params plain spy none
|
||||
init_params $scobj_hpath
|
||||
set_param $scobj_hpath ls336_driveTolerance1 $tol1
|
||||
set_param $scobj_hpath ls336_driveTolerance2 $tol2
|
||||
set_param $scobj_hpath ls336_verbose $verbose
|
||||
|
||||
set ns "[namespace current]"
|
||||
|
||||
# terminator string for serial communication (empty for ls340, taken care of with the COMM command)
|
||||
#set CR "\r"
|
||||
#set LF "\n"
|
||||
#Wombat uses only CR not CRLF
|
||||
#set_param $scobj_hpath ls336_term "" ! obsolete
|
||||
|
||||
# Create state machines for the following device commands (non-polled entries are place-holders
|
||||
# for manually maintained nodes, like the selector for the input that provides the sample temperature
|
||||
# 'sampleSensor', the sample tempreature reading 'Tsample', the input that provides for the controlLoop
|
||||
@@ -1712,10 +1733,10 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p
|
||||
# helpNotes4user $scobj_hpath $cmdGroup $varName
|
||||
}
|
||||
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_A units $::scobj::ls336::ls336_tempUnits
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_B units $::scobj::ls336::ls336_tempUnits
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_C units $::scobj::ls336::ls336_tempUnits
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_D units $::scobj::ls336::ls336_tempUnits
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_A units [get_param $scobj_hpath ls336_tempUnits]
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_B units [get_param $scobj_hpath ls336_tempUnits]
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_C units [get_param $scobj_hpath ls336_tempUnits]
|
||||
hsetprop $scobj_hpath/input/alarm_Limits_D units [get_param $scobj_hpath ls336_tempUnits]
|
||||
|
||||
# Create state machines for the following required nodes that do not correspond
|
||||
# to device commands. So far we only provide one tolerance for both control loops.
|
||||
@@ -1725,22 +1746,22 @@ proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable p
|
||||
helpNotes4user $scobj_hpath "control" "apply_tolerance"
|
||||
|
||||
hfactory $scobj_hpath/control/tolerance1 plain user float
|
||||
hsetprop $scobj_hpath/control/tolerance1 units $::scobj::ls336::ls336_tempUnits
|
||||
hsetprop $scobj_hpath/control/tolerance1 units [get_param $scobj_hpath ls336_tempUnits]
|
||||
# hsetprop $scobj_hpath/control/tolerance units "K"
|
||||
hset $scobj_hpath/control/tolerance1 $tol1
|
||||
helpNotes4user $scobj_hpath "control" "tolerance1"
|
||||
|
||||
hfactory $scobj_hpath/control/tolerance2 plain user float
|
||||
hsetprop $scobj_hpath/control/tolerance2 units $::scobj::ls336::ls336_tempUnits
|
||||
hsetprop $scobj_hpath/control/tolerance2 units [get_param $scobj_hpath ls336_tempUnits]
|
||||
hset $scobj_hpath/control/tolerance2 $tol2
|
||||
helpNotes4user $scobj_hpath "control" "tolerance2"
|
||||
|
||||
# hfactory $scobj_hpath/lowerlimit plain mugger float
|
||||
# hsetprop $scobj_hpath/lowerlimit units $::scobj::ls336::ls336_tempUnits
|
||||
# hset $scobj_hpath/lowerlimit $::scobj::ls336::ls336_lowerlimit
|
||||
# hsetprop $scobj_hpath/lowerlimit units [get_param $scobj_hpath ls336_tempUnits]
|
||||
# hset $scobj_hpath/lowerlimit [get_param $scobj_hpath ls336_lowerlimit]
|
||||
# hfactory $scobj_hpath/upperlimit plain mugger float
|
||||
# hsetprop $scobj_hpath/upperlimit units $::scobj::ls336::ls336_tempUnits
|
||||
# hset $scobj_hpath/upperlimit $::scobj::ls336::ls336_upperlimit
|
||||
# hsetprop $scobj_hpath/upperlimit units [get_param $scobj_hpath ls336_tempUnits]
|
||||
# hset $scobj_hpath/upperlimit [get_param $scobj_hpath ls336_upperlimit]
|
||||
|
||||
# environment monitoring flags: shows if setpoints of loop 1 and 2 are in tolerance
|
||||
hfactory $scobj_hpath/emon/monMode_Lp1 plain user text
|
||||
|
||||
Reference in New Issue
Block a user