# 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 }