297 lines
7.0 KiB
Tcl
297 lines
7.0 KiB
Tcl
# auto range for lsc 370
|
|
namespace eval auto370 {
|
|
}
|
|
|
|
proc stdConfig::auto370 {lsc370 {getcmd 0}} {
|
|
variable path
|
|
variable name
|
|
|
|
controller syncedprot 10
|
|
|
|
pollperiod 1 1
|
|
|
|
obj auto370 wr
|
|
prop enum 1
|
|
prop label "auto heater on"
|
|
prop read auto370::poll
|
|
prop write stdSct::completeUpdate
|
|
prop lsc370 /$lsc370/set
|
|
prop lastdown 0
|
|
prop lastup 0
|
|
prop resist 0
|
|
prop @rangetarget 0
|
|
prop getcmd $getcmd
|
|
prop heat 1
|
|
kids "$lsc370 autorange settings" {
|
|
node mode -int out
|
|
prop enum 0,1
|
|
prop check auto370::checkmode
|
|
prop write stdSct::complete
|
|
default 0
|
|
|
|
node heaterrange -int out
|
|
prop check auto370::checkrange
|
|
prop write stdSct::complete
|
|
prop enum 1,2,3,4,5,6,7,8
|
|
prop label heaterrange
|
|
|
|
node minrange par 3
|
|
prop enum 1,2,3,4,5,6,7,8
|
|
prop label minrange
|
|
|
|
node maxrange par 6
|
|
prop enum 1,2,3,4,5,6,7,8
|
|
prop label maxrange
|
|
|
|
node switchup par 90
|
|
|
|
node switchupdelay par 60
|
|
prop label "switch up delay"
|
|
prop help "min. time to be above the threshold before switching up"
|
|
|
|
node switchdown par 10
|
|
|
|
node switchdowndelay par 300
|
|
prop label "switch down delay"
|
|
prop help "min. time to be below the threshold before switching down"
|
|
|
|
node heater upd
|
|
|
|
node autoprop par 0
|
|
prop enum 1
|
|
prop newline 1
|
|
|
|
node calcpow upd
|
|
|
|
node ttable -text par {0.01 0.02 0.064 0.2}
|
|
prop width 40
|
|
prop label T power table
|
|
prop help "T for 1uW, 10uW, 100uW, 1mW ..."
|
|
prop newline 1
|
|
|
|
node prop par 5
|
|
prop label "max. prop"
|
|
|
|
node propmin par 0.2
|
|
prop label "min. prop"
|
|
}
|
|
|
|
}
|
|
|
|
proc auto370::neededPower {tem table} {
|
|
set pow 1.0e-7
|
|
set last [expr [lindex $table 0] * sqrt(0.1)]
|
|
foreach t $table {
|
|
if {$tem < $t} {
|
|
if {$last == 0} {
|
|
return $pow
|
|
}
|
|
return [expr $pow * pow($tem / $last, 1.0 / log10($t/$last))]
|
|
}
|
|
set pow [expr $pow * 10]
|
|
set last $t
|
|
}
|
|
return [expr $pow * pow($tem / $last, 2)]
|
|
}
|
|
|
|
proc auto370::poll {} {
|
|
catch {hdelprop [sct] geterror}
|
|
set now [clock seconds]
|
|
set p [sct lsc370]
|
|
set resist [sctval $p/resist]
|
|
set pow [sctval $p/maxpower]
|
|
if {$pow <= 0} {
|
|
return idle
|
|
}
|
|
set htrrng [expr round(log10($pow / $resist) + 10)]
|
|
set htr [silent 0 hgetpropval $p/power htr]
|
|
updateval [sct]/heater $htr
|
|
set minr [sctval [sct]/minrange]
|
|
set minp [expr $resist * pow(10, $minr - 10)]
|
|
set maxr [sctval [sct]/maxrange]
|
|
set maxp [expr $resist * pow(10, $maxr - 10)]
|
|
set maxpowerlim [sctval $p/maxpowerlim]
|
|
set maxl [expr round(log10($maxpowerlim / $resist) + 10)]
|
|
set w1 [expr $resist * 0.01]
|
|
set w2 [expr $resist * 0.1]
|
|
set w3 $resist
|
|
set plist [format {%gnW=1 %guW=2 %guW=3 %guW=4 %gmW=5 %gmW=6 %gmW=7 %gW=8} $w3 $w1 $w2 $w3 $w1 $w2 $w3 $w1]
|
|
set plist [lrange $plist 0 [expr $maxl-1]]
|
|
set htxt [join [lrange $plist [expr $minr-1] [expr $maxr-1]] ,]
|
|
if {$htxt ne [hgetpropval [sct]/heaterrange enum]} {
|
|
hsetprop [sct]/minrange enum [join $plist ,]
|
|
hsetprop [sct]/maxrange enum [join $plist ,]
|
|
hsetprop [sct]/heaterrange enum $htxt
|
|
}
|
|
|
|
set soll [hvali $p/reg]
|
|
|
|
set psoll [neededPower $soll [hvali [sct]/ttable]]
|
|
hupdate [sct]/calcpow $psoll
|
|
if {[hvali [sct]/autoprop]} {
|
|
set prop [hvali $p/prop]
|
|
set f [expr sqrt($psoll / $pow)]
|
|
if {$f > 1} {
|
|
set f 1
|
|
}
|
|
set pnew [expr [hvali [sct]/prop] * $f]
|
|
set propmin [hvali [sct]/propmin]
|
|
if {$pnew < $propmin} {
|
|
set pnew $propmin
|
|
}
|
|
if {$prop != $pnew} {
|
|
hset $p/prop $pnew
|
|
}
|
|
hsetprop $p/prop priv internal
|
|
} else {
|
|
hsetprop $p/prop priv user
|
|
}
|
|
|
|
|
|
set switchup [hvali [sct]/switchup]
|
|
if {$switchup > 100} {
|
|
set switchup 100
|
|
hupdate [sct]/switchup $switchup
|
|
} elseif {$switchup < 10} {
|
|
set switchup 10
|
|
hupdate [sct]/switchup $switchup
|
|
}
|
|
set switchdown [hvali [sct]/switchdown]
|
|
if {$switchdown > $switchup * 0.3} {
|
|
set switchdown [expr $switchup * 0.3]
|
|
hupdate [sct]/switchdown $switchdown
|
|
} elseif {$switchdown < 0.1} {
|
|
set switchdown 0.1
|
|
hupdate [sct]/switchdown $switchdown
|
|
}
|
|
set rangetarget [sct @rangetarget]
|
|
if {$rangetarget == 0} {
|
|
updateval [sct]/heaterrange $htrrng
|
|
} else {
|
|
sct @rangetarget 0
|
|
if {$rangetarget != $htrrng} {
|
|
set newpow [expr $pow * pow(10, $rangetarget - $htrrng)]
|
|
sctsync {
|
|
hset $p/maxpower $newpow
|
|
}
|
|
return "auto370::complete $pow $newpow [hvali $p/power]"
|
|
}
|
|
}
|
|
if {$htr > $switchup * 0.3 && $htrrng < $maxr} {
|
|
sct lastdown $now
|
|
if {$htr >= $switchup} {
|
|
set newpow [expr $pow * 10]
|
|
if {$newpow > $maxp * 1.1} {
|
|
set newpow $maxp
|
|
}
|
|
if {$now > [sct lastup] + [hvali [sct]/switchupdelay]} {
|
|
if {[sctval [sct]] == 0} {
|
|
return idle
|
|
}
|
|
sct lastup $now
|
|
sctsync {
|
|
hset $p/maxpower $newpow
|
|
}
|
|
return "auto370::complete $pow $newpow [hvali $p/power]"
|
|
}
|
|
} else {
|
|
sct lastup $now
|
|
}
|
|
set r [expr $now - [sct lastup]]
|
|
if {[sctval [sct]] == 0} {
|
|
set r 0
|
|
}
|
|
if {$r < 5} {
|
|
hsetprop [sct]/switchupdelay label "switch up delay"
|
|
} else {
|
|
hsetprop [sct]/switchupdelay label "switch up d.($r)"
|
|
}
|
|
}
|
|
if {$htr < $switchdown / 0.3 && $htrrng > $minr} {
|
|
sct lastup $now
|
|
if {$htr <= $switchdown} {
|
|
set newpow [expr $pow * 0.1]
|
|
if {$newpow < $minp * 0.9} {
|
|
set newpow $minp
|
|
}
|
|
if {$htr == 0} {
|
|
sct lastdown $now
|
|
}
|
|
if {$now > [sct lastdown] + [hvali [sct]/switchdowndelay]} {
|
|
if {[sctval [sct]] == 0} {
|
|
return idle
|
|
}
|
|
sct lastdown $now
|
|
sctsync {
|
|
hset $p/maxpower $newpow
|
|
}
|
|
return "auto370::complete $pow $newpow [hvali $p/power]"
|
|
}
|
|
} else {
|
|
sct lastdown $now
|
|
}
|
|
set r [expr $now - [sct lastdown]]
|
|
if {[sctval [sct]] == 0} {
|
|
set r 0
|
|
}
|
|
if {$r < 5} {
|
|
hsetprop [sct]/switchdowndelay label "switch down delay"
|
|
} else {
|
|
hsetprop [sct]/switchdowndelay label "switch down d.($r)"
|
|
}
|
|
}
|
|
return idle
|
|
}
|
|
|
|
proc auto370::complete {oldpow newpow manpow} {
|
|
set p [sct lsc370]
|
|
sctsync {
|
|
hset $p/manualpower $manpow
|
|
}
|
|
return "auto370::complete2 $oldpow"
|
|
}
|
|
|
|
proc auto370::complete2 {oldpow} {
|
|
set p [sct lsc370]
|
|
set pow [sctval $p/maxpower]
|
|
sctsync {
|
|
hset $p/mode 1
|
|
}
|
|
# return stdSct::complete
|
|
return auto370::finish
|
|
}
|
|
|
|
proc auto370::finish {} {
|
|
return idle
|
|
}
|
|
|
|
proc auto370::checkrange {} {
|
|
sct @rangetarget [sct target]
|
|
sct update [sct target]
|
|
}
|
|
|
|
proc auto370::checkmode {} {
|
|
set code [silent {} sct mode[sct target]]
|
|
if {$code eq ""} {
|
|
error "illegal mode [sct target]"
|
|
}
|
|
sct update [sct target]
|
|
set enum [split [hgetpropval [sct] enum] ,]
|
|
clientput "set parameters for [lindex $enum [sct target]]"
|
|
eval $code
|
|
}
|
|
|
|
proc auto370::mode {nr mode code} {
|
|
set p $::stdConfig::path
|
|
hsetprop $p/mode mode$nr $code
|
|
set enum [split [hgetpropval $p/mode enum] ,]
|
|
if {$nr > 10} {
|
|
error "nr $nr too big"
|
|
}
|
|
while {[llength $enum] <= $nr} {
|
|
lappend enum $nr
|
|
}
|
|
lset enum $nr $mode
|
|
hsetprop $p/mode enum [join $enum ,]
|
|
}
|