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:
Douglas Clowes
2011-08-22 11:30:20 +10:00
parent 89bfef55b0
commit c765c33f6d

View File

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