Overshoot When Cooling

So I am in the middle of my first trial run and have found that the beer temp has been overshot by 1.5 degrees.
Looking at the fridge set point, it was clear it was going to do this some way out from when the beer hit temp, as the fridge set point was still well under the beer set point, even after the beer reached set point…
Why would it keep cycling the cooler, after the beer has reached set point?
Why wouldn’t the fridge set point aim to meet the beer set point, at the time it reaches temp. i.e. i had beer set at 14, so logically, the fridge set point should be at 14 by the time the beer reaches 14 in order to not overshoot.

In my case, the fridge set point, took another 3 hours to get up to the beer temp, and by this time the beer was 12.5 ish degrees.
The increased on time and off time at the end was me changing the settings so min on time was 5 minutes and min off time was 15 minutes. (trying not to kill my freezer)

Ok, so i’ve ready quite a few other threads on the same issue when doing first trial, and commonly the answer is to increase fridge KP

My settings below.
I don’t really understand the settings too well.
My freezer is quite good and can cool the air at about 1 degree per minute. Being a freezer it can also go down to around minus 18 or so, so it would be good if it could use this extra cooling power initially when bringing the temp down. Currently it only goes 10 degrees below beer set point.

  "kind": "Control",
  "pids": [
    {
      "kind": "Pid",
      "name": "heater1pid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorFallback",
          "onBackupSensor": false,
          "sensor": {
            "kind": "TempSensorDelegate",
            "name": "fridge",
            "delegate": {
              "kind": "OneWireTempSensor",
              "value": 11.75,
              "connected": true,
              "address": "28AF3606090000F9",
              "calibrationOffset": 0
            }
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "fridgeset",
          "value": 14.3242
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 27.5,
        "period": 4,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 1422969
          },
          "target": {
            "kind": "ActuatorDigitalDelegate",
            "name": "heater1",
            "delegate": {
              "kind": "ActuatorPin",
              "state": false,
              "pin": 24,
              "invert": false
            }
          }
        }
      },
      "inputError": -2.6719,
      "Kp": 10,
      "Ti": 600,
      "Td": 60,
      "p": 26.7188,
      "i": 0,
      "d": 0.7813,
      "actuatorIsNegative": false
    },
    {
      "kind": "Pid",
      "name": "heater2pid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorDelegate",
          "name": "beer2",
          "delegate": {
            "kind": "TempSensorDisconnected",
            "value": null,
            "connected": false
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "beer2set",
          "value": null
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 0,
        "period": 4,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 1422952
          },
          "target": {
            "kind": "ActuatorDigitalDelegate",
            "name": "heater2",
            "delegate": {
              "kind": "ActuatorNop",
              "state": false
            }
          }
        }
      },
      "inputError": null,
      "Kp": 10,
      "Ti": 600,
      "Td": 60,
      "p": 0,
      "i": 0,
      "d": 0,
      "actuatorIsNegative": false
    },
    {
      "kind": "Pid",
      "name": "coolerpid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorFallback",
          "onBackupSensor": false,
          "sensor": {
            "kind": "TempSensorDelegate",
            "name": "fridge",
            "delegate": {
              "kind": "OneWireTempSensor",
              "value": 11.75,
              "connected": true,
              "address": "28AF3606090000F9",
              "calibrationOffset": 0
            }
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "fridgeset",
          "value": 14.3242
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 0,
        "period": 1200,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 1422934
          },
          "target": {
            "kind": "ActuatorTimeLimited",
            "minOnTime": 300,
            "minOffTime": 900,
            "maxOnTime": 65535,
            "state": false,
            "target": {
              "kind": "ActuatorDigitalDelegate",
              "name": "cooler",
              "delegate": {
                "kind": "ActuatorPin",
                "state": false,
                "pin": 25,
                "invert": false
              }
            }
          }
        }
      },
      "inputError": -2.6719,
      "Kp": 10,
      "Ti": 1800,
      "Td": 200,
      "p": 26.7188,
      "i": 0,
      "d": 2.5781,
      "actuatorIsNegative": true
    },
    {
      "kind": "Pid",
      "name": "beer2fridgepid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorDelegate",
          "name": "beer1",
          "delegate": {
            "kind": "OneWireTempSensor",
            "value": 14,
            "connected": true,
            "address": "2895A160090000A4",
            "calibrationOffset": 0
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "beer1set",
          "value": 14
        }
      },
      "output": {
        "kind": "ActuatorOffset",
        "target": {
          "kind": "SensorSetPointPair",
          "sensor": {
            "kind": "TempSensorFallback",
            "onBackupSensor": false,
            "sensor": {
              "kind": "TempSensorDelegate",
              "name": "fridge",
              "delegate": {
                "kind": "OneWireTempSensor",
                "value": 11.75,
                "connected": true,
                "address": "28AF3606090000F9",
                "calibrationOffset": 0
              }
            }
          },
          "setPoint": {
            "kind": "SetPointSimple",
            "name": "fridgeset",
            "value": 14.3242
          }
        },
        "reference": {
          "kind": "SensorSetPointPair",
          "sensor": {
            "kind": "TempSensorDelegate",
            "name": "beer1",
            "delegate": {
              "kind": "OneWireTempSensor",
              "value": 14,
              "connected": true,
              "address": "2895A160090000A4",
              "calibrationOffset": 0
            }
          },
          "setPoint": {
            "kind": "SetPointSimple",
            "name": "beer1set",
            "value": 14
          }
        },
        "useReferenceValue": false,
        "setting": 0.3242,
        "achieved": -2.25,
        "minimum": -20,
        "maximum": 20
      },
      "inputError": 0.0039,
      "Kp": 2,
      "Ti": 7200,
      "Td": 1200,
      "p": -0.0078,
      "i": -0.0352,
      "d": 0.3672,
      "actuatorIsNegative": false
    }
  ]
}```

Ok, so I tried setting BtF Kp to 10 but it doesn’t seem to have made an appreciable difference to the overshoot. Or maybe it did a little.
The beer tracks the set point really well once it reaches it but that takes around 7 - 8 hours.

I would love some help with these settings Elco? I’ve been researching how to tune PID’s but it’s very complicated.

This was last nights test. Changing the mas diff setting to 20 allowed the freezer to get much colder which helped with how quickly it could cool the 35 litre’s of water i have in there.

I am curious though about why it turned the cooling off several times well before the freezer reached set point. This prevented it from ever reaching the coldest set point.

Zooming in on the interesting parts, there are a couple of things i’m curious about how to fix.
Firstly, the fridge didnt track the set point very well. It started over and then ended up under, basically tracking a shallower curve than the set point.
Just before 11:30 the defrost cycle ran, so there is a cooling period there where it didint actually cool, but if it had, it would have remained under set point for longer.

The other thing which is the same issue as the first trial, is how long it took the fridge set point to get above beer temp, even after beer reached set point?

My first test also had a much smoother fridge set point but not sure if that makes much difference to the process.

In this test the overshoot was a bit over .62 degrees and took a bit over 3 hours to get back on track.

I guess lastly, i’m also curious about why it fires the heater at this point, when the fridge temp is fairly quickly tracking toward the set point, and then is over it for the rest of the time. I dont actually have a heater in the setup yet. Being summer in Australia now it’s probably not necessary at this point.

Below are my current settings. I would love some help with this.

  "kind": "Control",
  "pids": [
    {
      "kind": "Pid",
      "name": "heater1pid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorFallback",
          "onBackupSensor": false,
          "sensor": {
            "kind": "TempSensorDelegate",
            "name": "fridge",
            "delegate": {
              "kind": "OneWireTempSensor",
              "value": 10.0625,
              "connected": true,
              "address": "28AF3606090000F9",
              "calibrationOffset": 0
            }
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "fridgeset",
          "value": 10.0234
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 0,
        "period": 4,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 813197
          },
          "target": {
            "kind": "ActuatorDigitalDelegate",
            "name": "heater1",
            "delegate": {
              "kind": "ActuatorPin",
              "state": false,
              "pin": 24,
              "invert": false
            }
          }
        }
      },
      "inputError": 0.0234,
      "Kp": 10,
      "Ti": 600,
      "Td": 60,
      "p": -0.2344,
      "i": 0.2813,
      "d": -2.0313,
      "actuatorIsNegative": false
    },
    {
      "kind": "Pid",
      "name": "heater2pid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorDelegate",
          "name": "beer2",
          "delegate": {
            "kind": "TempSensorDisconnected",
            "value": null,
            "connected": false
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "beer2set",
          "value": null
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 0,
        "period": 4,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 813179
          },
          "target": {
            "kind": "ActuatorDigitalDelegate",
            "name": "heater2",
            "delegate": {
              "kind": "ActuatorNop",
              "state": false
            }
          }
        }
      },
      "inputError": null,
      "Kp": 10,
      "Ti": 600,
      "Td": 60,
      "p": 0,
      "i": 0,
      "d": 0,
      "actuatorIsNegative": false
    },
    {
      "kind": "Pid",
      "name": "coolerpid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorFallback",
          "onBackupSensor": false,
          "sensor": {
            "kind": "TempSensorDelegate",
            "name": "fridge",
            "delegate": {
              "kind": "OneWireTempSensor",
              "value": 10.0625,
              "connected": true,
              "address": "28AF3606090000F9",
              "calibrationOffset": 0
            }
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "fridgeset",
          "value": 10.0234
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 13.1602,
        "period": 1200,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 813160
          },
          "target": {
            "kind": "ActuatorTimeLimited",
            "minOnTime": 300,
            "minOffTime": 900,
            "maxOnTime": 65535,
            "state": false,
            "target": {
              "kind": "ActuatorDigitalDelegate",
              "name": "cooler",
              "delegate": {
                "kind": "ActuatorPin",
                "state": false,
                "pin": 25,
                "invert": false
              }
            }
          }
        }
      },
      "inputError": 0.0234,
      "Kp": 10,
      "Ti": 1800,
      "Td": 200,
      "p": -0.2344,
      "i": -6.168,
      "d": -6.7578,
      "actuatorIsNegative": true
    },
    {
      "kind": "Pid",
      "name": "beer2fridgepid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorDelegate",
          "name": "beer1",
          "delegate": {
            "kind": "OneWireTempSensor",
            "value": 10,
            "connected": true,
            "address": "2895A160090000A4",
            "calibrationOffset": 0
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "beer1set",
          "value": 10
        }
      },
      "output": {
        "kind": "ActuatorOffset",
        "target": {
          "kind": "SensorSetPointPair",
          "sensor": {
            "kind": "TempSensorFallback",
            "onBackupSensor": false,
            "sensor": {
              "kind": "TempSensorDelegate",
              "name": "fridge",
              "delegate": {
                "kind": "OneWireTempSensor",
                "value": 10.0625,
                "connected": true,
                "address": "28AF3606090000F9",
                "calibrationOffset": 0
              }
            }
          },
          "setPoint": {
            "kind": "SetPointSimple",
            "name": "fridgeset",
            "value": 10.0234
          }
        },
        "reference": {
          "kind": "SensorSetPointPair",
          "sensor": {
            "kind": "TempSensorDelegate",
            "name": "beer1",
            "delegate": {
              "kind": "OneWireTempSensor",
              "value": 10,
              "connected": true,
              "address": "2895A160090000A4",
              "calibrationOffset": 0
            }
          },
          "setPoint": {
            "kind": "SetPointSimple",
            "name": "beer1set",
            "value": 10
          }
        },
        "useReferenceValue": false,
        "setting": 0.0234,
        "achieved": 0.0625,
        "minimum": -20,
        "maximum": 20
      },
      "inputError": 0,
      "Kp": 10,
      "Ti": 7200,
      "Td": 1200,
      "p": 0,
      "i": -0.0156,
      "d": 0.0391,
      "actuatorIsNegative": false
    }
  ]
}```

The cooler is controlled by the cooler PID. The PID calculation determines the PWM value, which is why it turns off before the setpoint is reached. It’s not running at 100%, but for example at 75%. So it turns off after 75% of the period.

If you are not using a heater, don’t install one in the device list and your chart will not show heating and it will also not trigger the minimum dead time for switching.

Please note that the beer-to-fridge PID settings determine the fridge setpoint.
Firstly, the proportional part, just Kp * error.

If this doesn’t move the beer temp to the setpoint quickly enough, the integrator will increase and this will lower the fridge setpoint. Changes to the integrator are slow, slow to increase and slow to decrease. The integrator should only correct steady state errors. If the integrator is doing work that should be done by the proportional part, it can cause overshoot.
Anti-windup algorithms prevent this:

  • When the setpoint is already clipped to the maximum
  • When the temperature is not reaching the fridge setpoint

So to prevent overshoot caused by the integrator, you can make sure you hit the maximum, by increasing Kp or decreasing the maximum difference.