Multi heaters and sensors, PID and hysterisis heating script

For heating/cooling related questions in Domoticz

Moderator: leecollings

Post Reply
greg
Posts: 5
Joined: Monday 26 December 2016 22:52
Target OS: Linux
Domoticz version:
Contact:

Multi heaters and sensors, PID and hysterisis heating script

Post by greg »

Hello,

As a new Domoticz user and member of this forum, it's my pleasure to share the script i've developed to heat my chalet in the french Alps.

This script provides heating control in a room, providing different modes (Comfort, Eco), according to presence in the room and to a couple of setpoints. The heating control is proposed through two differents algorithms (Hysterisis or PID). The script supports multiple temperature control devices used in fallback, and multiple heating devices used simultaneously.
A power consumption computation is made, based on the declared power consumption of each heating device.

Required Domoticz configuration :

- A Thermostat to set the comfort temperature, created with Dummy hardware and a Thermostat device
Variable : sSetPointConfortDeviceName

- A Thermostat to set the eco temperature, created with Dummy hardware and a Thermostat device
Variable : sSetPointEcoDeviceName

- A Mode switch to set and program with timers the heating scenarii, created with Dummy hardware and a Selector Switch device
Variable : sHeatingModeDeviceName

- A Control Mode switch to switch between the Hysterisis and PID ways of control.
Variables : sHeatingControlModeDeviceName
sHeatingControlModePIDName, sHeatingControlModeHysteresisName are used for the name given to either mode.

- A Presence detection switch. The switch would be controlled either by hand or by some external scripts/commands.
Variable : sPresenceDeviceName

- An Electricity consumption meter, created with an Instant+Counter meter
Variable : sPowerMeterDeviceName

Script configuration

- A few variables need to be set in the script, to fit with your Domoticz instance.

- Heaters
One or more heaters have to be declared in an array, together with their power consumption and commands.
Variable : aHeatingDeviceNames

- Temperature sensors
They are declared in a array, with fall back mode implemented. The script is written for sensors that gather both temperature and humidity.
Variable : aTempSensorDeviceNames

- User variables
- fISumLast, a float value initialized to 0, that's the PID current integral value ;
- fTempLastInput, a float value initialized to 0, used for the PID derivative computation ;
- fSetpointLast, a float value initialized to 0, used to check a setpoint change ;
- iResetDeviceMeterTime, an integer value initialized to 0, used to record the power meter reset time.

The PID parameters are to be determined for your own installation. Three parameters need to be calculated,
according to the following formulas :

Kp = ΔPV / ΔCO -- On steady temperature states, ratio of temperature difference for command difference
Tp -- Time needed to reach 63% of the setpoint
θp -- Time between action on the heating and measurable reaction of the temperature sensor
Tc -- Response time, highest value among 0.1Tp or 0.8θp (agressive), 1Tp or 8θp (middle), 10Tp or 80θp (conservative)
Kc = P = (1/Kp)*(Tp/(θp+Tc)) -- Our fPIDKp
I = Kc/Ti -- Our fPIDKi
Td = (Tp x θp)/(2Tp+θp) -- Needed to compute the last constant
D = Kc * Td -- Our fPIDKd

The resulting temperature control is very good for my usage. Here is a temperature graph for going to a setpoint of 15 Celsius :
pid-regul-temp-1s1.png
pid-regul-temp-1s1.png (100.14 KiB) Viewed 5246 times
I thank very much the authors of the following web pages for their wonderful work :

http://brettbeauregard.com/blog/category/pid/
http://www.rhaaa.fr/regulation-pid-comment-la-regler-12
http://controlguru.com

I also thank a lot the members of this forum, and the ones of the french easydomoticz.com forum.

If this script is useful to you, i would be very happy to read about it, especially if it brought more comfort
and energy saving.

Thank you

Greg

Code: Select all

