254 lines
6.5 KiB
Tcl
254 lines
6.5 KiB
Tcl
namespace eval bronkgen {} {
|
|
}
|
|
|
|
proc stdConfig::bronkgen {label scale {adr 128} {readonly 0} {ramp 0} {setoffset 0} {ctrlmode 0} {invalidvalue none}} {
|
|
|
|
# driver for Bronkhorst Flow or Pressure regulator (i.e.P-602CV-21KA-AAD)
|
|
# serial interface is set to:
|
|
# Char Size/Stop Bits: 8/1 Input Speed: 38400
|
|
# Flow Ctrl: None Output Speed: 38400
|
|
# Parity: None Modem Control: None
|
|
|
|
# syntax (chaining not mentioned):
|
|
# read command: :06Ad04CopyPrTp
|
|
# write command: :LnAd01PrTpData
|
|
# where:
|
|
# Ln: number of bytes (hex digits pairs) following
|
|
# Ad: node address (starting from 3)
|
|
# Copy: values just to be copied by the reply (first and third digit < 8)
|
|
# recommended practice: Use PrTp for Copy
|
|
# Pr: Process number (<80)
|
|
# Tp: Type + parameter number. Type: 00 byte, 20 int, 40 long/float, 60 string
|
|
# for strings either 00 (for nul terminated) or the max. number of chars
|
|
# has to be appended to the type
|
|
# Data: length depending on type.
|
|
|
|
# the interface returns readings on a scale where 32000 is 100%
|
|
|
|
set adr [format %02x $adr]
|
|
|
|
controller std "\r\n"
|
|
prop read bronkgen::read
|
|
prop write bronkgen::write
|
|
prop update bronkgen::update
|
|
prop startcmd :07${adr}047163716300
|
|
prop convert_idn bronkgen::result2string
|
|
|
|
clientput "BRONK $label $scale $adr"
|
|
|
|
obj BRONKGEN rd
|
|
prop label $label
|
|
prop par "1 0 $scale"
|
|
prop @adr $adr
|
|
if {$invalidvalue ne "none"} {
|
|
prop invalidvalue $invalidvalue
|
|
}
|
|
|
|
kids "$label" {
|
|
if {$readonly == 0} {
|
|
node set wr
|
|
prop label setpoint
|
|
prop par "1 1 $scale"
|
|
prop setoffset $setoffset
|
|
|
|
if {$ramp != 0} {
|
|
prop write bronkgen::write_with_ramp
|
|
prop update bronkgen::update_set
|
|
|
|
node reg upd
|
|
|
|
node ramptime rd
|
|
prop par "1 2 i 0.1"
|
|
|
|
node ramp par $ramp
|
|
|
|
node rampstd par $ramp
|
|
}
|
|
|
|
if {$ctrlmode} {
|
|
node ctrlmode wr
|
|
prop label "control mode"
|
|
prop enum manual=4,loop=11
|
|
prop par "1 4 b"
|
|
|
|
node output wr
|
|
prop par "114 1 l 0.002"
|
|
}
|
|
}
|
|
|
|
node fluid rd -text
|
|
prop par "1 17 s"
|
|
|
|
node par out -text
|
|
default "113 6 s"
|
|
prop write bronkgen::setpar /x
|
|
|
|
node x wr -text
|
|
prop par "113 6 s"
|
|
prop width 32
|
|
}
|
|
|
|
}
|
|
|
|
proc bronkgen::result2string {} {
|
|
set string ""
|
|
foreach {h l} [split [string range [sct result] 13 end-2] ""] {
|
|
append string [format %c [scan $h$l %2x]]
|
|
}
|
|
return $string
|
|
}
|
|
|
|
proc bronkgen::update {{as_function 0}} {
|
|
lassign [sct par] process par type scale
|
|
if {$scale eq ""} {
|
|
set scale 1
|
|
}
|
|
set value 0
|
|
switch -- $type {
|
|
b {
|
|
set res [scan [string range [sct result] 11 12] %2x value]
|
|
}
|
|
i {
|
|
set res [scan [string range [sct result] 11 14] %4x value]
|
|
set value [expr $value * $scale]
|
|
}
|
|
l {
|
|
set res [scan [string range [sct result] 11 18] %8x value]
|
|
set value [expr $value * $scale]
|
|
}
|
|
s {
|
|
set value ""
|
|
foreach {h l} [split [string range [sct result] 13 end-2] ""] {
|
|
append value [format %c [scan $h$l %2x]]
|
|
}
|
|
set res 1
|
|
}
|
|
default {
|
|
set res [scan [string range [sct result] 11 14] %4x value]
|
|
set value [format %.4g [expr $value * $type / 32000.]]
|
|
}
|
|
}
|
|
if {$res != 1} {
|
|
error "bad result format: '[sct result]'"
|
|
} elseif {$as_function} {
|
|
return $value
|
|
}
|
|
if {$value != [silent -0.123e-45 sct invalidvalue]} {
|
|
sct update $value
|
|
}
|
|
return idle
|
|
}
|
|
|
|
|
|
proc bronkgen::read {} {
|
|
lassign [sct par] process par type
|
|
switch -- $type {
|
|
b {
|
|
set arg [format %2.2X%2.2X $process $par]
|
|
set arg $arg$arg
|
|
}
|
|
s {
|
|
set arg [format %2.2X%2.2X $process [expr $par + 0x60]]
|
|
set arg $arg${arg}00
|
|
}
|
|
l {
|
|
set arg [format %2.2X%2.2X $process [expr $par + 0x40]]
|
|
set arg $arg${arg}00
|
|
}
|
|
default { # i and scaled
|
|
set arg [format %2.2X%2.2X $process [expr $par + 0x20]]
|
|
set arg $arg$arg
|
|
}
|
|
}
|
|
set len [format %2.2X [expr 2 + [string length $arg] / 2]]
|
|
sct send :$len[sct @adr]04$arg
|
|
return update
|
|
}
|
|
|
|
proc bronkgen::write {{logtext ""}} {
|
|
# clientput "write [sct] [sct target] $logtext"
|
|
lassign [sct par] process par type scale
|
|
if {$scale eq ""} {
|
|
set scale 1
|
|
}
|
|
switch -- $type {
|
|
b {
|
|
set arg [format %2.2X%2.2X%2.2X $process $par [sct target]]
|
|
}
|
|
s {
|
|
set arg [format %2.2X%2.2X $process [expr $par + 0x60]]
|
|
set arg $arg00
|
|
foreach char [split [sct target] ""] {
|
|
lappend arg [format %2.2X [scan $char %c]]
|
|
}
|
|
lappend "00"
|
|
}
|
|
i {
|
|
set arg [format %2.2X%2.2X%4.4X $process [expr $par + 0x20] [expr round([sct target]/$scale)]]
|
|
}
|
|
l {
|
|
set arg [format %2.2X%2.2X%8.8X $process [expr $par + 0x40] [expr round([sct target]/$scale)]]
|
|
}
|
|
default {
|
|
set val [expr round(([sct target] + [silent 0 sct setoffset]) * 32000. / $type)]
|
|
if {$val > 32000} {
|
|
if {$val < 32320} {
|
|
set val 32000
|
|
} else {
|
|
error "[sct]: [sct target] must be <= $type"
|
|
}
|
|
} elseif {$val < 0} {
|
|
error "[sct]: [sct target] must be >= 0"
|
|
}
|
|
set arg [format %2.2X%2.2X%4.4X $process [expr $par + 0x20] $val]
|
|
}
|
|
}
|
|
set len [format %2.2X [expr 2 + [string length $arg] / 2]]
|
|
sct send :$len[sct @adr]01$arg
|
|
return bronkgen::acknowledge
|
|
}
|
|
|
|
proc bronkgen::acknowledge {} {
|
|
if {[string range [sct result] 7 8] ne "00"} {
|
|
error "[sct]: bad status '[sct result]'"
|
|
}
|
|
return read
|
|
}
|
|
|
|
proc bronkgen::write_with_ramp {} {
|
|
lassign [sct par] process par scale
|
|
set rpath [sct objectPath]/ramp
|
|
set ramp [hval $rpath]
|
|
set ramptime [format %.1f [expr min(3200.0, max(10., $scale * 60.0 / max($ramp, 0.1)))]]
|
|
if {$ramptime != [silent -1 hval ${rpath}time]} {
|
|
sct send :06[sct @adr]010122[format %4.4X [expr round(10*$ramptime)]]
|
|
hupdate $rpath [hval ${rpath}std]
|
|
return "bronkgen::write {with ramp $ramp}"
|
|
}
|
|
hupdate $rpath [hval ${rpath}std]
|
|
return [bronkgen::write]
|
|
}
|
|
|
|
proc bronkgen::setpar {relpath} {
|
|
hsetprop [sct objectPath]$relpath par [sct target]
|
|
sct update [sct target]
|
|
[sct controller] queue [sct objectPath]$relpath read read
|
|
return stdSct::complete
|
|
}
|
|
|
|
proc bronkgen::update_set {} {
|
|
set req [silent none sct requested]
|
|
if {$req ne "none"} {
|
|
sct update $req
|
|
return idle
|
|
}
|
|
set value [expr max(0,[bronkgen::update 1] - [sct setoffset])]
|
|
if {$value == [silent -9999 sct old]} {
|
|
sct update $value
|
|
}
|
|
sct old $value
|
|
updateval [sct parent]/reg $value
|
|
return idle
|
|
}
|
|
|