Logic Machine Forum
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 PIDConfusedetoutput()
      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
      selfConfusedetoutput()
     
      -- 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!