useful_programs
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
useful_programs [2019/07/31 13:11] – [Debug printing] emozolyak | useful_programs [2020/03/20 10:06] – [3-point control for a valve or servo] emozolyak | ||
---|---|---|---|
Line 47: | Line 47: | ||
end | end | ||
- | function outbit(condition, | + | function outbit(condition, |
if condition then | if condition then | ||
| | ||
Line 53: | Line 53: | ||
| | ||
| | ||
+ | end | ||
+ | |||
+ | function outBit(condition, | ||
+ | local new_value = outbit(condition, | ||
+ | | ||
end | end | ||
Line 135: | Line 140: | ||
<code lua> | <code lua> | ||
- | function DBG( ...) -- ... accepts multiple arguments in a table arg | + | function DBG(...) |
- | + | local tc = tabToStr | |
- | local table_sign | + | |
- | local table_sign_found = false | + | function align2s(s1, s2) -- appends space to smaller string |
- | local tab_s_index = 0 | + | |
- | + | ||
- | if ENABLE_DEBUG then -- should be global in the calling script | + | |
- | + | ||
- | -- find divider | + | |
- | for i = 1, #arg do | + | |
- | if arg[i] | + | |
- | table_sign_found = true | + | |
- | tab_s_index = i | + | |
- | break | + | |
- | end | + | |
- | end | + | |
| | ||
- | if not table_sign_found then | + | if (d ~= 0) then |
- | INFO(tabToStr(arg)) -- outputs table values in a single row | + | |
- | else | + | |
- | local header_t, value_t | + | |
- | + | ||
- | for k = 1, tab_s_index - 1 do | + | |
- | header_t[k] = arg[k] | + | |
- | end | + | |
- | for j = tab_s_index + 1, #arg do | + | |
- | value_t[j - tab_s_index] = tostring(arg[j]) | + | |
- | end | + | |
| | ||
- | if (#header_t ~= #value_t) then | + | |
- | ERROR("column count differs!") | + | |
+ | | ||
+ | Lp = ad / 2 ; Rp = Lp ; INFO("even parts, L R = " | ||
else | else | ||
- | | + | |
- | local delta = # | + | |
- | if delta ~= 0 then | + | |
- | if (delta > 0) then | + | |
- | value_t[g] | + | |
- | else | + | |
- | header_t[g] = header_t[g] | + | |
- | end | + | |
- | end | + | |
- | end -- for | + | |
- | INFO(tabToStr(header_t)) ; INFO(tabToStr(value_t)) | + | |
end | end | ||
+ | return (((d > 0) and {s1, s:rep(Lp) .. s2 .. s: | ||
+ | or | ||
+ | | ||
+ | else | ||
+ | return {s1, s2} | ||
end | end | ||
- | end -- if ENABLE_DEBUG | + | end |
- | + | ||
- | return true | + | |
- | end -- DBG | + | |
+ | if ENABLE_DEBUG then | ||
+ | local arg_str = tc(arg) | ||
+ | local t_s_pos = string.find(arg_str, | ||
+ | |||
+ | if not t_s_pos then | ||
+ | INFO(arg_str) | ||
+ | else | ||
+ | local h_row, v_row = {}, {} | ||
+ | -- header | ||
+ | for w in string.gmatch(arg[1], | ||
+ | h_row[# | ||
+ | end | ||
+ | -- values | ||
+ | for i = 3, #arg do | ||
+ | v_row[# | ||
+ | end | ||
+ | |||
+ | if (#h_row ~= #v_row) then | ||
+ | ERROR(" | ||
+ | INFO(" | ||
+ | return | ||
+ | else | ||
+ | for g = 1, #h_row do | ||
+ | h_row[g], v_row[g] = unpack(align2s(h_row[g], | ||
+ | end | ||
+ | end | ||
+ | INFO(tc(h_row)) ; INFO(tc(v_row)) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
function tabToStr(t) | function tabToStr(t) | ||
local s = "" | local s = "" | ||
for i = 1, #t do | for i = 1, #t do | ||
- | s = s .. tostring(t[i]) .. ' ' | + | |
+ | | ||
end -- for | end -- for | ||
return s | return s | ||
- | end | + | end |
</ | </ | ||
+ | Then the print output can be enhanced like this: | ||
+ | {{ : | ||
The // | The // | ||
Line 267: | Line 279: | ||
<code lua> | <code lua> | ||
- | function Timer (bool_input, | + | function Timer (bool_input, |
-- bool sec to ON sec to OFF string alias | -- bool sec to ON sec to OFF string alias | ||
+ | |||
+ | local now , nowString, curTimeStamp, | ||
+ | os.time(), os.date(" | ||
- | local now , nowString, curTimeStamp, | + | DBG("Timer State Stamp", "|", tmrAlias, |
- | os.date("%c", | + | |
- | R(tmrAlias), | + | |
- | TRUE(tmrAlias .." | + | |
- | + | ||
- | DEBUG(" | + | |
- | DEBUG ("cur " | + | |
-- protects from malfunctions on very first run | -- protects from malfunctions on very first run | ||
if curTimeStamp == 0 then | if curTimeStamp == 0 then | ||
- | | + | |
WriteReg(tmrAlias, | WriteReg(tmrAlias, | ||
return nil, 0 -- countdown | return nil, 0 -- countdown | ||
end | end | ||
+ | |||
+ | -- in and output are equal | ||
- | -- in and output are equal | + | if (bool_input == curTmrState) then |
- | | + | WriteReg(tmrAlias, |
- | WriteReg(tmrAlias, | + | |
return curTmrState, | return curTmrState, | ||
- | | + | |
- | -- TON | + | -- TON |
- | elseif bool_input then | + | elseif bool_input then |
- | if ((now - GetReg(tmrAlias)) > onDelay) then | + | if ((now - curTimeStamp) > onDelay) then |
- | WriteReg(tmrAlias .." | + | SET(tmrAlias .." |
- | DEBUG(" | + | |
| | ||
else | else | ||
- | local countDown = onDelay - (now - curTimeStamp) | + | local countDown = onDelay - (now - curTimeStamp) |
- | DEBUG(" | + | |
return curTmrState, | return curTmrState, | ||
end | end | ||
+ | |||
+ | -- TOFF | ||
+ | elseif not bool_input then | ||
| | ||
- | -- TOFF | + | |
- | elseif not bool_input then | + | |
- | | + | return false, 0 |
- | | + | |
- | DEBUG(" | + | |
- | return false | + | |
else | else | ||
- | local countDown = offDelay - (now - curTimeStamp) | + | local countDown = offDelay - (now - curTimeStamp) |
- | DEBUG (" | + | |
return curTmrState, | return curTmrState, | ||
end | end | ||
Line 602: | 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 |
<code lua> | <code lua> | ||
- | function | + | function |
+ | |||
+ | local FULL_PATH_TIME = R(v .. " | ||
+ | local HOMING_DELAY = R(v .. " | ||
| | ||
- | -- copy desired Tfeed to valve PID target temp. | + | local auto, autoOpenCmd, |
- | | + | TRUE("auto_mode" |
+ | |||
+ | 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 .. " | ||
+ | |||
+ | if autoCloseCmd | ||
+ | quant = quant * (-1) -- closing | ||
+ | UpdReg(v | ||
+ | end | ||
+ | else | ||
+ | RESET(v .. " | ||
+ | quant = 0 | ||
+ | end -- if motion | ||
+ | UpdReg(v .. " | ||
+ | return quant | ||
+ | end -- motionTmr | ||
- | local manOpenCmd, manCloseCmd = R(" | + | local pos = Limiter(Round(R(v .. "curPosition")) + motionTmr(), 0, 100) |
- | local autoOpenCmd, | + | local sp = R(v .. "posSetpoint" |
- | local openSw, closeSw = (R("valveOpenSw" | + | |
- | local pullUpFlag, pullDownFlag = (R(" | + | |
- | + | ||
- | local curPosition = Round(R(" | + | |
- | + | ||
- | -- filtering cur position and check limit sw | + | |
- | if (curPosition >= 100) or openSw then | + | |
- | curPosition = 100 | + | |
- | if openSw then | + | |
- | W (" | + | |
- | pullUpFlag = true | + | |
- | end | + | |
- | end | + | |
- | + | ||
- | if ((curPosition < 0) or closeSw) then | + | |
- | curPosition = 0 | + | |
- | if closeSw then | + | |
- | W (" | + | |
- | pullDownFlag = true | + | |
- | end | + | |
- | end | + | |
- | -- pulling | + | |
- | if (curPosition == 100) and not (openSw) and not pullUpFlag then | + | |
- | | + | |
- | end | + | |
- | if (curPosition == 0 ) and not (closeSw) and not pullDownFlag then | + | |
- | curPosition = 1 ; | + | |
- | end | + | |
- | + | ||
- | W (" | + | |
- | + | ||
- | -- AUTO MODE ---- | + | |
- | local valveSp | + | |
- | local positionError = (curPosition - valveSp) | + | |
- | + | ||
- | if (positionError ~= 0) and ( autoOpenCmd ~= 1) and (autoCloseCmd ~= 1) then | + | |
- | -- reset pulling flags befor start | + | |
- | W ("pullDownFlag" | + | |
- | end | + | |
- | + | ||
- | if ( R ( " | + | |
| | ||
- | | + | |
- | W (" | + | |
| | ||
- | | + | |
- | W ("autoOpenCmd", 0 ) | + | |
- | W (" | + | |
- | | + | |
- | DEBUG(" | + | |
- | W ("autoOpenCmd", | + | |
- | W (" | + | |
- | | + | |
- | | + | |
- | DEBUG("GO UP because positionError = "..positionError) ; DEBUG(" | + | |
- | W (" | + | |
- | W (" | + | |
- | else | + | |
- | DEBUG(" | + | |
end | end | ||
- | --- MANUAL MODE ----- | ||
- | else | ||
- | -- just copy manual cmd to valve auto cmd | ||
- | W (" | ||
- | W (" | ||
| | ||
- | | + | OUT(auto and uShoot and not homing or (not auto and TRUE(v .. " |
- | W (" | + | |
- | else | + | |
- | W (" | + | |
- | W (" | + | |
- | W (" | + | |
- | end | + | |
- | if not closeSw then | + | |
- | W ("autoCloseCmd", manCloseCmd) | + | |
- | | + | |
- | W (" | + | |
- | W (" | + | |
- | W (" | + | |
- | end | + | |
- | + | ||
- | end | + | |
- | + | ||
- | end -- main | + | |
- | + | ||
- | function MotionTimer(openCmd, | + | |
- | + | ||
- | local FULL_PATH_TIME = 180 -- sec. full path time | + | |
- | local KOEF = 100 / FULL_PATH_TIME | + | |
- | local quant = 0 | + | |
- | --[[ | + | |
- | 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(" | + | |
- | local outAlias = tmrAlias.."_out" | + | |
- | local curTmrState = (R(outAlias) == 1) ; DEBUG(" | + | |
- | | + | |
- | | + | |
- | quant = (now - R(tmrAlias)) * KOEF | + | |
- | if not motion.dir then | + | |
- | quant = quant * (-1) | + | |
- | end | + | |
- | | + | |
- | W (outAlias, 1) -- "in motion" | + | |
- | + | ||
- | else | + | |
- | DEBUG(" | + | |
- | W (outAlias, 0) | + | |
- | quant = 0 | + | |
- | end -- if | + | |
| | ||
- | W (tmrAlias, now) -- rememeber last call time | + | DBG("auto sp pos autoOpenCmd autoCloseCmd uShoot oShoot ", ' |
- | return quant | + | auto, sp, Round(pos, 1), autoOpenCmd, |
- | + | end | |
- | end -- function | + | |
</ | </ | ||
useful_programs.txt · Last modified: 2024/05/27 13:23 by emozolyak