--[[

Type : Time
Name : script_time_heating.lua
Description : Controls heating in a room with hysterisis or PID method
Usage : Place in scripts/lua directory of Domoticz instance

This script provides heating control in a room, providing different modes (Comfort, Eco), according
to presence in the room and to a couple of setpoints. The heating control is proposed through
two differents algorithms (Hysterisis or PID). The script supports multiple temperature control
devices used in fallback, and multiple heating devices used simultaneously.
A power consumption computation is made, based on the declared power consumption of each heating device.

Required Domoticz configuration :

- A Thermostat to set the comfort temperature, created with Dummy hardware and a Thermostat device
  Variable : sSetPointConfortDeviceName

- A Thermostat to set the eco temperature, created with Dummy hardware and a Thermostat device
  Variable : sSetPointEcoDeviceName

- A Mode switch to set and program with timers the heating scenarii, created with Dummy hardware and a Selector Switch device
  Variable : sHeatingModeDeviceName

- A Control Mode switch to switch between the Hysterisis and PID ways of control.
  Variables : sHeatingControlModeDeviceName
  sHeatingControlModePIDName, sHeatingControlModeHysteresisName are used for the name given to either mode.

- A Presence detection switch. The switch would be controlled either by hand or by some external scripts/commands.
  Variable : sPresenceDeviceName

- An Electricity consumption meter, created with an Instant+Counter meter
  Variable : sPowerMeterDeviceName

- Heaters
  One or more heaters have to be declared in an array, together with their power consumption and commands.
  Variable : aHeatingDeviceNames

- Temperature sensors
  They are declared in a array, with fall back mode implemented. The script is written for sensors that gather both temperature and humidity.
  Variable : aTempSensorDeviceNames

- User variables
  - fISumLast, a float value initialized to 0, that's the PID current integral value ;
  - fTempLastInput, a float value initialized to 0, used for the PID derivative computation ;
  - fSetpointLast, a float value initialized to 0, used to check a setpoint change ;
  - iResetDeviceMeterTime, an integer value initialized to 0, used to record the power meter reset time.

The PID parameters are to be determined for your own installation. Three parameters need to be calculated,
according to the following formulas :

Kp = ΔPV / ΔCO  -- On steady temperature states, ratio of temperature difference for command difference
Tp -- Time needed to reach 63% of the setpoint
θp -- Time between action on the heating and measurable reaction of the temperature sensor
Tc -- Response time, highest value among 0.1Tp or 0.8θp (agressive), 1Tp or 8θp (middle), 10Tp or 80θp (conservative)
Kc = P = (1/Kp)*(Tp/(θp+Tc)) -- Our fPIDKp
I = Kc/Ti -- Our fPIDKi
Td = (Tp x θp)/(2Tp+θp) -- Needed to compute the last constant
D = Kc * Td -- Our fPIDKd

This script distributed under the GPL license. Please see https://www.gnu.org/licenses/gpl.html
--]]

-- Zone name
local sZoneName = 'Living room'

-- Setpoint
local sSetPointConfortDeviceName = 'Thermostat Confort'         -- Thermostat for comfort Setpoint
local sSetPointEcoDeviceName = 'Thermostat Eco'                 -- Thermostat for eco Setpoint

-- Power Meter
local sPowerMeterDeviceName = 'Consommation Chauffage'          -- Power meter based on configured heating devices consumption

-- Modes
-- These modes belong to the heating mode selector switch
local sHeatingModeDeviceName = 'Mode Chauffage'
local sHeatingModeComfortName = 'Confort'
local sHeatingModeEcoName = 'Eco'
local sHeatingModeForceOnName = 'Force'
local sHeatingModeFrostFreeName = 'Off'

-- Heating control mode (PID or Hysteresis)
local sHeatingControlModeDeviceName = 'Mode Controle Chauffage'
local sHeatingControlModePIDName = 'PID'                             -- Selection switch name for PID
local sHeatingControlModeHysteresisName = 'Hysteresis'         -- Selection switch name for hysterisis mode

local fHysteresis = 0.4                          -- Hysterisis value

-- Sensors
-- Will be choosen in fallback. Second parameter is a delta to the first temp sensor
local aTempSensorDevices = {
                             { 'Living-room 1',0 } ,

                             { 'Chambre Enfant',1.2 }     -- The room is usually ~1.2 deg hotter than the living room
                           }

