diff --git a/tcl/drivers/ah2550.tcl b/tcl/drivers/ah2550.tcl new file mode 100644 index 0000000..4cdd9d2 --- /dev/null +++ b/tcl/drivers/ah2550.tcl @@ -0,0 +1,137 @@ +# Andeen Hagerling 2550 capacitance bridge 1kHz +namespace eval ah2550 {} { +} + +proc stdConfig::ah2550 {} { + controller std sendterminator=\r timeout=60 lineseparator=, + + variable node + set node $node/tasks + prop start ah2550::start + + obj ah2550 rd -none + prop read ah2550::read + prop do_read_avg 1 + prop period 0 + prop cnt 0 + + kids ah2550 { + node cap upd + prop fmt %.8f + + node loss upd + prop fmt %.8f + + node period out + default 5 + prop check ah2550::change_period + prop write stdSct::complete + + node V out + prop label Exitation Voltage + prop writecmd "VO %g;SI" + prop complete ah2550::update + + node average out -int + prop label "average setting" + prop writecmd "AV %d;SH AV" + prop complete ah2550::update_av + } +} + +proc ah2550::start {} { + sct send "UN DF" + return ah2550::start1 +} + +proc ah2550::start1 {} { + set prefix [lindex [sct result] 0] + if {$prefix eq "UN"} { # this was the echo + sct send "SERIAL ECHO OFF" + return ah2550::start + } + if {$prefix ne "C=" && [sct result] ne "NO DATA FOUND"} { + error "bad response: [sct result]" + } + sct send "*IDN?" + return ah2550::start2 +} + +proc ah2550::start2 {} { + sct result [join [sct result]] + return stdSct::completeStart +} + +proc ah2550::read {} { + sct send "SI" + sct sendtime [DoubleTime] + return ah2550::update +} + +proc ah2550::update {} { + # analyze result: _ is a placeholder for text words + set res [string map {"," " , "} [sct result]] + set res [string map {"=" "= "} $res] + #clientput $res + lassign $res prefix c _ _ _ l un _ _ v _ _ _ _ _ _ _ + if {$prefix eq "SI"} { + sct send "\r\nSERIAL ECHO OFF\r" + return stdSct::complete + } + if {$prefix eq "C="} { + hupdate [sct objectPath]/status "" + } else { + hupdate [sct objectPath]/status [sct result] + } + set period [expr [DoubleTime] - [sct sendtime] + 0.1] + sct cnt [expr min(20, [sct cnt] + 1)] + set dif [expr $period - [sct period]] + sct period [expr [sct period] + $dif / [sct cnt]] + if {abs([sct period] - [hval [sct]/period]) > 0.1 || [sct cnt] == 10} { + set period [format {%.1f} [sct period]] + if {$period != [hval [sct]/period]} { + hupdate [sct]/period [format {%.1f} $period] + set_period [sct] $period + sct do_read_avg 1 + } + } + hupdate [sct objectPath]/cap $c + hupdate [sct objectPath]/V $v + if {[string index $un 0] eq "Z"} { + sct send "ZERO OFF" + return ah2550::update + } elseif {[string index $un 0] eq "R"} { + sct send "REF OFF" + return ah2550::update + } elseif {$un ne "DF"} { + sct send "UN DF" + return ah2550::update + } + hupdate [sct objectPath]/loss $l + if {[sct do_read_avg]} { + sct do_read_avg 0 + sct send "SH AV" + return ah2550::update_av + } + return idle +} + +proc ah2550::update_av {} { + set res1 [lindex [split [sct result] " "] end] + catch { + hupdate [sct objectPath]/average $res1 + } msg + hsetprop [sct objectPath] cnt 0 + return idle +} + +proc ah2550::set_period {node target} { + [sct controllerName] poll $node $target + hupdate $node/period $target +} + +proc ah2550::change_period {} { + set_period [sct objectPath] [sct target] + return idle +} +