PID Thermostat - cooling mode - Printable Version +- Logic Machine Forum (https://forum.logicmachine.net) +-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1) +--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8) +--- Thread: PID Thermostat - cooling mode (/showthread.php?tid=333) |
PID Thermostat - cooling mode - hebeanflorin - 29.06.2016 I have a LM2 and I try to use the PID script: http://openrb.com/example-pid-thermostat-with-lm2/ In heating mode it's work great but in cooling mode it's not working ( the value output =0) Can you tell me what I need to do? RE: PID Thermostat - cooling mode - admin - 29.06.2016 Try setting inverted = true on line 5. RE: PID Thermostat - cooling mode - hebeanflorin - 29.06.2016 (29.06.2016, 07:19)admin Wrote: Try setting inverted = true on line 5. Thks. I try this but the value output it's still =0. RE: PID Thermostat - cooling mode - admin - 29.06.2016 Just did a quick simulation and it work correctly for cooling. Have you changed any of the gain values or any other parameters like min/max? Enabling inverted mode just sets all gains to be negative. RE: PID Thermostat - cooling mode - hebeanflorin - 29.06.2016 I changed only the value for line 5, inverted=true. I still got the valuea output=0 (you can see in the picture attached). The resident script that I use is this: -- init pid algorithm if not p then p = PID:init({ inverted=true, current = '10/1/3', setpoint = '10/1/0', output = '10/1/2' }) end -- run algorithm p:run() The script that I use is this: PID = { -- default params defaults = { -- invert algorithm, used for cooling inverted = true, -- minimum output value min = 0, -- maximum output value max = 100, -- proportional gain kp = 1, -- integral gain ki = 1, -- derivative gain kd = 1, } } -- PID init, returns new PID object function PID:init(params) local n = setmetatable({}, { __index = PID }) local k, v -- set user parameters n.params = params -- copy parameters that are set by user for k, v in pairs(PID.defaults) do if n.params[ k ] == nil then n.params[ k ] = v end end -- reverse gains in inverted mode if n.params.inverted then n.params.kp = -n.params.kp n.params.ki = -n.params.ki n.params.kd = -n.params.kd end return n end -- resets algorithm on init or a switch back from manual mode function PID:reset() -- previous value self.previous = grp.getvalue(self.params.current) -- reset iterm self.iterm = 0 -- last running time self.lasttime = os.time() -- clamp iterm self:clampiterm() end -- clamps iterm value function PID:clampiterm() self.iterm = math.max(self.iterm, self.params.min) self.iterm = math.min(self.iterm, self.params.max) end -- clamp and set new output value function PIDetoutput() local t, object, value self.output = math.max(self.output, self.params.min) self.output = math.min(self.output, self.params.max) value = math.floor(self.output) local t = type(self.params.output) -- write to output if object is set if t == 'string' or t == 'table' then if t == 'string' then self.params.output = { self.params.output } end for _, output in ipairs(self.params.output) do grp.write(output, value, dt.scale) end end end -- algorithm step, returns nil when disabled or no action is required, output value otherwise function PID:run() local result -- get manual mode status local manual = self.params.manual and grp.getvalue(self.params.manual) or false -- in manual mode, do nothing if manual then self.running = false -- not in manual, check if reset is required after switching on elseif not self.running then self:reset() self.running = true end -- compute new value if not in manual mode if self.running then -- get time between previous and current call local now = os.time() self.deltatime = now - self.lasttime self.lasttime = now -- run if previous call was at least 1 second ago if self.deltatime > 0 then result = self:compute() end end return result end -- computes new output value function PID:compute() local current, setpoint, deltasc, deltain, output -- get input values current = grp.getvalue(self.params.current) setpoint = grp.getvalue(self.params.setpoint) -- delta between setpoint and current deltasc = setpoint - current -- calculate new iterm self.iterm = self.iterm + self.params.ki * self.deltatime * deltasc self:clampiterm() -- delta between current and previous value deltain = current - self.previous -- calculate output value self.output = self.params.kp * deltasc + self.iterm self.output = self.output - self.params.kd / self.deltatime * deltain -- write to output selfetoutput() -- save previous value self.previous = current return self.output end RE: PID Thermostat - cooling mode - admin - 29.06.2016 The same script is working correctly on my device. What sleep interval do you have set for PID resident script. Is there anything in the Error log tab? RE: PID Thermostat - cooling mode - hebeanflorin - 29.06.2016 Sleep interval (seconds)=10 I have some errors in Error log Tab ( attached). RE: PID Thermostat - cooling mode - admin - 29.06.2016 Looks like your PID user library has some errors, maybe you have deleted some code by accident? RE: PID Thermostat - cooling mode - hebeanflorin - 29.06.2016 The code is the same with this: http://openrb.com/example-pid-thermostat-with-lm2/#codesyntax_1 I don't know if I need to copy this: Usage p = PID:init(parameters) p:run() I deleted all empty spaces and now it's working! |