Files
sea/tcl/startup/keithley.tcl
2022-08-18 15:04:28 +02:00

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
}