Files
sics/site_ansto/instrument/config/environment/sct_protek_common.tcl
Ferdi Franceschini 202bb2869a servlog.c
Fix month in logfile name and put date in all log file names.
sct_protek_common.tcl
Catch non-numeric readings from main multimeter display
Added support for a callbank function which is called after reportVal

sct_julabo_lh45.tcl
Clear the geterror property when getting a new reading.
Don't set the overtemp and subtemp warning limits because this can cause the julabo to alarm.
Do nothing if the setpoint hasn't been updated.
Set default settletime to 60s and the default error handler to "lazy".
Added start_temperature and end_temperature which are updated by callbacks on the histogram memory control.

sct_lakeshore_340.tcl
Set the type for the setpoint nodes to drivable
r3032 | ffr | 2010-12-02 14:03:44 +1100 (Thu, 02 Dec 2010) | 15 lines
2012-11-15 17:06:45 +11:00

152 lines
4.6 KiB
Tcl

##
# @file sct_protek_common.tcl
# @brief Gets display state from Protek 608 multimeters.
#
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
## MULTIMETER STATE FIELDS AND VALUES
###### MODES
# AUTOOFF:1/0 PULSE:1/0 MAX:1/0 PLUSPEAK:1/0 REL:1/0 RECALL:1/0 GO/NG:1/0 MINUSPER:1/0
# RS232C:1/0 PLUS:1/0 MINUS:1/0 MIN:1/0 MINUSPEAK:1/0 AVG:1/0 STORE:1/0 REF:1/0 PLUSPER:1/0
# LOBAT:1/0
###### MAIN DISPLAY
# AC1:1/0 SIGN1:1/0 DC1:1/0 PW1:1/0
# MD5:np MD4:np MD3:np MD2:np MD1:n
# M1:1/0 k1:1/0 OHM1:1/0
# u1:1/0 Hz1:1/0
# m1:1/0 V1:1/0 A1:1/0
# n1:1/0 S1:1/0 F1:1/0
# DEGC1:1/0 s1:1/0
# DEGF1:1/0
###### BAR GRAPH
# B16K:1/0 B8K:1/0 B4K:1/0 B2K:1/0 B1K:1/0
# B512:1/0 B256:1/0 B128:1/0 B64:1/0 B32:1/0
# B16:1/0 B8:1/0 B4:1/0 B2:1/0 B1:1/0 B0:1/0
###### SUB DISPLAY
# RANGE2:1/0 HOLD2:1/0 DUTY2:1/0
# CONT2:1/0 ZD2:1/0
# AC2:1/0 SIGN2:1/0 DC2:1/0
# SD5:np SD4:np SD3:np SD2:np SD1:n
# PERCENT2:1/0 dBm2:1/0
# m2:1/0 V2:1/0 A2:1/0 DEGK2:1/0
# G2:1/0 M2:1/0 k2:1/0 OHM2:1/0 Hz2:1/0
# ROTSWITCH:[0-8]
### The return values for nine bytes is undocumented,
### they are labelled as X1 to X9
# X[1-9]:?
##
# @brief Sends a state report request to the protek script context protocol handler.
proc rqStateRep {} {
sct send "STATE"
return rdStateRep
}
##
# @brief Processes state report from the protek script context protocol handler.
proc rdStateRep {} {
set stateRep [sct result]
if {[string match "ASCERR:*" $stateRep]} {
sct geterror $stateRep
# Setting oldval forces update and clears geterror on next call
sct oldval "UNKNOWN"
return idle
}
array set stateArr [split $stateRep "|:"]
if {$stateArr(AUTOOFF)} {
broadcast "PROTEK608:[sct IP]:[sct PORT] WARNING AUTO OFF IS ENABLED"
}
if {$stateArr(LOBAT)} {
broadcast "PROTEK608: LOW BATTERY WARNING"
}
if {$stateRep != [sct oldval]} {
sct update $stateRep
sct oldval $stateRep
}
return idle
}
proc rqVal {nextState} {
return $nextState
}
proc ProtekMainDisplay {protek nextState} {
if [catch {
set stateRep [hval $protek/state]
set MDpath [sct]
set scale [hval $MDpath/scale]
set offset [hval $MDpath/offset]
array set SA [split $stateRep "|:"]
if {$SA(SIGN1)} {
set sign1 "-"
} else {
set sign1 ""
}
set MDISP "$sign1$SA(MD5)$SA(MD4)$SA(MD3)$SA(MD2)$SA(MD1)"
if {[string is double $MDISP] == 0} {
error "Non-numeric reading ($MDISP) from Protek main display"
}
set MDISP [expr {$scale * $MDISP + $offset}]
set oldval [sct oldval]
if {$MDISP != $oldval} {
sct update $MDISP
sct oldval $MDISP
}
} msg ] {
return -code error "[info level 0]: $msg"
}
return $nextState
}
##
# @brief Makes a state monitor object for the protek multimeter
#
# @param name, name of object which reports main display reading
# @param IP, IP address of protek moxa box
# @param PORT, port number for protek on moxa box
# @param scale, scales reading to physical units
# @param offset, offset for main display reading
# @param interval, polling interval in seconds (optional, default = 0.5seconds)
# @param cbFunc, this function will be called after the voltage reading has been updated
# NOTE: If the interval is negative then the multimeter will be polled on every cycle of
# the SICS task loop.
proc MakeProtek {name IP PORT {scale 1.0} {offset 0.0} {interval 0.5} {cbFunc "return idle"}} {
set sctName "sct_$name"
set sobjName "$name"
set soState "so_state_$name"
puts "MakeSICSObj $sobjName SCT_OBJECT"
MakeSICSObj $soState SCT_OBJECT
MakeSICSObj $sobjName SCT_OBJECT user float
sicslist setatt $sobjName long_name $sobjName
hfactory /sics/$soState/state plain user text
hsetprop /sics/$soState/state read rqStateRep
hsetprop /sics/$soState/state rdStateRep rdStateRep
hsetprop /sics/$soState/state oldval "UNKNOWN"
hsetprop /sics/$sobjName read rqVal "reportVal"
hsetprop /sics/$sobjName reportVal ProtekMainDisplay /sics/$soState callBack
hsetprop /sics/$sobjName callBack $cbFunc
hfactory /sics/$sobjName/scale plain user float
hset /sics/$sobjName/scale $scale
hfactory /sics/$sobjName/offset plain user float
hset /sics/$sobjName/offset $offset
hsetprop /sics/$sobjName oldval "UNKNOWN"
sicslist setatt $sobjName klass sample
::scobj::hinitprops $sobjName
sicslist setatt $sobjName long_name $name
if {[SplitReply [environment_simulation]] == false} {
makesctcontroller $sctName protek608 $IP:$PORT
hsetprop /sics/$soState/state IP $IP
hsetprop /sics/$soState/state PORT $PORT
$sctName poll /sics/$soState/state $interval
$sctName poll /sics/$sobjName $interval
}
return /sics/$sobjName
}