This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

PID algorithm questions
#1
Hi, I'm trying to setup underfloor heating with SE Valves

This is my setup/configuration, but I have some questions:

  1. Is this how it should be done?
  2. If I want to use GA 1/1/3 to indicate if the heating is On or Off with 1 bit 01.001 switching how can I do that?
  3. What if I want heating in more rooms? Do I just make a new Residential script and according Group Addresses?
  4. he Manual mode, it says that the PID algorithm is stopped when this object value is 1, is it stopped or just paused? Should I use it to stop heating if my window is open in that room?
  5. Again about the Manual mode, I have window switches connected to a knx binary input, and the way I use it is with 1bit - 01.009, so that it says Close(1) if the window is closed and Open(0) if the window is open, but thats reversed, how to fix that?

Group Addresses:

1/1/0 Test Room Setpoint Temp - (2 byte - 09-001 Temperature) - Temp setpoint visualization
1/1/1 Test Room Output Value - (1 byte - 05.001 scale) - SE Valve, Group Object: 0: Valve Actuating value - Drive to position
1/1/2 Test Room Actual Position - (1 byte - 05.001 scale) - SE Valve, Group Object: 2: Actual valve position - Indicate actual valve position
1/1/3 Test Room Heating On/Off - (1 bit - 01.001 switch) -
1/1/4 Test Room Window Contact - (1 bit - 01.009 open/close) - Binary input, Group Object: 0: Window open/close
1/1/5 Test Room Current Temp - (2 byte - 09-001 Temperature) - PIR with temp, Group Object: 11: Temperature sensor:Output


Scripting -> Common functions

Code:
-- 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 PID:setoutput()   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   self:setoutput()   -- save previous value   self.previous = current   return self.output end

Scripting -> Resident -> PID Test Room (Sleep interval 10 seconds)

Code:
-- init pid algorithm if not p then   p = PID:init({     current = '1/1/5',     setpoint = '1/1/0',     output = '1/1/1', manual = '1/1/4', min = '0', max = '100', kp = '1', ki = '1', kd = '1'   }) end -- run algorithm p:run()
Reply


Messages In This Thread
PID algorithm questions - by Novodk - 15.04.2023, 12:34
RE: PID algorithm questions - by admin - 17.04.2023, 07:52

Forum Jump: