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 [2020/02/21 13:46] – [Debug printing] emozolyak | useful_programs [2021/02/12 10:17] – [Processing double float numbers] emozolyak | ||
---|---|---|---|
Line 153: | Line 153: | ||
Lp = ad / 2 ; Rp = Lp ; INFO(" | Lp = ad / 2 ; Rp = Lp ; INFO(" | ||
else | else | ||
- | Lp = math.floor(ad / 2) ; Rp = Lp + 1 ; INFO(" | + | Lp = math.floor(ad / 2) ; Rp = Lp + 1 ; INFO(" |
end | end | ||
return (((d > 0) and {s1, s:rep(Lp) .. s2 .. s: | return (((d > 0) and {s1, s:rep(Lp) .. s2 .. s: | ||
Line 181: | Line 181: | ||
if (#h_row ~= #v_row) then | if (#h_row ~= #v_row) then | ||
- | ERROR(" | + | ERROR(" |
INFO(" | INFO(" | ||
return | return | ||
Line 228: | Line 228: | ||
end | end | ||
+ | </ | ||
+ | |||
+ | For complex tables print, you can use the following function: | ||
+ | <code lua> | ||
+ | function tprint(t, indent) | ||
+ | if not indent then indent = 0 end | ||
+ | for k, v in pairs(t) do | ||
+ | local formatting = string.rep(' | ||
+ | if type(v) == " | ||
+ | ERROR(formatting) | ||
+ | tprint(v, indent + 1) -- recursive call | ||
+ | else | ||
+ | if type(v) == " | ||
+ | v = v and " | ||
+ | end | ||
+ | ERROR(formatting .. v) | ||
+ | end | ||
+ | end -- for | ||
+ | end -- tprint | ||
</ | </ | ||
Line 608: | Line 627: | ||
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 | + | |
</ | </ | ||
Line 833: | Line 769: | ||
return false -- nothing happened | return false -- nothing happened | ||
end -- P_TRIG | end -- P_TRIG | ||
+ | |||
+ | -- multiple ids or aliases read, returns table, have to be unpack() 'ed | ||
+ | -- usage: v1, v2, v3... = unpack(mRead(1, | ||
+ | function mRead(...) | ||
+ | local results = {} | ||
+ | for i = 1, #arg do | ||
+ | local param = arg[i] | ||
+ | -- INFO(" | ||
+ | results[i] = GetReg(param) | ||
+ | | ||
+ | if (#results == 1) then | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | end | ||
</ | </ | ||
Line 925: | Line 877: | ||
</ | </ | ||
+ | ===== Curve handler ===== | ||
+ | Library | ||
+ | <code lua - curves.lib> | ||
+ | function GetCurveValue ( curve_register, | ||
+ | --[[ | ||
+ | --Curve handler | ||
+ | INPUT: | ||
+ | Put curve register as first argument and X coordinate as second. | ||
+ | OUTPUT: | ||
+ | Get as result status if it is inside curve range of outside(false) and the Y value as second output argument | ||
+ | | ||
+ | EXAMPLE: | ||
+ | curve_status, | ||
+ | --]] | ||
+ | table = cjson.decode( R ( curve_register ) ) | ||
+ | -- inRangeCurve( table, x_to_find_y ) | ||
+ | for _, value in ipairs( table ) do --piecewise handler inside range of the curve | ||
+ | if ( value.range[1] <= x_to_find_y and x_to_find_y < value.range[2] ) then | ||
+ | -- in_range_status, | ||
+ | in_range_status, | ||
+ | return in_range_status, | ||
+ | end | ||
+ | end | ||
+ | if x_to_find_y < table[1].range[1] then -- behaivior for outside left-sided | ||
+ | -- in_range_status, | ||
+ | in_range_status, | ||
+ | return in_range_status, | ||
+ | elseif x_to_find_y > table[# | ||
+ | -- in_range_status, | ||
+ | in_range_status, | ||
+ | return in_range_status, | ||
+ | end | ||
+ | |||
+ | return in_range_status, | ||
+ | end | ||
+ | </ | ||
+ | Example of usage: | ||
+ | <code lua - curves getter> | ||
+ | include " | ||
+ | |||
+ | function main (userId) | ||
+ | |||
+ | local t = os.date(" | ||
+ | current_hour = tonumber(t.hour) | ||
+ | curve_status, | ||
+ | WriteReg(" | ||
+ | |||
+ | end | ||
+ | </ | ||
+ | |||
+ | ===== Processing double float numbers ===== | ||
+ | |||
+ | <code lua> | ||
+ | function d2float(n) | ||
+ | |||
+ | local function getBits(input_num, | ||
+ | -- works with number and len | ||
+ | local tab = {} | ||
+ | local max_i = length - 1 | ||
+ | local remainder = input_num | ||
+ | | ||
+ | for i = max_i, 0, -1 do | ||
+ | local bit_ = (remainder - 2^i >= 0) and ' | ||
+ | table.insert(tab, | ||
+ | end | ||
+ | return tab | ||
+ | end | ||
+ | |||
+ | local function getNumberFromTab(tab, | ||
+ | local result_str = "" | ||
+ | |||
+ | for i = start, (start + length - 1) do | ||
+ | result_str = result_str .. tostring(tab[i]) | ||
+ | end | ||
+ | return tonumber(result_str, | ||
+ | end | ||
+ | |||
+ | local NaN = tonumber(" | ||
+ | local result_tab = {} | ||
+ | |||
+ | -- get a table of " | ||
+ | if (type(n) == " | ||
+ | result_tab = getBits(n, 64) | ||
+ | elseif (type(n) == " | ||
+ | local tmpS = '' | ||
+ | for i = 1, #n do | ||
+ | tmpS = tmpS .. table.concat(getBits(n[i], | ||
+ | end | ||
+ | |||
+ | for j=1, #tmpS do | ||
+ | table.insert(result_tab, | ||
+ | end | ||
+ | else | ||
+ | ERROR(" | ||
+ | end | ||
+ | |||
+ | local sign, exp, mantissa = 0, 0, 0 | ||
+ | local fraction_table = {} -- fraction part table | ||
+ | |||
+ | sign = ((result_tab[1] == " | ||
+ | exp = getNumberFromTab(result_tab, | ||
+ | |||
+ | for i = 13, 64 do | ||
+ | table.insert(fraction_table, | ||
+ | end | ||
+ | |||
+ | for j = 1, 52 do | ||
+ | if (fraction_table[j]== " | ||
+ | mantissa = mantissa +(2 ^(-1 * j)) -- calc. mantissa by summing individual bits | ||
+ | end | ||
+ | end | ||
+ | mantissa = mantissa + 1 | ||
+ | local result_num = sign * (2 ^ (exp - 1023)) * mantissa | ||
+ | |||
+ | ----------------------------------------- exceptions ---------------------------------- | ||
+ | if exp == 0 then -- subnormals | ||
+ | | ||
+ | end | ||
+ | |||
+ | if exp == 0x7ff then -- nan | ||
+ | | ||
+ | end | ||
+ | |||
+ | | ||
+ | end | ||
+ | </ | ||
useful_programs.txt · Last modified: 2024/05/27 13:23 by emozolyak