local sPresenceDeviceName = 'Presence'          -- Presence device switch. Heating goes in Eco mode when Presence is Off.

-- Heaters
-- Domoticz Device Name, power in Watts, On command, Off command.
local aHeatingDevices = {
                             { 'Hors-Gel Radiateur Salon Est', 1500 , 'Off AFTER 3', 'On' } ,

                             { 'Hors-Gel Radiateur Salon Sud', 1500 , 'Off AFTER 3', 'On' }

                        }

-- PID - Proportional, Integral, Derivative - Parameters

local iHeatingCycleDuration = 10 -- Duration of a heating cycle in minutes, to be adapted to the heating devices
local fPIDKp = 113  -- Change this !
local fPIDKi = 0.05 -- Change this !
local fPIDKd = 30045 -- Change this !

-- Alerts
local sEmailContact = '[email protected]'

-- Debug
local bDebug = true
---------------------------------------------- End of configuration section ----------------------------------------------

-- Variables

local fCurrentTemp = 1000

-- Statics variables
-- Heating commands, constants not to be changed
local sHeatingOnCommand = 'ON'
local sHeatingOnForCommand = 'ONFOR'
local sHeatingOffCommand = 'OFF'

-- Functions

function prDebug(sString)
  if(bDebug) then
   print ( sString )
  end
end

