User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
useful_programs [2020/01/13 10:17]
emozolyak [Debug printing]
useful_programs [2020/03/20 10:06] (current)
emozolyak [3-point control for a valve or servo]
Line 142: Line 142:
 function DBG(...) function DBG(...)
 local tc = tabToStr local tc = tabToStr
- +  
-local function align2s(s1, s2) -- appends space to smaller string  +function align2s(s1, s2) -- appends space to smaller string  
-    local d, s = (#s1 - #s2), ' '  +    local d, s = (#s1 - #s2), ' ' ​; local ad = math.abs(d) 
-    if (d ~= 0) then return (((d > 0) and {s1, s2 .. s:rep(d)}) or ({s1 .. s:rep(math.abs(d)), s2}))+    ​ 
 +    if (d ~= 0) then  
 +         
 +        local Lp, Rp = 0, 0 
 +         
 +        if ((ad % 2) == 0) then  
 +            Lp = ad / 2 ; Rp = Lp ; INFO("​even parts, L R = " .. Lp .. s .. Rp) 
 +        else  
 +            Lp = math.floor(ad / 2) ; Rp = Lp + 1 ; INFO("​not even L R " .. Lp .. s .. Rp) 
 +        end  
 +        ​return (((d > 0) and {s1, s:rep(Lp) .. s2 .. s:rep(Rp)})  
 +                        ​or 
 +             ({s:rep(Lp) .. s1 .. s:rep(Rp), s2}))
     else      else 
         return {s1, s2}         return {s1, s2}
Line 154: Line 166:
         local arg_str = tc(arg)         local arg_str = tc(arg)
         local t_s_pos = string.find(arg_str,​ "​|"​) ​         local t_s_pos = string.find(arg_str,​ "​|"​) ​
-    ​+ 
         if not t_s_pos then          if not t_s_pos then 
             INFO(arg_str) ​ -- Just printing single line              INFO(arg_str) ​ -- Just printing single line 
Line 167: Line 179:
                 v_row[#​v_row + 1] = tostring(arg[i])                 v_row[#​v_row + 1] = tostring(arg[i])
             end              end 
-            ​+ 
             if (#h_row ~= #v_row) then              if (#h_row ~= #v_row) then 
-                ERROR("​Inconsistent header and value rows in DBGnew!")+                ERROR("​Inconsistent header and value rows in DBG!"
 +                INFO("​h_row:"​ .. tc(h_row)) ; INFO("​v_row"​ .. tc("​v_row"​))
                 return ​                 return ​
             else              else 
Line 180: Line 193:
     end      end 
 end  ​ end  ​
 + 
 function tabToStr(t) ​ -- glue all and add spaces, use tostring to protect from nil and bool argument ​ function tabToStr(t) ​ -- glue all and add spaces, use tostring to protect from nil and bool argument ​
     local s = "" ​           ​     local s = "" ​           ​
Line 595: Line 608:
 To determine intermediate positions, a calculated value is used, determined from the characteristics of the 'full path time', which can also be determined experimentally.  ​ To determine intermediate positions, a calculated value is used, determined from the characteristics of the 'full path time', which can also be determined experimentally.  ​
  
-Below is a variant of 3-point control for a valve with 2 limit switches. ​+Below is a variant of 3-point control for a valve withoutlimit ​switches. ​
  
 <code lua> <code lua>
-function ​main (userId)+function ​valveControl(v) 
 +     
 +    local FULL_PATH_TIME = R(v .. "​pathTime"​) ; local KOEF = 100 / FULL_PATH_TIME 
 +    local HOMING_DELAY = R(v .. "​homingDelay"​) * 60 * 60 -- get seconds from hours  ​
     ​     ​
-       -- copy desired Tfeed to valve PID target temp. +    local auto, autoOpenCmd,​ autoCloseCmd,​ now =  
-    ​W ​( "HeatDistribution.targetTemperature", ​ ​R ​( "recalcFeedTemp" ))     ​+          TRUE("auto_mode"​),​ TRUE(v .. "openCmd"​)TRUE(v .. "closeCmd"), os.time() 
 +                     
 +local motionTmr = function() -- calc. path quant passed from last call 
  
-now = os.time() -- global ​+    local quant = 0 
 +    if (autoOpenCmd or autoCloseCmd) then  
 +          quant = (now - R(v .. "​motionTmr"​)) * KOEF ; SET(v .. "​valveStatus"​) -- opening  
 +           
 +          if autoCloseCmd ​ then   
 +              quant quant * (-1)          -- closing  
 +              UpdReg(v ​.. "​valveStatus",​ 2)  
 +          end  
 +    else  
 +          RESET(v .. "​valveStatus"​) 
 +          quant = 0  
 +    end  -- if motion  
 +    UpdReg(v .. "​motionTmr",​ now)     -- remember last call  
 +    return quant 
 +end -- motionTmr ​
  
-local manOpenCmd, manCloseCmd = R("​manOpenCmd"​),​ R("​manCloseCmd"​) ​    ​-- manual run flags +    local pos Limiter(Round(R(v .. "curPosition")) + motionTmr(), 0, 100) 
-local autoOpenCmd,​ autoCloseCmd ​R("​autoOpenCmd"​),​ R("​autoCloseCmd"​) -- cmds to control valve +    local sp = R(.. "posSetpoint"​) ​ 
-local openSw, closeSw = (R("valveOpenSw"​) ​== 1) , (R("​valveCloseSw"​) == 1) +
-local pullUpFlag, pullDownFlag = (R("​pullUpFlag"​) == 1 ), (R("​pullDownFlag"​) == 1 )  ;  +
- +
-local curPosition = Round(R("​valveCurPos"​) + MotionTimer(autoOpenCmd,​ autoCloseCmd,​ "​Tmr5"​)) ; DEBUG("​curPosition calc. as "​..curPosition) +
- +
-                -- filtering cur position and check limit sw +
-if (curPosition >= 100) or openSw then  +
-    curPosition = 100  +
-        if openSw then  +
-            W ("​pullUpFlag"​1 ) +
-            pullUpFlag = true  +
-        end  +
-end  +
- +
-if ((curPosition < 0) or closeSw) then  +
-    curPosition = 0  +
-        if closeSw then  +
-            W ("​pullDownFlag"​1 )  +
-            pullDownFlag = true  +
-        end  +
-end  +
-                            -- pulling +
-if (curPosition == 100) and not (openSw) and not pullUpFlag then  +
-    ​curPosition = 99  ;                                             ​DEBUG("​ pulling up")  +
-end  +
-if (curPosition == 0 ) and not (closeSw) and not pullDownFlag then  +
-    curPosition = 1   ; ​                                            ​DEBUG("​ pulling down")  +
-end  +
- +
-W ("​valveCurPos",​ curPosition) -- renew current position +
- +
-                                    -- AUTO MODE ----  +
-local valveSp ​= R ( "​valveSp"​ )  ;                                     ​DEBUG("​valveSp ​ "..valveSp) ​                                     +
-local positionError = (curPosition - valveSp) ​   +
- +
-if (positionError ~= 0) and ( autoOpenCmd ~= 1) and (autoCloseCmd ~= 1) then  +
-    -- reset pulling flags befor start  +
-    W ("pullDownFlag" ​, 0 ); W ("​pullUpFlag",​ 0) +
-end  +
- +
-if ( R ( "​distribAutoMode"​) == 1) then +
     ​     ​
-    ​W ("​manOpenCmd"​0 ) -- clear manual cmds +    ​local uShootoShoot = (pos < sp)(pos > sp
-    W ("​manCloseCmd"​0    ​+
     ​     ​
-    ​if (positionError ​== 0)  then  +    ​local homingOut ​TRUE(v .. "homingTmr_out") 
-        W ("autoOpenCmd", 0 ) +    ​local homing ​Timer(not homingOut, HOMING_DELAY,​ FULL_PATH_TIME * 2, v .. "homingTmr") 
-        W ("​autoCloseCmd",​ 0)  +    ​if not homingOut and homing ​then  
-    ​elseif (positionError > 0)   then  +        ​AddInfoMessage("Started homing for valve " .. v)
-                                    DEBUG("​GO DOWN because positionError ​"​..positionError) ; DEBUG(" math.abs error <= 0."..math.abs(positionError)) +
-        W ("autoOpenCmd",​ 0 ) +
-        W ("​autoCloseCmd",​ 1) -- GO DOWN +
-        ​ +
-    ​elseif (positionError < 0)  ​then  +
-                                    DEBUG("GO UP because positionError = "..positionError) ; DEBUG("​ math.abs error <= 0.5 "​..math.abs(positionError)) +
-        W ("​autoOpenCmd",​ 1 ) -- GO UP +
-        W ("​autoCloseCmd",​ 0)  +
-    else  +
-                                    DEBUG("​Undefined if !!! in valve control ")+
     end      end 
-                                  --- MANUAL MODE -----  
-else                ​ 
-                                  -- just copy manual cmd to valve auto cmd 
-    W ("​autoOpenCmd",​ manOpenCmd ) 
-    W ("​autoCloseCmd",​ manCloseCmd) 
     ​     ​
-     ​if ​not openSw then  +    OUT(auto and uShoot and not homing or (not auto and TRUE(v .. "​manOpenCmd"​)), ​v .. "openCmd") 
-        W ("​autoOpenCmd",​ manOpenCmd )  +    ​OUT(auto and oShoot or homing ​or (not auto and TRUE(.. "manCloseCmd")) ​v ​.. "closeCmd") 
-    else  +    ​UpdReg(.. "curPosition", ​pos)
-        W ("​manOpenCmd"​, 0 ) +
-        W ("​autoOpenCmd",​ 0 ) +
-        W ("​valveCurPos"​100) -- renew position after open limit sw +
-    end  +
-    if not closeSw then  +
-        W ("autoCloseCmd", manCloseCmd)  +
-    ​else  +
-        W ("​manCloseCmd",​ 0)  +
-        W ("​autoCloseCmd",​ 0)  +
-        W ("​valveCurPos",​ 0) -- renew position after close limit sw +
-    end  +
-    +
-end  +
- +
-end -- main  +
- +
-function MotionTimer(openCmd,​ downCmd, tmrAlias) +
- +
-local FULL_PATH_TIME = 180 -- sec. full path time +
-local KOEF = 100 / FULL_PATH_TIME +
-local quant = 0  +
---[[                 ​bool ​       string  +
-remembers start time +
-recalc. micro path from the previous call if was in motion +
-adds micro path to current position  +
---                                                  open = true                                       ]]  +
-    local motion = { flag = ((openCmd == 1) or (downCmd == 1)), dir = (openCmd == 1), lastTimeStamp = R(tmrAlias)} +
-    DEBUG("​ motion.flag = "​..tostring(motion.flag).." ​dir  ​"..tostring(motion.dir)..os.date("​%c"​lastTimeStamp))  +
-    local outAlias = tmrAlias.."_out" +
-    local curTmrState = (R(outAlias) == 1) ; DEBUG("​cur "​..tmrAlias.."​ State =  "​..tostring(curTmrState)) +
-                                                ​ +
-    ​if motion.flag then  +
-      quant = (now - R(tmrAlias)) * KOEF +
-          if not motion.dir then  +
-              quant = quant * (-1)  +
-          end  +
-                                                     ​DEBUG("​quant calculated as = "..quant) +
-      W (outAlias, 1) -- "in motion" ​flag +
-                                                     +
-    else  +
-                    DEBUG("​no motion lasts = ") +
-      W (outAlias0  +
-      quant = 0  +
-    end  -- if +
     ​     ​
-(tmrAliasnow)     -- rememeber last call time  +    DBG("auto sp pos autoOpenCmd autoCloseCmd uShoot oShoot ", '​|'​,  
-return quant +           auto, sp, Round(pos, 1), autoOpenCmd,​ autoCloseCmd,​ uShoot, oShoot) 
- +end
-end -- function ​+
 </​code>​ </​code>​
  

Page Tools