Files
sics/site_ansto/instrument/config/environment/sct_keithley_2700.tcl
Ferdi Franceschini d7acb7c16c Load drivers which have been enabled in the SICS config ini files.
Lakeshore 336 drivers with known IP addresses have been added to the ini files with unique IDs.
All entries in the ini files now have unique IDs
The wombat ini now has radio buttons to select sample stage motor configurations.
2014-05-05 12:25:00 +10:00

706 lines
25 KiB
Tcl

# Define procs in ::scobj::xxx namespace
# MakeSICSObj $obj SCT_<class>
# The MakeSICSObj cmd adds a /sics/$obj node. NOTE the /sics node is not browsable.
# Moxa RS232 configuration
# Port 3
# Baud rate : 9600
# Data bits : 8
# Stop bits : 1
# Parity : None
# Flow control : XON/XOFF
# FIFO : Enable
# Interface : RS-232
namespace eval ::scobj::k2700 {
# Environment controllers should have at least the following nodes
# /envcont/setpoint
# /envcont/sensor/value
proc debug_log {args} {
set fd [open "/tmp/k2700.log" a]
puts $fd "[clock format [clock seconds] -format "%T"] $args"
close $fd
}
# issue a command to read a register and expect a value response
proc getValue {tc_root nextState cmd} {
debug_log "getValue $cmd sct=[sct] root=$tc_root nextState=$nextState"
sct send "$cmd"
return $nextState
}
proc rdParm {tc_root} {
debug_log "rdParm tc_root=$tc_root sct=[sct]"
set data [sct result]
if {[ catch {
debug_log "rdParm $tc_root [sct] result=$data"
} catch_message ]} {
debug_log "rdParm $tc_root failure"
}
if {[string equal -nocase -length 7 $data "ASCERR:"]} {
sct geterror "$data"
set nextState idle
} elseif {[string equal -nocase -length 1 $data "?"]} {
sct geterror "Error: $data"
set nextState idle
} else {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
debug_log "rdParm Read: $data"
if {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
debug_log "rdParm new data for $tc_root [sct] result=$data"
}
}
return idle
}
proc rdText {tc_root} {
debug_log "rdText tc_root=$tc_root sct=[sct]"
set data [sct result]
if {[ catch {
debug_log "rdText $tc_root [sct] result=$data"
} catch_message ]} {
debug_log "rdText $tc_root failure"
}
if {[string equal -nocase -length 7 $data "ASCERR:"]} {
sct geterror "$data"
set nextState idle
} elseif {[string equal -nocase -length 1 $data "?"]} {
sct geterror "Error: $data"
set nextState idle
} else {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
debug_log "rdText Read: $data"
if {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
debug_log "rdText new data for $tc_root [sct] result=$data"
}
}
return idle
}
proc rdValue {tc_root} {
debug_log "rdValue tc_root=$tc_root sct=[sct]"
set data [sct result]
if {[ catch {
debug_log "rdValue $tc_root [sct] result=$data"
} catch_message ]} {
debug_log "rdValue $tc_root failure"
}
if {[string equal -nocase -length 7 $data "ASCERR:"]} {
sct geterror "$data"
set nextState idle
} elseif {[string equal -nocase -length 1 $data "?"]} {
sct geterror "Error: $data"
set nextState idle
} else {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
if {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
debug_log "rdValue new data for $tc_root [sct] result=$data"
}
}
return idle
}
proc rdData {tc_root} {
debug_log "rdData tc_root=$tc_root sct=[sct]"
set data [sct result]
if {[ catch {
debug_log "rdData $tc_root [sct] result=$data"
} catch_message ]} {
debug_log "rdData $tc_root failure"
}
if {[string equal -nocase -length 7 $data "ASCERR:"]} {
sct geterror "$data"
set nextState idle
} elseif {[string equal -nocase -length 1 $data "?"]} {
sct geterror "Error: $data"
set nextState idle
} else {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set flds [split "$data" ","]
scan [lindex $flds 0] "%f%s" value units
debug_log "rdData Read: $value $units from $data"
if {$value != [sct oldval]} {
sct oldval $value
sct update $value
sct utime readtime
sct units $units
debug_log "rdData new data for $tc_root [sct] result=$value"
}
}
return idle
}
proc wrParm {tc_root nextState cmd} {
debug_log "wrParm root=$tc_root sct=[sct] cmd=$cmd target=[sct target]"
set par "[sct target]"
sct send "$cmd $par"
debug_log "wrParm send: $cmd $par;*IDN?"
if {$par != [sct oldval]} {
sct oldval $par
sct update $par
sct utime readtime
debug_log "wrParm new data for $tc_root [sct] result=$par"
}
return $nextState
}
proc wrText {tc_root nextState cmd} {
debug_log "wrText root=$tc_root sct=[sct] cmd=$cmd target=[sct target]"
set par "[sct target]"
sct send "$cmd \"$par\";*IDN?"
debug_log "wrText send: $cmd \"$par\""
if {$par != [sct oldval]} {
sct oldval $par
sct update $par
sct utime readtime
debug_log "wrText new data for $tc_root [sct] result=$par"
}
return $nextState
}
# issue a command with a value in the target property of the variable
proc wrValue {tc_root nextState cmd} {
debug_log "wrValue root=$tc_root sct=[sct] cmd=$cmd target=[sct target]"
set par "[sct target]"
sct send "$cmd $par;*IDN?"
debug_log "wrValue send: $cmd $par"
if {$par != [sct oldval]} {
sct oldval $par
sct update $par
sct utime readtime
debug_log "wrValue new data for $tc_root [sct] result=$par"
}
return $nextState
}
proc wrFunc {tc_root nextState cmd} {
debug_log "wrFunc root=$tc_root sct=[sct] cmd=$cmd target=[sct target]"
set par "[sct target]"
if {[hpropexists [sct] values]} {
set target {}
set values [split [SplitReply [hgetprop [sct] values]] ","]
foreach value $values {
sct print "Testing $par against $value"
if {[string toupper "$par"] == [string toupper "$value"]} {
set target "$par"
break
}
}
if {"$target" == ""} {
return -code error "Invalid value: \"$par\""
}
}
sct send "$cmd '$par';*IDN?"
debug_log "wrFunc send: $cmd '$par'"
if {$par != [sct oldval]} {
sct oldval $par
sct update $par
sct utime readtime
debug_log "wrFunc new data for $tc_root [sct] result=$par"
}
return $nextState
}
proc wrNode {tc_root cmd level} {
set space [string repeat " " $level]
set val [hval $tc_root]
if {"$val" == ""} {
set line "$tc_root ([hinfo $tc_root])"
} else {
set line "$tc_root ([hinfo $tc_root]) = $val"
}
sct print "$space* $line"
if {"[string tolower "$cmd"]" == "-prop"} {
set props [hlistprop $tc_root]
#sct print "<<$props>>"
foreach prop $props {
#sct print "prop: $prop"
set flds [split $prop "="]
#sct print "flds: $flds"
if {[llength $flds] > 1} {
set fld0 [lindex $flds 0]
#sct print "fld0: $fld0"
if {[hpropexists $tc_root $fld0]} {
sct print "$space - [hgetprop $tc_root $fld0]"
}
}
}
}
foreach node [hlist $tc_root] {
wrNode $tc_root/$node "$cmd" [expr {$level + 1}]
}
}
proc wrTree {tc_root nextState cmd} {
debug_log "wrTree root=$tc_root sct=[sct] cmd=$cmd target=[sct target]"
sct print "$tc_root"
wrNode $tc_root "[sct target]" 1
return idle
}
proc chkWrite {tc_root} {
set data [sct result]
debug_log "chkWrite resp=$data sct=[sct] tc_root=$tc_root"
if {[string equal -nocase -length 7 $data "ASCERR:"]} {
sct geterror "$data"
} elseif {[string equal -nocase -length 1 $data "?"]} {
sct geterror "Error: $data"
} else {
set data [sct target]
if {$data != [sct oldval]} {
sct oldval $data
sct update $data
sct utime readtime
debug_log "chkWrite new data for $tc_root [sct] result=$data"
}
}
return idle
}
proc setPoint {tc_root nextState cmd} {
set catch_status [ catch {
debug_log "setPoint $tc_root $nextState $cmd sct=[sct]"
debug_log "setPoint: sct=[sct] target=[sct target] writestatus=[sct writestatus]"
sct print "setPoint: sct=[sct] target=[sct target] writestatus=[sct writestatus]"
set err_msg ""
if { $err_msg != "" } {
sct print "error:$err_msg"
debug_log "error:$err_msg"
return -code error "$err_msg"
}
set par "[sct target]"
if {[sct writestatus] == "start"} {
# Called by drive adapter
hset $tc_root/status "busy"
hsetprop $tc_root/setpoint driving 1
}
if {$par != [sct oldval]} {
sct oldval $par
sct update $par
sct utime readtime
debug_log "setPoint new data for $tc_root [sct] result=$par"
}
hset $tc_root/status "busy"
sct print "status: busy"
hset $tc_root/drive_state "START"
} catch_message ]
if {$catch_status != 0} {
hsetprop $tc_root/setpoint driving 0
return -code error $catch_message
}
sct print "setPoint: [hget $tc_root/drive_state]"
return $nextState
}
# This is the command phase of the state machine that drives the controller.
# For each state, it sends the appropriate command to get values from, or set
# values in the controller in a sequence intended to transition the controller
# between states.
proc getState {tc_root nextState cmd} {
set my_state "[SplitReply [hgetprop $tc_root/device_state my_state]]"
debug_log "getState $tc_root $nextState $cmd sct=[sct] state=$my_state"
if {[ catch {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
if {$my_state == "STATE_INIT"} {
set my_cmd "SYSTEM:PRESET;*IDN?"
hsetprop $tc_root/device_state my_state "STATE_IDN"
set nextState read
} elseif {$my_state == "STATE_IDN"} {
set my_cmd "*IDN?"
} elseif {$my_state == "STATE_CHNL_SET"} {
set my_cmd "SENS:FUNC \"VOLTS:DC\";*IDN?"
set mmf [hval $tc_root/Control/MMF]
set mbf [hval $tc_root/Control/MBF]
set mun [hval $tc_root/Control/MUN]
set my_cmd "CALC:FORM MXB;CALC:KMAT:MMF 1.0;CALC:KMAT:MBF 0.0;CALC:KMAT:MUN \"X\";CALC:STAT ON"
hsetprop $tc_root/device_state my_state "STATE_CHNL_GET"
set nextState read
} elseif {$my_state == "STATE_CHNL_GET"} {
set my_cmd "CALC:STAT?"
} elseif {$my_state == "STATE_FIELD"} {
set my_cmd "FETCH?"
} else {
hsetprop $tc_root/device_state my_state "STATE_IDN"
set my_cmd "*IDN?"
}
sct send "$my_cmd"
debug_log "getState end $tc_root state=$my_state, cmd=$my_cmd"
} catch_message ]} {
debug_log "getState error: $catch_message"
}
set old_state $my_state
set new_state "[SplitReply [hgetprop $tc_root/device_state my_state]]"
if {"$new_state" != "$old_state"} {
debug_log "getState change $old_state to $new_state"
}
debug_log "getState returns: $nextState"
return $nextState
}
# This is the response phase of the state machine that drives the controller.
# For each state, it reads the appropriate command response from the controller
# and, based on the response and internal variables performs a sequence
# intended to transition the controller between states.
##
# @brief Reads the current k2700 state and error messages.
proc rdState {tc_root} {
set my_state "[SplitReply [hgetprop $tc_root/device_state my_state]]"
debug_log "rdState $tc_root sct=[sct] state=$my_state response=\"[sct result]\""
set nextState {}
if {[ catch {
if { [hpropexists [sct] geterror] } {
hdelprop [sct] geterror
}
set data "[sct result]"
if {[string equal -nocase -length 7 $data "ASCERR:"]} {
sct geterror "$data"
set nextState idle
} elseif {[string equal -nocase -length 1 $data "?"]} {
sct geterror "Error: $data"
set nextState idle
} else {
debug_log "rdState $tc_root state=$my_state, response=\"[sct result]\""
if {$my_state == "STATE_INIT"} {
hsetprop $tc_root/device_state my_state "STATE_IDN"
set nextState read
} elseif {$my_state == "STATE_IDN"} {
set my_version "[sct result]"
hsetprop $tc_root/device_state my_version "$my_version"
hsetprop $tc_root/device_state my_state "STATE_CHNL_SET"
set nextState read
} elseif {$my_state == "STATE_CHNL_SET"} {
hsetprop $tc_root/device_state my_state "STATE_CHNL_GET"
set nextState read
} elseif {$my_state == "STATE_CHNL_GET"} {
hsetprop $tc_root/device_state my_state "STATE_FIELD"
hsetprop [sct] chnl [sct result]
set nextState read
} elseif {$my_state == "STATE_FIELD"} {
set my_driving [SplitReply [hgetprop $tc_root/setpoint driving]]
if { $my_driving } {
set my_sp [hval $tc_root/setpoint]
set my_pv [hval $tc_root/display/value]
set my_tol [SplitReply [hgetprop $tc_root/setpoint tolerance]]
if {$my_sp - $my_tol < $my_sp + $my_tol} {
set my_lo_tol [expr {$my_sp - $my_tol}]
} else {
set my_lo_tol [expr {$my_sp + $my_tol}]
}
if {$my_sp - $my_tol > $my_sp + $my_tol} {
set my_hi_tol [expr {$my_sp - $my_tol}]
} else {
set my_hi_tol [expr {$my_sp + $my_tol}]
}
debug_log "rdState Testing: ($my_lo_tol <= $my_pv <= $my_hi_tol) = [expr {($my_lo_tol <= $my_pv && $my_pv <= $my_hi_tol)}]"
if {($my_lo_tol <= $my_pv && $my_pv <= $my_hi_tol)} {
hsetprop $tc_root/setpoint driving 0
}
}
hsetprop $tc_root/device_state my_state "STATE_FIELD"
set nextState idle
}
}
if { $nextState == "" } {
set nextState idle
}
} catch_message ]} {
debug_log "rdState error: $catch_message"
}
set old_state $my_state
set new_state "[SplitReply [hgetprop $tc_root/device_state my_state]]"
if {"$new_state" != "$old_state"} {
debug_log "rdState change $old_state to $new_state"
}
if { "$nextState" == "" } {
set nextState "idle"
}
debug_log "rdState returns: $nextState"
return $nextState
}
proc noResponse {} {
return idle
}
proc wrtValue {wcmd args} {
}
# check that a target is within allowable limits
proc check {tc_root} {
return OK
}
# Check that the sensor is reading within tolerance of the setpoint.
# Return 1 or 0 if it is or is not, respectively.
proc checktol {tc_root currtime timecheck} {
debug_log "checktol $tc_root $currtime $timecheck"
return 1
}
##
# @brief Implement the checkstatus command for the drivable interface
#
# NOTE: The drive adapter initially sets the writestatus to "start" and will
# only call this when writestatus!="start"
proc drivestatus {tc_root} {
if {[sct driving]} {
return busy
} else {
sct print "drivestatus: idle"
hset $tc_root/status "idle"
return idle
}
}
proc halt {tc_root} {
debug_log "halt $tc_root"
sct print "halt $tc_root"
set my_driving [SplitReply [hgetprop $tc_root/setpoint driving]]
hset $tc_root/drive_state "HALT"
hsetprop $tc_root/device_state my_state "STATE_X"
if { $my_driving } {
hsetprop $tc_root/device_state my_state "STATE_A0"
return read
}
return idle
}
##
# @brief createNode() creates a node for the given nodename with the properties and virtual
# function names provided
# @param scobj_hpath string variable holding the path to the object's base node in sics (/sample/tc1)
# @param sct_controller name of the scriptcontext object (typically sct_xxx_yyy)
# @param cmdGroup subdirectory (below /sample/tc*/) in which the node is to be created
# @param varName name of the actual node typically representing one device command
# @param readable set to 1 if the node represents a query command, 0 if it is not
# @param writable set to 1 if the node represents a request for a change in settings sent to the device
# @param drivable if set to 1 it prepares the node to provide a drivable interface
# @param dataType data type of the node, must be one of none, int, float, text
# @param permission defines what user group may read/write to this node (is one of spy, user, manager)
# @param rdCmd actual device query command to be sent to the device
# @param rdFunc nextState Function to be called after the getValue function, typically rdValue()
# @param wrCmd actual device write command to be sent to the device
# @param wrFunc Function to be called to send the wrCmd to the device, typically wrValue()
# @param allowedValues allowed values for the node data - does not permit other
# @param klass Nexus class name (?)
# @return OK
proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable\
drivable dataType permission rdCmd rdFunc wrCmd\
wrFunc allowedValues klass} {
set catch_status [ catch {
# set ns ::scobj::k2700
set ns "[namespace current]"
set nodeName "$scobj_hpath/$cmdGroup/$varName"
if {1 > [string length $cmdGroup]} {
set nodeName "$scobj_hpath/$varName"
}
debug_log "Creating node $nodeName"
hfactory $nodeName plain $permission $dataType
if {$readable > 0} {
hsetprop $nodeName read ${ns}::getValue $scobj_hpath $rdFunc $rdCmd
hsetprop $nodeName $rdFunc ${ns}::$rdFunc $scobj_hpath
set poll_period 30
if { $readable >= 0 && $readable <= 9 } {
set poll_period [lindex [list 0 1 2 3 4 5 10 15 20 30] $readable]
}
debug_log "Registering node $nodeName for poll at $poll_period seconds"
$sct_controller poll $nodeName $poll_period
}
if {$writable == 1} {
set parts [split "$wrFunc" "."]
if { [llength $parts] == 2 } {
set func_name [lindex $parts 0]
set next_state [lindex $parts 1]
hsetprop $nodeName write ${ns}::$func_name $scobj_hpath $next_state $wrCmd
hsetprop $nodeName $next_state ${ns}::$next_state $scobj_hpath
} else {
hsetprop $nodeName write ${ns}::$wrFunc $scobj_hpath noResponse $wrCmd
hsetprop $nodeName noResponse ${ns}::noResponse
}
hsetprop $nodeName writestatus UNKNOWN
debug_log "Registering node $nodeName for write callback"
$sct_controller write $nodeName
}
switch -exact $dataType {
"none" { }
"int" { hsetprop $nodeName oldval -1 }
"float" { hsetprop $nodeName oldval -1.0 }
default { hsetprop $nodeName oldval UNKNOWN }
}
if {1 < [string length $allowedValues]} {
hsetprop $nodeName values $allowedValues
}
# Drive adapter interface
if {$drivable == 1} {
hsetprop $nodeName check ${ns}::check $scobj_hpath
hsetprop $nodeName driving 0
hsetprop $nodeName checklimits ${ns}::check $scobj_hpath
hsetprop $nodeName checkstatus ${ns}::drivestatus $scobj_hpath
hsetprop $nodeName halt ${ns}::halt $scobj_hpath
}
} message ]
if {$catch_status != 0} {
return -code error "in createNode $message"
}
return OK
}
proc mk_sct_keithley_2700 {sct_controller klass tempobj tol CID CTYPE} {
set catch_status [ catch {
# set ns ::scobj::k2700
set ns "[namespace current]"
MakeSICSObj $tempobj SCT_OBJECT
sicslist setatt $tempobj klass $klass
sicslist setatt $tempobj long_name $tempobj
set scobj_hpath /sics/$tempobj
# Group Node R W D type perm rdCmd rdFunc wrCmd wrFunc allowed
set deviceCommand {\
Control Function 1 1 0 text user {SENS:FUNC?} {rdText} {SENS:FUNC} {wrFunc} {VOLT:DC,VOLT:AC,CURR:DC,CURR:AC,RES,FRES,CONT,FREQ,PER}\
Control Math 1 1 0 text user {CALC1:FORM?} {rdParm} {CALC1:FORM} {wrParm} {MXB}\
Control MMF 1 1 0 float user {CALC1:KMAT:MMF?} {rdValue} {CALC1:KMAT:MMF} {wrValue} {}\
Control MBF 1 1 0 float user {CALC1:KMAT:MBF?} {rdValue} {CALC1:KMAT:MBF} {wrValue} {}\
Control MUN 1 1 0 text user {CALC1:KMAT:MUN?} {rdText} {CALC1:KMAT:MUN} {wrText} {}\
Control Stat 1 1 0 text user {CALC1:STAT?} {rdParm} {CALC1:STAT} {wrParm} {ON,OFF}\
Display Value 1 0 0 float internal {FETCH?} {rdData} {} {} {}\
{} Setpoint 0 1 1 float user {} {} {} {setPoint} {}\
Display Tree 0 1 0 text user {} {} {} {wrTree} {}\
}
hfactory $scobj_hpath/Control plain spy none
hfactory $scobj_hpath/Display plain spy none
foreach {cmdGroup varName readable writable drivable dataType permission rdCmd rdFunc wrCmd wrFunc allowedValues} $deviceCommand {
createNode $scobj_hpath $sct_controller $cmdGroup $varName $readable $writable $drivable $dataType $permission $rdCmd $rdFunc $wrCmd $wrFunc $allowedValues $klass
}
hfactory $scobj_hpath/status plain spy text
hset $scobj_hpath/status "idle"
hsetprop $scobj_hpath/status values busy,idle
hfactory $scobj_hpath/device_state plain spy text
hsetprop $scobj_hpath/device_state read ${ns}::getState $scobj_hpath rdState "X"
hsetprop $scobj_hpath/device_state rdState ${ns}::rdState $scobj_hpath
hsetprop $scobj_hpath/device_state oldval "UNKNOWN"
hsetprop $scobj_hpath/device_state my_state "STATE_FIELD"
hsetprop $scobj_hpath/device_state my_status "UNKNOWN"
hsetprop $scobj_hpath/device_state my_version "UNKNOWN"
hfactory $scobj_hpath/drive_state plain mugger text
hset $scobj_hpath/drive_state "UNKNOWN"
hfactory $scobj_hpath/remote_ctrl plain spy text
hset $scobj_hpath/remote_ctrl "UNKNOWN"
hfactory $scobj_hpath/device_lasterror plain user text
hset $scobj_hpath/device_lasterror ""
hsetprop $scobj_hpath/setpoint tolerance $tol
hsetprop $scobj_hpath/setpoint permlink data_set ${CTYPE}${CID}SP1
if {[SplitReply [environment_simulation]]=="false"} {
$sct_controller poll $scobj_hpath/device_state 1 halt read
}
hsetprop $scobj_hpath type part
foreach snsr {Display} {
foreach {rootpath hpath klass priv} "\
$scobj_hpath $snsr NXsensor spy\
$scobj_hpath $snsr/Value sensor user\
" {
hsetprop $rootpath/$hpath klass $klass
hsetprop $rootpath/$hpath privilege $priv
hsetprop $rootpath/$hpath control true
hsetprop $rootpath/$hpath data true
hsetprop $rootpath/$hpath nxsave true
}
hsetprop $scobj_hpath/$snsr type part
hsetprop $scobj_hpath/$snsr/value nxalias mm1_${snsr}_value
hsetprop $scobj_hpath/$snsr/value mutable true
hsetprop $scobj_hpath/$snsr/value sdsinfo ::nexus::scobj::sdsinfo
hsetprop $scobj_hpath/$snsr/value permlink data_set ${CTYPE}${CID}S1
}
hsetprop $scobj_hpath privilege spy
::scobj::hinitprops $tempobj setpoint
if {[SplitReply [environment_simulation]]=="false"} {
ansto_makesctdrive ${tempobj}_driveable $scobj_hpath/setpoint $scobj_hpath/display/value $sct_controller
}
} catch_message ]
if {$catch_status != 0} {
return -code error $catch_message
}
}
namespace export mk_sct_keithley_2700
}
##
# @brief Create a Keithley 2700 Multimeter
#
# @param name, the name of the multimeter (eg mm1)
# @param IP, the IP address of the device, this can be a hostname, (eg ca1-kowari)
# @param port, the IP protocol port number of the device
proc add_k2700 {name IP port terminator {_tol 1.0} {CID 1} {CTYPE V} } {
set fd [open "/tmp/k2700.log" a]
if {[SplitReply [environment_simulation]]=="false"} {
puts $fd "makesctcontroller sct_k2700 std ${IP}:$port"
makesctcontroller sct_k2700 std ${IP}:$port $terminator
}
puts $fd "mk_sct_keithley_2700 sct_k2700 environment $name $_tol"
mk_sct_keithley_2700 sct_k2700 environment $name $_tol $CID $CTYPE
close $fd
}
puts stdout "file evaluation of sct_keithley_2700.tcl"
set fd [open "/tmp/k2700.log" w]
puts $fd "file evaluation of sct_keithley_2700.tcl"
close $fd
if {[ catch {
if { [ info exists ::config_dict ] } {
dict for {secname secinfo} $::config_dict {
if { [dict exists $secinfo "driver"] && ([dict get $secinfo "driver"] == "k2700") } {
if { [ dict get $::secinfo enabled ] } {
set name [dict get $::secinfo name]
set IP [dict get $::secinfo ip]
set PORT [dict get $::secinfo port]
set term [dict get $::secinfo terminator]
set tol [dict get $::secinfo tol]
set cid [dict get $::secinfo id]
set ctype [dict get $::secinfo type]
add_k2700 $name $IP $PORT $term $tol $cid $ctype
}
}
}
}
} message ]} {
puts "ERROR: $message"
}
namespace import ::scobj::k2700::*