function addCommand( sDevice, sCommand )
   commandArray[#commandArray+1] = { [sDevice] = sCommand }
end

function timeDifference(sDeviceName)
   sDeviceTimeChanged = otherdevices_lastupdate[sDeviceName]
   sYear = string.sub(sDeviceTimeChanged, 1, 4)
   sMonth = string.sub(sDeviceTimeChanged, 6, 7)
   sDay = string.sub(sDeviceTimeChanged, 9, 10)
   sHour = string.sub(sDeviceTimeChanged, 12, 13)
   sMinutes = string.sub(sDeviceTimeChanged, 15, 16)
   sSeconds = string.sub(sDeviceTimeChanged, 18, 19)
   t1 = os.time()
   t2 = os.time{year=sYear, month=sMonth, day=sDay, hour=sHour, min=sMinutes, sec=sSeconds}
   return os.difftime (t1, t2)
end

function round(fNumber, iPrecision)
  local iMult = 10^(iPrecision or 0)
  return math.floor(fNumber * iMult + 0.5) / iMult
end

function commandHeating(sCommand,iTime)
 local fIntervalEnergy = 0
 local fInstantPower = 0

      -- Send command to heaters, calculate power and energy

       for iHeatingDeviceIndex = 1, #aHeatingDevices do
        local sActiveHeatingDevice = aHeatingDevices[iHeatingDeviceIndex]
        fInstantPower = fInstantPower + sActiveHeatingDevice[2]
        if( sCommand == sHeatingOnForCommand ) then
          fIntervalEnergy = fIntervalEnergy + (tonumber(fInstantPower) / 60 ) * iHeatingCycleDuration 
        else
           fIntervalEnergy = fIntervalEnergy + tonumber(fInstantPower) / 60 
        end
        if( sCommand == sHeatingOnCommand ) then
         prDebug('Heating device : - '..sActiveHeatingDevice[1]..' - , power : ' .. sActiveHeatingDevice[2]..' Watts gets command : '..sActiveHeatingDevice[3])
         addCommand(sActiveHeatingDevice[1],sActiveHeatingDevice[3])
        end
        if( sCommand == sHeatingOnForCommand ) then 
         prDebug('Heating device : - '..sActiveHeatingDevice[1]..' - , power : ' .. sActiveHeatingDevice[2]..' Watts gets command : '..sActiveHeatingDevice[3]..' FOR '..tostring(iTime))
         addCommand(sActiveHeatingDevice[1],sActiveHeatingDevice[3] .. ' FOR ' .. tostring(iTime))  -- Can be missed :-( --> zwave!
        end
        if( sCommand == sHeatingOffCommand ) then
         prDebug('Heating device : - '..sActiveHeatingDevice[1]..' - , power : ' .. sActiveHeatingDevice[2]..' Watts gets command : '..sActiveHeatingDevice[4])
         addCommand(sActiveHeatingDevice[1],sActiveHeatingDevice[4])
        end
       end

      -- Energy accounting
       -- Get current power-meter values
       sCurrentPower,sCurrentTotalEnergy = string.match(otherdevices_svalues[sPowerMeterDeviceName], "(%d+%.*%d*);(%d+%.*%d*)" )
       local fCurrentTotalEnergy = tonumber(sCurrentTotalEnergy)
       if(sCommand == sHeatingOffCommand ) then -- No instant power consumption
         addCommand('UpdateDevice', iPowerMeterIdx .. '|0|0;' .. sCurrentTotalEnergy)
         return
       end

       fUpdatedEnergy = fCurrentTotalEnergy + fIntervalEnergy
       if(sCommand == sHeatingOnForCommand ) then -- System heating iTimes minutes
         addCommand('UpdateDevice', iPowerMeterIdx .. '|0|' .. fInstantPower .. ';' .. fUpdatedEnergy)
         addCommand('Variable:iResetDeviceMeterTime',tostring(iTime))
       end

       if(sCommand == sHeatingOnCommand ) then -- System in On/Off mode, heating happends until a stop command
       -- Total instant power update
         addCommand('UpdateDevice', iPowerMeterIdx .. '|0|' .. fInstantPower .. ';' .. fUpdatedEnergy)
       end
end


-- Init
commandArray = {}
iPowerMeterIdx = otherdevices_idx[sPowerMeterDeviceName]

-- Get time
local sCurrentTime = string.sub(os.date("%X"), 1, 5)
local sCurrentMinute = os.date('%M')

-- Check temperature sensors, choose the first one with response time < 10 min
-- set setpoint delta

for iTempSensorIndex = 1, #aTempSensorDevices do
      prDebug('Temp Sensor Device : '..aTempSensorDevices[iTempSensorIndex][1]..' - Delta to reference : ' .. aTempSensorDevices[iTempSensorIndex][2] )
      sTempSensorDeviceName = aTempSensorDevices[iTempSensorIndex][1]
      sTempSensorDeltaToReference = aTempSensorDevices[iTempSensorIndex][2]
  -- Last seen ?
      local sTempSensorLastSeen = string.sub(os.date("!%X", timeDifference(sTempSensorDeviceName)), 1, 5)
        -- if (sTempSensorLastSeen >= '00:10' and sTempSensorLastSeen < '00:12') then
        if (sTempSensorLastSeen >= '00:10') then
                  prDebug('Temp sensor missing')
          addCommand('SendEmail',sZoneName..' Heating Alert#Temperature sensor '..sTempSensorDeviceName..' has not updated for more than 10m.#'..sEmailContact)
        else -- Sensor has been seen, we use it
          sCurrentTemp,sCurrentHumidity = string.match(otherdevices_svalues[sTempSensorDeviceName],"(%d+%.*%d*);(%d+%.*%d*)")
          fCurrentTemp = tonumber(sCurrentTemp) + tonumber(sTempSensorDeltaToReference)
          prDebug ('Current measured temperature and delta applied : '..fCurrentTemp)
          break
        end
end
if ( fCurrentTemp == 1000) then return commandArray end -- No temp sensor, end of execution

-- Check for energy accounting timer to reset the meter
local iResetMeterDeviceTime = tonumber(uservariables['iResetDeviceMeterTime'])
if ( iResetMeterDeviceTime > 0 ) then -- There is an ongoing power consumption
    local iNewResetDeviceMeterTime = iResetMeterDeviceTime - 1
     if( iNewResetDeviceMeterTime == 0) then
  -- reset energy counters on time
         sCurrentPower,sCurrentTotalEnergy = string.match(otherdevices_svalues[sPowerMeterDeviceName], "(%d+%.*%d*);(%d+%.*%d*)" )
         addCommand('UpdateDevice', iPowerMeterIdx .. '|0|0;' .. sCurrentTotalEnergy)
     end
    addCommand('Variable:iResetDeviceMeterTime',tostring(iNewResetDeviceMeterTime))
end

-- Get current heating mode
sHeatingMode = otherdevices[sHeatingModeDeviceName]

-- Heating in Eco or Comfort, needs a calculation

if ( sHeatingMode == sHeatingModeComfortName
     or
     sHeatingMode == sHeatingModeEcoName
   )
   then
            -- Inits
            bPresence = false
            fSetPointTemp = 7

            -- Check for presence
            sPresenceDeviceStatus = otherdevices[sPresenceDeviceName]
            if ( sPresenceDeviceStatus == 'On' ) then
                   prDebug('Presence is on')
                   bPresence = true
             else
                   prDebug('Presence is off')
                   bPresence = false
            end

            -- Comfort mode, set heating setpoint to thermostat value, only applies if Presence is true.
            if( (sHeatingMode == sHeatingModeComfortName) and bPresence ) then
                fSetPointTemp = tonumber(otherdevices_svalues[sSetPointConfortDeviceName])
                prDebug ('Heating in *Comfort mode*, Setpoint : '..fSetPointTemp..' at '..sCurrentTime)
            end

            -- Eco mode, setpoint adjusted. Use this setpoint if no Presence.
            if( sHeatingMode == sHeatingModeEcoName or bPresence == false) then
               fSetPointTemp = tonumber(otherdevices_svalues[sSetPointEcoDeviceName])
                prDebug ('Heating in *Eco mode*, Setpoint : '..fSetPointTemp..' at '..sCurrentTime)
            end
                        -- Control mode

            local sControlMode = otherdevices[sHeatingControlModeDeviceName]
            prDebug('Heating Control mode : ' .. sControlMode)

            if( sControlMode == sHeatingControlModeHysteresisName ) then -- Control mode set to hysteresis

                             -- Decision to heat or not

                             -- Is it cold ?
                             if(fCurrentTemp <= (fSetPointTemp - fHysteresis) ) then
                                 prDebug ('Heating needed with delta : ' .. fCurrentTemp - fSetPointTemp)
                                 -- startHeating(aHeatingDeviceNames) --GH get rid of variable
                                 commandHeating(sHeatingOnCommand)
                            end

                             -- Is it warm ?
                            if(fCurrentTemp >= (fSetPointTemp + fHysteresis) ) then
                                 prDebug ('Stopping heating needed with delta : ' .. fCurrentTemp - fSetPointTemp)
                                 -- stoptHeating(aHeatingDeviceNames)
                                 commandHeating(sHeatingOffCommand)
                            end
             end

            if( sControlMode == sHeatingControlModePIDName ) then -- Control mode set to PID
                   -- We control the execution frequency
                   if( sCurrentMinute % iHeatingCycleDuration == 0) then -- We run the cycle

                                -- Set PID coefficients according to sample time
                                local fPIDTKi = fPIDKi * iHeatingCycleDuration * 60
                                local fPIDTKd = fPIDKd / (iHeatingCycleDuration * 60)
                                -- Current temperature error
                                 fTempError = fSetPointTemp - fCurrentTemp
                                 -- Compute new Integral
                                        -- If Setpoint changed, reset the integral action
                                         if( fSetPointTemp ~= tonumber(uservariables['fSetpointLast']) ) then
                                          fISum=0
                                         else
                                          -- Get the last Integral
                                          fISum = uservariables['fISumLast']
                                         end
                                 fISum = fISum + (fPIDTKi * fTempError)
                                 -- if(fISum > 255) then fISum = 255 end
                                 if(fISum > 255) then fISum = 255 end -- Integral limitation
                                 if(fISum < 0) then fISum = 0 end
                                 -- Derivative computation
                                 local fDeltaInput = fCurrentTemp - uservariables['fTempLastInput']  -- to number
                                 -- Sum up the PID output
                                 local fPIDOutput = fPIDKp * fTempError + fISum - fPIDTKd * fDeltaInput
                                 prDebug('PID Output : fPIDKp * fTempError = ' ..fPIDKp..' * '..fTempError..' = '..fPIDKp*fTempError..', fISum + '..fPIDTKi * fTempError..'  = '..fISum..', -fPIDTKd * fDeltaInput = '..fPIDTKd..' * '..fDeltaInput..' = -' .. fPIDTKd*fDeltaInput..', Output : '..fPIDOutput)
                                 if(fPIDOutput > 255) then fPIDOutput = 255 end
                                 if(fPIDOutput < 0) then fPIDOutput = 0 end
                                 -- Update user variables for next cycle
                                 addCommand('Variable:fTempLastInput',tostring(fCurrentTemp))
                                 addCommand('Variable:fISumLast',tostring(fISum))
                                 addCommand('Variable:fSetpointLast',tostring(fSetPointTemp))
                                 
                                  -- Heating cycle duration calculation
                                 if( fPIDOutput > 0 ) then -- heat
                                    fCycleDuration = round(fPIDOutput * iHeatingCycleDuration / 255,0)
                                    if( fCycleDuration == 0 ) then fCycleDuration = 1 end -- Heating is needed, let's go for at least 1 minute
                                    prDebug('Going to heat for : ' ..fCycleDuration..' minutes during the next '..round(iHeatingCycleDuration*60)..' seconds ('..iHeatingCycleDuration..' minutes) period.' )
                                    commandHeating(sHeatingOnForCommand,fCycleDuration)
                                  else -- Output null or negative, stop the heating
                                    prDebug('No heating needed')
                                    commandHeating(sHeatingOffCommand)
                                 end

            end -- Time period
       end -- PID mode
end

-- Heating forced on
if ( sHeatingMode == sHeatingModeForceOnName )
   then
            prDebug('Heaters forced On')
            commandHeating(sHeatingOnCommand)
end

-- Heating forced off
if ( sHeatingMode == sHeatingModeFrostFreeName )
   then
            prDebug('Heaters forced Off - Anti-frost mode')
            commandHeating(sHeatingOffCommand)
end

return commandArray
Skippiemanz
Posts: 230
Joined: Sunday 14 July 2013 20:21
Target OS: Linux
Domoticz version: 4.10233
Location: Alkmaar, The Netherlands
Contact:

Re: Multi heaters and sensors, PID and hysterisis heating script

Post by Skippiemanz »

Greg,

Looks nice!

Could it be used for a normal boiler heating system?

Is it the case of just leaving the watts out of does is need more?
greg
Posts: 5
Joined: Monday 26 December 2016 22:52
Target OS: Linux
Domoticz version:
Contact:

Re: Multi heaters and sensors, PID and hysterisis heating script

Post by greg »

Thank you ! I guess it can be used with a normal boiler heating system. I would be careful with the minimum time the boiler would need to heat to be effective. You can maybe tweak the line "if( fCycleDuration == 0 ) then fCycleDuration = 1 end -- Heating is needed, let's go for at least 1 minute" to accomodate with a minimal heating time.

The Watts are not needed, it's cosmetic ;-)

Cheers
Abbadon
Posts: 40
Joined: Thursday 01 October 2015 8:25
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland, Wrocław
Contact:

Re: Multi heaters and sensors, PID and hysterisis heating script

Post by Abbadon »

great piece of work, i will test it in my flat.
Thank you

edit. i add json line to update selector (comfort/eco) when persence button is on/off

Code: Select all

            -- Comfort mode, set heating setpoint to thermostat value, only applies if Presence is true.
            if( (sHeatingMode == sHeatingModeComfortName) and bPresence ) then
                fSetPointTemp = tonumber(otherdevices_svalues[sSetPointConfortDeviceName])
                prDebug ('Heating in *Comfort mode*, Setpoint : '..fSetPointTemp..' at '..sCurrentTime)
commandArray[1]={['OpenURL']='http://ip:port/json.htm?type=command&param=switchlight&idx=180&switchcmd=Set%10Level&level=10' }

            end

            -- Eco mode, setpoint adjusted. Use this setpoint if no Presence.
            if( sHeatingMode == sHeatingModeEcoName or bPresence == false) then
               fSetPointTemp = tonumber(otherdevices_svalues[sSetPointEcoDeviceName])
                prDebug ('Heating in *Eco mode*, Setpoint : '..fSetPointTemp..' at '..sCurrentTime)
commandArray[1]={['OpenURL']='ip:port/json.htm?type=command&param=switchlight&idx=180&switchcmd=Set%20Level&level=20'}.
            end
humi chart: humi 100% when heat is ON, humi 1% when is off
Bez tytułu.png
Bez tytułu.png (60.56 KiB) Viewed 4779 times
Bez tytułu.png
Bez tytułu.png (60.56 KiB) Viewed 4779 times
Blueone
Posts: 130
Joined: Friday 29 November 2013 11:30
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Multi heaters and sensors, PID and hysterisis heating script

Post by Blueone »

I'm very interested in this script and especially the PID part but it is all a bit new for me. Do you have some tips for calculating the the pid parameters?

Kp = ΔPV / ΔCO -- On steady temperature states, ratio of temperature difference for command difference
- What does this exactly mean?

Tp -- Time needed to reach 63% of the setpoint
-My setpoint is set at 20.5 which I can increase with 0.5, is is 63% of the time it takes for the heating system to increase the temp wit 0.5?

θp -- Time between action on the heating and measurable reaction of the temperature sensor
-clear, can be easily measured, is it in minutes or seconds?

Tc -- Response time, highest value among 0.1Tp or 0.8θp (agressive), 1Tp or 8θp (middle), 10Tp or 80θp (conservative)
Can you explain this a bit more?

Kc = P = (1/Kp)*(Tp/(θp+Tc)) -- Our fPIDKp
I = Kc/Ti -- Our fPIDKi
what is the Ti value in this formule

Td = (Tp x θp)/(2Tp+θp) -- Needed to compute the last constant
D = Kc * Td -- Our fPIDKd

Thanks for your reply!
greg
Posts: 5
Joined: Monday 26 December 2016 22:52
Target OS: Linux
Domoticz version:
Contact:

Re: Multi heaters and sensors, PID and hysterisis heating script

Post by greg »

Sorry for my late reply. Please find answers below :
Blueone wrote: Kp = ΔPV / ΔCO -- On steady temperature states, ratio of temperature difference for command difference
- What does this exactly mean?
PV is the room's temperature ;
CO - Controller Output - , is the power percentage of the heaters.

The variable indicates the temperature change that will follow a change in the heating power.

To calculate this value, i put the system in place with basic values (i really recommend you to create
a spreadsheet to compute those), until the temperature is steady. I then have a look at the computed
values, especially the heating percentage. If the heaters are on for 3 minutes on 10 minutes cycles, then
they are running at 30%, it's the first CO. I keep the record of the steady temperature in the room, that's the first PV.
Then, i raise the setpoint, and wait until the temperature is steady again. The heaters are now maybe
running at 70%, it's the second CO. The measured temperature in the room is the second PV.
Blueone wrote: Tp -- Time needed to reach 63% of the setpoint
-My setpoint is set at 20.5 which I can increase with 0.5, is is 63% of the time it takes for the heating system to increase the temp wit 0.5?
Yes, if you increase the setpoint with 0.5, and it takes one hour to reach it, Tp=2268 seconds.
Blueone wrote: θp -- Time between action on the heating and measurable reaction of the temperature sensor
-clear, can be easily measured, is it in minutes or seconds?
It's in seconds.
Blueone wrote: Tc -- Response time, highest value among 0.1Tp or 0.8θp (agressive), 1Tp or 8θp (middle), 10Tp or 80θp (conservative)
Can you explain this a bit more?
It the speed at which the heating system will react. When it's agressive, the system will surpass the setpoint,
while when conservative, the system will take more time to reach the setpoint, but won't exceed it.

Blueone wrote: Kc = P = (1/Kp)*(Tp/(θp+Tc)) -- Our fPIDKp
I = Kc/Ti -- Our fPIDKi
what is the Ti value in this formule
Actually, Ti = Tp.
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests