From 6e1d946f21512f02cfc164e2a62236e499a551e3 Mon Sep 17 00:00:00 2001 From: l_samenv Date: Wed, 24 May 2023 11:50:42 +0200 Subject: [PATCH] fix fictrl (version jafter mods by ael lorenzana), not working yet --- tcl/drivers/fictrl.tcl | 252 ++++++++++++++++++++--------------------- 1 file changed, 124 insertions(+), 128 deletions(-) diff --git a/tcl/drivers/fictrl.tcl b/tcl/drivers/fictrl.tcl index 10d8f9f..fde00e1 100644 --- a/tcl/drivers/fictrl.tcl +++ b/tcl/drivers/fictrl.tcl @@ -1,5 +1,5 @@ -# furnace control (for now used by FI blue ILL type furnace) -# for Arduino fictrl_11 (not fictrl_12!!) +# furnace control, version for FI furnace after modification by Jael Lorenzana 03.2023 +# Arduino Firmware fictrl_13 namespace eval fictrl { } @@ -29,11 +29,6 @@ proc stdConfig::fictrl {body} { prop @voltscale $arguments(voltscale) prop @min_resist $arguments(min_resist) prop @max_resist $arguments(max_resist) - prop @offset_I $arguments(current_offset) - prop @offset_U $arguments(voltage_offset) - prop @offset_h 0 - prop @power_supply_off 0 - if {[info proc stdConfig::tdrive] eq ""} { namespace eval :: { source drivers/trun.tcl @@ -43,6 +38,8 @@ proc stdConfig::fictrl {body} { hsetprop $path/set check fictrl::check_set kids "fi control ($name)" { + node limit par 1000 + foreach ch {1 2 3 4} { node t$ch upd @@ -64,37 +61,48 @@ proc stdConfig::fictrl {body} { hfactory $path/points plain mugger floatvarar 1 } - node valid rd + node valid rd -int + prop enum 1 prop readcmd s$ch prop readfmt s$ch=%d } } node tref rd - prop readcmd t2 + prop readcmd tr prop update fictrl::update_ref - # prop readfmt "s$ch=%g" prop old 0 node tout rd - prop readcmd t1 + prop readcmd tw + prop update fictrl::update_out + + node toutmax wr + prop write fictrl::write_lim + prop readcmd wh + prop update fictrl::update_out + + node toutmin wr + prop readcmd wl + prop write fictrl::write_lim prop update fictrl::update_out - # prop readfmt "s$ch=%g" node ctrlmode wr prop writecmd s=%d prop readcmd s prop readfmt s=%d - prop enum ok,off,illegal_channel,no_sensor,no_waterflow,above_alarm,bad_vacuum,power_supply_off + prop enum ok,off,illegal_channel,no_sensor,no_waterflow,bad_vacuum,tc_overflow,wall_T_overflow prop update fictrl::update_c node ramp par 20 node smooth par 60 - node prop par 0.5 + node prop par 0.005 + prop help "proportional gain for T slope control" - node int par 0.1 + node int par 0.2 + prop help "time constant for T slope control" node powerset out default 0 @@ -118,7 +126,11 @@ proc stdConfig::fictrl {body} { prop readcmd o prop readfmt o=%g + node manualpower -int par 0 + prop enum 1 + node ctrlchan wr -int + default 1 prop writecmd c=%d prop readcmd c prop readfmt c=%d @@ -126,30 +138,36 @@ proc stdConfig::fictrl {body} { node interlock_state rd -int prop readcmd is prop readfmt is=%d - prop enum ok=0,no_waterflow=1 - # ,no_vacuum=2,no_water_no_vacuum=3 + prop enum ok=0,no_waterflow=1,bad_vacuum=2,no_waterflow_bad_vacuum=3 node interlock_mask wr -int prop readcmd im prop readfmt im=%d prop writecmd im=%d - prop enum check_water_flow=0,no_check=1 - # ,check_vacuum_only=2,check_all=3 + prop enum no_check=0,check_water_only=1,check_vacuum_only=2,check_all=3 node sramp upd node slope upd - node v_htr upd + node v_htr rd + prop readcmd U + prop readfmt U=%g + prop update fictrl::update_offset + prop offset 0 - node i_htr upd + node i_htr rd + prop readcmd I + prop readfmt I=%g + prop update fictrl::update_offset + prop offset 0 node htr rd - prop readcmd "h U I" + prop readcmd h + prop readfmt h=%g prop update fictrl::update_power node powerprop upd - } } @@ -158,77 +176,51 @@ proc fictrl::check_power {} { if {$p > 0} { set r [hval [sct parent]/resist] set s [sct @voltscale] - set output [format %.2f [expr 100 * sqrt($p * $r) / $s]] - # clientput "output $output" - hset [sct parent]/output $output + hset [sct parent]/output [format %.2f [expr 100 * sqrt($p * $r) / $s]] } else { - # clientput "output 0" hset [sct parent]/output 0 } } proc fictrl::update_power {} { - array set keyval {h 0 U 0 I 0} - foreach item [sct result] { - lassign [split $item =] key val - set keyval($key) [expr $val + [silent 0 sct @offset_$key]] - } - sct update $keyval(h) - set v $keyval(U) - set i $keyval(I) - set pow [expr max(0, $v * $i)] - set vout [expr $keyval(h) * 0.01 * [sct @voltscale]] - # set vpercent [expr $v * 100.0 / [sct @voltscale]] - # difference output voltage % - read voltage % - clientput "v $v vout $vout last [silent None sct last_v]" - if {abs($v - $vout) > 0.5} { - if {abs($v - [silent 100 sct last_v]) > 100.02} { - clientput "power supply feedback does not follow" - enum_decode [sct parent]/ctrlmode power_supply_off new - sct @power_supply_off 1 - if {$new != [sctval [sct parent]/ctrlmode]} { - hset [sct parent]/ctrlmode $new - } - return idle - } - sct last_v $v - set pow [expr max(0, $vout * $i)] - } - sct @power_supply_off 0 - if {[sctval [sct parent]/ctrlmode]} { - updateval [sct parent]/power 0 - return idle - } - updateval [sct parent]/v_htr $v - updateval [sct parent]/i_htr $i - updateval [sct parent]/power $pow - if {$i > 1 && $v > 0.05} { + stdSct::update + set v [silent 0 hval [sct parent]/v_htr] + set i [silent 0 hval [sct parent]/i_htr] + set p [expr $i * $v] + updateval [sct parent]/power $p + if {$i > 1 && $v > 0.1} { set r [hval [sct parent]/resist] set r1 [expr ($v - 0.005) / double($i + 0.1)] set r2 [expr ($v + 0.005) / double($i - 0.1)] if {$r1 > [sct @max_resist]} { - clientput "ERROR: resistance $r1 too high" + error "resistance $r too high" } if {$r2 < [sct @min_resist]} { - clientput "ERROR: resistance $r2 too low" + error "resistance $r too low" } if {$r < $r1} { -# set r $r1 - set r [expr $r * 0.9 + $r1 * 0.1] + set r $r1 +# set r [expr $r * 0.9 + $r1 * 0.1] } elseif {$r > $r2} { - set r [expr $r * 0.9 + $r2 * 0.1] -# set r $r2 +# set r [expr $r * 0.9 + $r2 * 0.1] + set r $r2 } hupdate [sct parent]/resist $r } + updateval [sct parent]/power $p return idle } proc fictrl::check_set {} { sct @switch_on 1 - sct @power_supply_off 0 - hupdate [sct parent]/status "" - hset [sct parent]/ctrlmode 0 + if {[sct target] > [hval [sct parent]/limit]} { + error "set T > limit ([hval [sct parent]/limit])" + } + hupdate [sct parent]/target [sct target] + if {[string match switched* [hval [sct parent]/status]]} { + hupdate [sct parent]/status "" + } + sct update [sct target] } proc fictrl::cmds {} { @@ -266,9 +258,6 @@ proc fictrl::to_mvolt {ch value} { proc fictrl::ctrl_slope {} { if {[sct @switch_on]} { - if {[hvali [sct parent]/ctrlmode]} { - hupdate [sct parent]/powerset 0 - } set init "s=0 " } elseif {[hvali [sct parent]/ctrlmode]} { # error state @@ -281,10 +270,11 @@ proc fictrl::ctrl_slope {} { return idle } - # set ta [expr [hval [sct parent]/t$ch] + 20] - set ta 1370 - set valarm [to_mvolt $ch $ta] + # alarm when T is increasing by more than 50 K within 5 sec or T > limit + 20 + set ta [expr min([hval [sct parent]/t$ch] + 50, [hval [sct parent]/limit] + 20)] + set valarm [format %g [to_mvolt $ch $ta]] sct @switch_on 0 + #clientput "ctrl talarm=$ta" sct send "${init}a=$valarm c=$ch dx vx sx" return fictrl::ctrl_do } @@ -323,8 +313,6 @@ proc fictrl::ctrl_do {} { set sramp [expr -$sramp] } hupdate [sct parent]/sramp $sramp - # filter slope - set slope [expr [silent $slope hval [sct parent]/slope] * 0.9 + $slope * 0.1] hupdate [sct parent]/slope $slope set last_dif [silent 0 sct last_dif] set dif [expr $sramp - $slope] @@ -334,7 +322,7 @@ proc fictrl::ctrl_do {} { set maxpower [hval [sct parent]/maxpower] set r [hval [sct parent]/resist] set s [sct @voltscale] - hset [sct parent]/maxheater [expr sqrt($maxpower * $r) * 100.0 / $s] + hset [sct parent]/maxheater [format %.5g [expr sqrt($maxpower * $r) * 100.0 / $s]] if {$out < 0} { if {$dif > 0} { set out 0 @@ -349,14 +337,15 @@ proc fictrl::ctrl_do {} { } } # clientput "dif $dif powerset $out" - hset [sct parent]/powerset [format %.5g $out] hupdate [sct parent]/powerprop [expr $prop * $dif] return idle } proc fictrl::update_ref {} { - [sct controller] queue [sct] slow fictrl::ctrl_slope + if {[hval [sct objectPath]/manualpower] == 0} { + [sct controller] queue [sct] slow fictrl::ctrl_slope + } set v [lindex [split [sct result] =] 1] set t [format %.1f [expr $v + 273.15]] sct update $t @@ -370,62 +359,69 @@ proc fictrl::update_out {} { return idle } +proc fictrl::write_lim {} { + sct send [format "[sct readcmd]=%.1f" [expr [sct target] - 273.15]] + return read +} + proc fictrl::update_v {} { stdSct::update - updateval [sct parent] [to_kelvin [sct channel] [hvali [sct]]] + set temp_k [to_kelvin [sct channel] [hvali [sct]]] + updateval [sct parent] $temp_k + if {([hval [sct objectPath]/manualpower] || [hvali [sct objectPath]/ctrlmode]) && + [sct channel] == [hval [sct objectPath]/ctrlchan]} { + updateval [sct objectPath] $temp_k + } + return idle +} + +proc fictrl::update_offset {} { + lassign [split [sct result] =] name v + if {$v > 0} { + set v [expr $v + [silent 0 sct offset]] + } + if {[silent "" sct geterror] ne "powersupply_switched_off"} { + sct update $v + } return idle } proc fictrl::update_c {} { - set value [stdSct::scanresult] - set old_status [hvali [sct objectPath]/status] - enum_decode [sct] $value _ old_mode - set new $old_mode - lassign [split [hvali /pv/sps] ","] pstate - set pstate 1 ;# HACK: when comm to TPG does not work - if {$pstate eq ""} { - set pstate 0 - } - if {!$pstate} { - # bad_vacuum - enum_decode [sct] bad_vacuum num - sct update $num - if {$old_mode eq "ok" || $old_mode eq "off"} { - hset [sct] $num - set new bad_vacuum - } - hsetprop [sct parent]/v_htr geterror powersupply_switched_off - hsetprop [sct parent]/i_htr geterror powersupply_switched_off - } else { - sct update $value - catch { - hdelprop [sct parent]/v_htr geterror - hdelprop [sct parent]/i_htr geterror - } - } - if {$new eq "power_supply_off"} { # HACK - set new "ok" + stdSct::update + if {[sct @switch_on]} { + return idle } + set o [sct objectPath] + set old [hvali $o/status] + set new [enum_txt [sct]] if {$new ne "ok"} { - switch $new { - bad_vacuum { - if {$pstate} { set new "off after bad_vacuum" } - } - no_waterflow { - if {[hval [sct parent]/interlock_state] == 0} { set new "off after no_waterflow" } - } - power_supply_off { - if {![sct @power_supply_off]} { set new "off after power_supply_off" } + if {$new != [silent 0 sct oldval]} { + clientput "ERROR: $new" + sct oldval $new + } + set interlock_state [expr [hval $o/interlock_state] & [hval $o/interlock_mask]] + set summary [list] + if {$interlock_state & 1} { + lappend summary "no waterflow" + } + if {$interlock_state & 2} { + lappend summary "bad vacuum" + } + if {[hval $o/tout] > [hval $o/toutmax]} { + lappend summary "wall T too high" + } elseif {[hval $o/tout] < [hval $o/toutmin]} { + lappend summary "missing wall sensor" + } + set summary [join $summary ", "] + if {$summary eq ""} { + if {$new eq "off"} { + set summary "switched off" + } else { + set summary "switched off because of $new" } } - if {$new ne $old_status} { - hupdate [sct parent]/powerset 0 - if {[lindex $new end] ne [lindex $old_status end]} { - clientput "ERROR: $new" - } - } - hupdate [sct objectPath]/status $new - } elseif {$old_status != ""} { + hupdate [sct objectPath]/status $summary + } elseif {$old != ""} { hupdate [sct objectPath]/status "" } return idle