LogicMachine Forum
PID in FB editor - Printable Version

+- LogicMachine 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 in FB editor (/showthread.php?tid=3423)



PID in FB editor - KoBra - 17.06.2021

I am using the PID function in FB editor but it is not calculating a value for valve opening. Anybody experienced this before?


RE: PID in FB editor - Daniel - 17.06.2021

As far I know FB PID is based on our script version. Have a read trough these threads and it should help you to debug it.
https://forum.logicmachine.net/showthread.php?tid=3133&pid=20270#pid20270
https://forum.logicmachine.net/showthread.php?tid=3167&pid=20501#pid20501


RE: PID in FB editor - KoBra - 17.06.2021

I get no output at all. I also removed the PID in FB editor and tried with this info https://openrb.com/example-pid-thermostat-with-lm2/

added the PID to the User Libraries 
Code:
PID = {   -- default params   defaults = {     -- invert algorithm, used for cooling     inverted = true,     -- minimum output value     min = 0,     -- maximum output value     max = 100,     -- proportional gain     kp = 0.25,     -- integral gain     ki = 0.42,     -- derivative gain     kd = 0.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 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


and added the following script to the Resident Scripts
Code:
-- init pid algorithm if not p then   p = PID:init({     current = '2/2/8',     setpoint = '32/1/58',     output = '32/1/58'   }) end -- run algorithm p:run()

But my output stays 0.

I want to control a 3 way valve at the output to get a stable temperature at the valve for cooling. 
Current is the measured flow temperature
Setpoint the requested flow temperature
and Output is 0-100% (0-10V)


RE: PID in FB editor - Daniel - 18.06.2021

Your setpoint and the output is same group. For PID to work it must be live device with real feedback.


RE: PID in FB editor - KoBra - 18.06.2021

(18.06.2021, 07:46)Daniel. Wrote: Your setpoint and the output is same group. For PID to work it must be live device with real feedback.

OK, that was the problem, live feedback was already there as it runs to a selector (different PID in cooling and heating)

The problem is in the fact it can't be a virtual object. 
Still in FB editor it won't work.