125 lines
2.9 KiB
Tcl
125 lines
2.9 KiB
Tcl
# virtual temperature controller using multiple controllers regulation the same T
|
|
#
|
|
|
|
namespace eval multit {} {
|
|
}
|
|
|
|
proc stdConfig::multit {label full_label slaves {slaves_with_offset 0} {offset 0} {rt_auto 0}} {
|
|
variable hostport none
|
|
variable name
|
|
variable path
|
|
|
|
controller syncedprot 30
|
|
prop write stdSct::complete
|
|
|
|
pollperiod 1 1
|
|
|
|
obj multi_t -drive wr
|
|
if {[info proc stdConfig::tdrive] eq ""} {
|
|
namespace eval :: {
|
|
source drivers/trun.tcl
|
|
}
|
|
}
|
|
tdrive $name -log 1
|
|
hsetprop $path/set check "multit::check_with_offset /set $slaves $slaves_with_offset"
|
|
hsetprop $path/set visible false
|
|
hsetprop $path label set
|
|
|
|
kids $full_label {
|
|
node reg rd
|
|
prop read "multit::poll {{} /reg /htr} $slaves"
|
|
|
|
node ramp out
|
|
prop check "multit::check_set /ramp $slaves"
|
|
|
|
node pb out
|
|
prop label "prop. band"
|
|
prop check "multit::check_set /pb $slaves"
|
|
|
|
node rt out
|
|
prop label "int. t"
|
|
prop help "int. t \[sec\]"
|
|
prop check "multit::check_set /rt $slaves"
|
|
|
|
node rt_auto par $rt_auto
|
|
if {$rt_auto == 0} {
|
|
prop visible false
|
|
}
|
|
prop label "int. t * t_set"
|
|
prop help "calculate int.t from this value (set to 0 for manual int.t)"
|
|
|
|
node td out
|
|
prop label "deriv. t"
|
|
prop help "deriv. t \[sec\]"
|
|
prop check "multit::check_set /td $slaves"
|
|
|
|
node manual out
|
|
prop check "multit::check_set /manual $slaves"
|
|
prop enum 1
|
|
|
|
node manual_output out
|
|
prop check "multit::check_set /manual_output $slaves"
|
|
|
|
node htr upd
|
|
|
|
if {$offset ne "0"} {
|
|
node offset -text par $offset
|
|
prop width 20
|
|
}
|
|
}
|
|
}
|
|
|
|
proc multit::check_set {relpath slaves} {
|
|
foreach a $slaves {
|
|
hset $a$relpath [sct target]
|
|
}
|
|
sct update [sct target]
|
|
}
|
|
|
|
proc multit::check_with_offset {relpath slaves {slaves_with_offset ""}} {
|
|
if {[sct target] == 0} {
|
|
hset [sct parent]/manual_output 0
|
|
hset [sct parent]/manual 1
|
|
} elseif {[sctval [sct parent]/manual]} {
|
|
hset [sct parent]/manual 0
|
|
}
|
|
foreach a $slaves {
|
|
hset $a$relpath [sct target]
|
|
set rta [hval [sct parent]/rt_auto]
|
|
if {$relpath eq "/set" && $rta != 0} {
|
|
set rt [expr $rta / max(20, [sct target])]
|
|
if {abs($rt - [hvali [sct parent]/rt]) >= 1} {
|
|
hset [sct parent]/rt $rt
|
|
}
|
|
}
|
|
}
|
|
foreach a $slaves_with_offset {
|
|
set formula [string map {$ "" "[" "(" "]" ")" "%" "* $t * 0.01"} [silent 0 hval $a/offset]]
|
|
set t [sct target]
|
|
if {$t != 0} {
|
|
set t [expr "\$t + $formula"]
|
|
}
|
|
hset $a$relpath $t
|
|
}
|
|
sct update [sct target]
|
|
hsetprop [sct objectPath] target [sct target]
|
|
}
|
|
|
|
proc multit::poll {relpaths slaves} {
|
|
foreach relpath $relpaths {
|
|
set n 0
|
|
set sum 0
|
|
foreach a $slaves {
|
|
catch {
|
|
set sum [expr $sum + [hval $a$relpath]]
|
|
incr n
|
|
}
|
|
}
|
|
if {$n > 0} {
|
|
updateval [sct objectPath]$relpath [expr $sum / double($n)]
|
|
}
|
|
}
|
|
return idle
|
|
}
|
|
|