380 lines
9.2 KiB
Tcl
380 lines
9.2 KiB
Tcl
# temperature reading out commented (search for: tt) 6.5.13
|
|
|
|
#----- Keithley electrometer
|
|
|
|
proc kthLayout args {
|
|
Group kth "Keithley 6517B"
|
|
}
|
|
|
|
proc kthMake {host {interval 1}} {
|
|
kth_make kth $host $interval
|
|
Layout kth
|
|
catch {
|
|
kth time0 0.5
|
|
kth time 7
|
|
kth rate 33
|
|
kth sigma 1
|
|
}
|
|
obj_list makeitem kth Keithley6517B
|
|
desc_env makeitem kth Keithley6517B
|
|
hsetprop /sics/kth objectPath /kth
|
|
}
|
|
|
|
proc kthGroup {} {
|
|
showStatus kth
|
|
Input Volt "kth volt"
|
|
CheckBox "Voltage Output" "kth output"
|
|
Newline
|
|
Input "kth Current Range A" "kth crange"
|
|
CheckBox "Autorange" "kth autorange"
|
|
Newline
|
|
Input "Time before Step" "kth time0"
|
|
Input "Time after Step" "kth time"
|
|
Input "Single Measurement Command" "kth measure"
|
|
Newline
|
|
Input "Datafile Path" "kth file" 32
|
|
Input "Ramp Step" "kth rampstep"
|
|
Input "Ramp to Volt" "kth rampto"
|
|
}
|
|
|
|
# -- send command
|
|
|
|
#write action
|
|
proc kth_start_send {} {
|
|
set cmd [sct target]
|
|
if {[string first ? $cmd] <= 0} {
|
|
set pos [string first " " $cmd]
|
|
if {$pos > 0} {
|
|
incr pos -1
|
|
set qcmd [string range $cmd 0 $pos]
|
|
sct send "$cmd;$qcmd?"
|
|
return kth_complete_send
|
|
}
|
|
}
|
|
sct send $cmd
|
|
return kth_complete_send
|
|
}
|
|
|
|
#write action, direct
|
|
proc kth_complete_send {} {
|
|
sct print "response = [sct result]"
|
|
sct update "[sct target]"
|
|
return idle
|
|
}
|
|
|
|
#config script
|
|
proc kth_make_send {path controller} {
|
|
hfactory $path/send plain user text
|
|
$controller write $path/send
|
|
hsetprop $path/send write kth_start_send
|
|
hsetprop $path/send visible false
|
|
}
|
|
|
|
#general error script
|
|
proc kth_error_script {} {
|
|
set s [split [sct result] :]
|
|
if {[string equal ASCERR [lindex $s 0]]} {
|
|
set s [lreplace $s 0 0]
|
|
}
|
|
set s [join $s :]
|
|
[sct controllerName] poll [sct tasksPath] 1 start start
|
|
error $s
|
|
}
|
|
|
|
#start action
|
|
proc kth_start {} {
|
|
sct send ":FORM:ELEM READ,TST;*IDN?"
|
|
return kth_start_idn
|
|
}
|
|
|
|
#start action, direct
|
|
proc kth_start_idn {} {
|
|
set idn [sct result]
|
|
if {! [string equal -length 8 KEITHLEY $idn]} {
|
|
sct send "*IDN?"
|
|
return kth_start_idn
|
|
}
|
|
sct idn $idn
|
|
sct print "connected to $idn"
|
|
return unpoll
|
|
}
|
|
|
|
#read action
|
|
proc kth_read {cmd} {
|
|
sct send $cmd
|
|
return update
|
|
}
|
|
|
|
#read action, update state
|
|
proc kth_update {{idx 0}} {
|
|
set r [lindex [split [sct result] ,] $idx]
|
|
sct update $r
|
|
return idle
|
|
}
|
|
|
|
#read action, update state
|
|
proc kth_update_pico {} {
|
|
set r [lindex [split [sct result] ,] 0]
|
|
sct update [expr $r * 1.0e12]
|
|
return idle
|
|
}
|
|
|
|
#config script
|
|
proc kth_rdonly {name queryCmd {skip 0} {interval 5}} {
|
|
global kth
|
|
|
|
if {[string equal "" $name]} {
|
|
set node $kth(path)
|
|
} else {
|
|
set node $kth(path)/name
|
|
hfactory $node plain internal float
|
|
}
|
|
logsetup $node
|
|
$kth(controller) poll $node $interval
|
|
hsetprop $node read kth_read $queryCmd
|
|
hsetprop $node update kth_update $skip
|
|
}
|
|
|
|
#write action
|
|
proc kth_write {queryCmd} {
|
|
set pos [string first ? $queryCmd]
|
|
if {$pos < 1} {
|
|
error "kth: queryCmd has no question mark"
|
|
}
|
|
set setcmd [string replace [string trim $queryCmd] $pos $pos " "]
|
|
sct send "$setcmd[sct target];$queryCmd"
|
|
return complete
|
|
}
|
|
|
|
#config script
|
|
proc kth_combi {name access queryCmd {idx 0}} {
|
|
global kth
|
|
|
|
set node $kth(path)/$name
|
|
hfactory $node plain $access float
|
|
logsetup $node
|
|
$kth(controller) write $node
|
|
hsetprop $node write kth_write $queryCmd
|
|
hsetprop $node complete kth_update $idx
|
|
$kth(controller) poll $node 10 slow
|
|
hsetprop $node read kth_read $queryCmd
|
|
hsetprop $node update kth_update $idx
|
|
}
|
|
|
|
#write action
|
|
proc kth_measure {} {
|
|
set o [sct objectPath]
|
|
set rate [hvali $o/rate]
|
|
set p0 [expr int([hvali $o/time0] * $rate + 1)]
|
|
set p1 [expr int([hvali $o/time] * $rate + 1)]
|
|
if {$p0 + $p1 >= 200} {
|
|
sct nbg [expr ($p0 + $p1)/200]
|
|
set p1 [expr 200 - $p0]
|
|
} else {
|
|
sct nbg 0
|
|
}
|
|
sct firstrun 1
|
|
sct p1 $p1
|
|
sct p0 $p0
|
|
set step [sct target]
|
|
set ovolt [hvali $o/volt]
|
|
sct ovolt $ovolt
|
|
set volt [expr $ovolt + $step]
|
|
sct volt $volt
|
|
sct send "[string repeat ":data?;" $p0]:source:volt $volt[string repeat ";:data?" $p1]"
|
|
# sct send "[string repeat ":read?;" $p0]:source:volt $volt[string repeat ";:read?" $p1]"
|
|
sct print "measure $ovolt => $volt"
|
|
return kth_complete_measure
|
|
}
|
|
|
|
proc kth_filename {path} {
|
|
set num 1
|
|
catch {
|
|
set fil [open $path/datanumber.txt r]
|
|
gets $fil num
|
|
close $fil
|
|
}
|
|
incr num
|
|
set fil [open $path/datanumber.tmp w]
|
|
puts $fil $num
|
|
puts $fil "^ this is the highest data file number used"
|
|
puts $fil "delete or modify this file if you want to overwrite data files"
|
|
close $fil
|
|
file rename -force $path/datanumber.tmp $path/datanumber.txt
|
|
return $path/data[format "%.4d" $num].txt
|
|
}
|
|
|
|
#complete action
|
|
proc kth_complete_measure {} {
|
|
global kth
|
|
|
|
set o [sct objectPath]
|
|
set rl [split [sct result] ";"]
|
|
set p0 [sct p0]
|
|
set p1 [sct p1]
|
|
set Temperature [result tt ts]
|
|
|
|
if {[sct firstrun]} {
|
|
set dl [split [lindex $rl $p0] ,]
|
|
set kth(t0) [lindex $dl 1]
|
|
set kth(filename) [kth_filename [hvali $o/file]]
|
|
set fil [open $kth(filename) w]
|
|
puts $fil "#time value dummySigma voltage=[sct volt] T= [expr $Temperature] "
|
|
# puts $fil "#time value dummySigma voltage=[sct volt]"
|
|
sct firstrun 0
|
|
} else {
|
|
set fil [open $kth(filename) a]
|
|
}
|
|
set last 0
|
|
foreach d $rl {
|
|
set dl [split $d ,]
|
|
set t [lindex $dl 1]
|
|
set y [expr [lindex $dl 0] * 1.0e12]
|
|
if {$t != $last && abs($y) < 1.0e12} {
|
|
set last $t
|
|
puts $fil "[expr $t - $kth(t0)] $y [hvali $o/sigma] [sct volt] $Temperature "
|
|
}
|
|
}
|
|
close $fil
|
|
if {[sct nbg] <= 0} {
|
|
sct print "$kth(filename) written"
|
|
hupdate $o/volt [sct volt]
|
|
sct update [sct target]
|
|
return idle
|
|
}
|
|
sct nbg [expr [sct nbg] - 1]
|
|
sct send "[string repeat ":data?;" 200]:data?"
|
|
sct print "$kth(filename) - measure background"
|
|
return kth_complete_measure
|
|
}
|
|
|
|
proc kth_rampto {} {
|
|
set o [sct objectPath]
|
|
set volt [hvali $o/volt]
|
|
set diff [expr [sct target] - $volt]
|
|
if {$diff == 0} {
|
|
sct print "we are already at [sct target] volt"
|
|
return unpoll
|
|
}
|
|
set rampstep [expr abs([hvali $o/rampstep])]
|
|
if {$diff < 0} {
|
|
set rampstep -$rampstep
|
|
}
|
|
[sct controllerName] poll [sct] 1 progress progress
|
|
sct progress kth_progress
|
|
sct print "start ramp to [sct target]"
|
|
sct update [sct target]
|
|
hset $o/measure $rampstep
|
|
return idle
|
|
}
|
|
|
|
proc kth_progress {} {
|
|
set o [sct objectPath]
|
|
set volt [hvali $o/volt]
|
|
set diff [expr [sct target] - $volt]
|
|
if {abs($diff) < 0.001} {
|
|
return unpoll
|
|
}
|
|
if {$volt == [hgetpropval $o/measure volt]} {
|
|
set rampstep [expr abs([hvali $o/rampstep])]
|
|
if {$diff > 0} {
|
|
if {$volt + $rampstep >= [sct target]} {
|
|
set rampstep [expr [sct target] - $volt]
|
|
}
|
|
} else {
|
|
set rampstep -$rampstep
|
|
if {$volt + $rampstep <= [sct target]} {
|
|
set rampstep [expr [sct target] - $volt]
|
|
}
|
|
}
|
|
hset $o/measure $rampstep
|
|
}
|
|
return idle
|
|
}
|
|
|
|
proc kth_make {objectName host {interval 1}} {
|
|
global kth
|
|
|
|
clientput "kth_make $objectName $host $interval"
|
|
set controllerName ctrl_$objectName
|
|
makesctcontroller $controllerName std $host "\r" 20
|
|
set path /$objectName
|
|
set kth(path) $path
|
|
set kth(controller) $controllerName
|
|
|
|
hfactory $path plain user float
|
|
dynsctdriveobj $objectName $path K6517B $controllerName
|
|
|
|
hfactory $path/controller link $controllerName
|
|
|
|
hfactory $path/tasks plain user none
|
|
hsetprop $path/tasks start kth_start
|
|
hsetprop $path/tasks visible false
|
|
|
|
hsetprop $path/controller idn empty
|
|
hsetprop $path/controller visible false
|
|
hsetprop $path/controller tasksPath $path/tasks
|
|
hsetprop $path/controller objectPath $path
|
|
hsetprop $path/controller objectName $objectName
|
|
hsetprop $path/controller state idle
|
|
hsetprop $path/controller commerror kth_error_script
|
|
|
|
kth_make_send $path $controllerName
|
|
$controllerName queue $kth(path)/tasks start start
|
|
|
|
hfactory $kth(path)/time0 plain user float
|
|
logsetup $kth(path)/time0
|
|
|
|
hfactory $kth(path)/time plain user float
|
|
logsetup $kth(path)/time
|
|
|
|
hfactory $kth(path)/rate plain user float
|
|
logsetup $kth(path)/rate
|
|
|
|
hfactory $kth(path)/file plain user text
|
|
logsetup $kth(path)/file
|
|
|
|
hupdate $kth(path)/file test
|
|
|
|
hfactory $kth(path)/sigma plain user float
|
|
logsetup $kth(path)/sigma
|
|
|
|
hfactory $kth(path)/status plain user text
|
|
hupdate $kth(path)/status ""
|
|
|
|
hfactory $kth(path)/sugar plain user text
|
|
hupdate $kth(path)/sugar ""
|
|
|
|
set node $kth(path)/measure
|
|
hfactory $node plain user float
|
|
$kth(controller) write $node
|
|
hsetprop $node write kth_measure
|
|
|
|
set node $kth(path)/rampto
|
|
hfactory $node plain user text
|
|
$kth(controller) write $node
|
|
hsetprop $node write kth_rampto
|
|
|
|
hfactory $kth(path)/rampstep plain user float
|
|
logsetup $kth(path)/rampstep
|
|
|
|
kth_rdonly "" ":SENS1:DATA?" 0 $interval
|
|
hsetprop $kth(path) update kth_update_pico
|
|
kth_combi volt user ":SOURCE:VOLT?" 0
|
|
kth_combi output user ":OUTP1:STAT?" 0
|
|
kth_combi crange user ":SENS:CURR:DC:RANG?" 0
|
|
kth_combi autorange user ":SENS:CURR:DC:RANG:AUTO?" 0
|
|
|
|
if {[string first [result vars] "kth.volt"] <= 0} {
|
|
vars = "[result vars] kth/pA/Kth/1 kth.volt/V/Volt/1"
|
|
}
|
|
|
|
hset $kth(path)/time0 0.5
|
|
hset $kth(path)/time 7
|
|
hset $kth(path)/rate 33
|
|
hset $kth(path)/sigma 1
|
|
hupdate $kth(path)/rampstep 1
|
|
hupdate $kth(path)/rampto 0
|
|
|
|
}
|