Normal overshoot?

First, what a great pice of engineering :slight_smile: I don’t agree with all those who wants everything, a silver bullet for all equipment. You have a great reputation to keep the fermentation at a constant temperature, stick you your guns and make it better and better!

I’m still in a testing phase and try to learn how to handle it all. I’m running 20L with only water trying to tune. My question, is it as expected with a overshoot as picture show going from 20C to 15C and 0.6C overshoot? It might be a stupid questions, I just don’t know what to expect. The extra cooling at 20:30 I don’t understand, the delay until heating is the 30 minutes delay as parameter set.

my settings

Control Algoritm
{
  "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": 18.4375,
              "connected": true,
              "address": "28951E030900009C",
              "calibrationOffset": 0
            }
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "fridgeset",
          "value": 21.1758
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 100,
        "period": 4,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 1799586
          },
          "target": {
            "kind": "ActuatorDigitalDelegate",
            "name": "heater1",
            "delegate": {
              "kind": "ActuatorPin",
              "state": true,
              "pin": 24,
              "invert": false
            }
          }
        }
      },
      "inputError": -2.8047,
      "Kp": 15,
      "Ti": 600,
      "Td": 60,
      "p": 42.0703,
      "i": 67.9141,
      "d": 5.0977,
      "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": 1799569
          },
          "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": 18.4375,
              "connected": true,
              "address": "28951E030900009C",
              "calibrationOffset": 0
            }
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "fridgeset",
          "value": 21.1758
        }
      },
      "output": {
        "kind": "ActuatorPwm",
        "dutySetting": 0,
        "period": 1200,
        "minVal": 0,
        "maxVal": 100,
        "target": {
          "kind": "ActuatorMutexDriver",
          "mutexGroup": {
            "kind": "ActuatorMutexGroup",
            "deadTime": 1800000,
            "waitTime": 1799551
          },
          "target": {
            "kind": "ActuatorTimeLimited",
            "minOnTime": 120,
            "minOffTime": 180,
            "maxOnTime": 65535,
            "state": false,
            "target": {
              "kind": "ActuatorDigitalDelegate",
              "name": "cooler",
              "delegate": {
                "kind": "ActuatorPin",
                "state": false,
                "pin": 25,
                "invert": false
              }
            }
          }
        }
      },
      "inputError": -2.8047,
      "Kp": 6,
      "Ti": 1800,
      "Td": 200,
      "p": 16.8281,
      "i": 0,
      "d": 6.7969,
      "actuatorIsNegative": true
    },
    {
      "kind": "Pid",
      "name": "beer2fridgepid",
      "enabled": true,
      "input": {
        "kind": "SensorSetPointPair",
        "sensor": {
          "kind": "TempSensorDelegate",
          "name": "beer1",
          "delegate": {
            "kind": "OneWireTempSensor",
            "value": 14.375,
            "connected": true,
            "address": "28CEC86009000090",
            "calibrationOffset": 0
          }
        },
        "setPoint": {
          "kind": "SetPointSimple",
          "name": "beer1set",
          "value": 15
        }
      },
      "output": {
        "kind": "ActuatorOffset",
        "target": {
          "kind": "SensorSetPointPair",
          "sensor": {
            "kind": "TempSensorFallback",
            "onBackupSensor": false,
            "sensor": {
              "kind": "TempSensorDelegate",
              "name": "fridge",
              "delegate": {
                "kind": "OneWireTempSensor",
                "value": 18.4375,
                "connected": true,
                "address": "28951E030900009C",
                "calibrationOffset": 0
              }
            }
          },
          "setPoint": {
            "kind": "SetPointSimple",
            "name": "fridgeset",
            "value": 21.1758
          }
        },
        "reference": {
          "kind": "SensorSetPointPair",
          "sensor": {
            "kind": "TempSensorDelegate",
            "name": "beer1",
            "delegate": {
              "kind": "OneWireTempSensor",
              "value": 14.375,
              "connected": true,
              "address": "28CEC86009000090",
              "calibrationOffset": 0
            }
          },
          "setPoint": {
            "kind": "SetPointSimple",
            "name": "beer1set",
            "value": 15
          }
        },
        "useReferenceValue": false,
        "setting": 6.1758,
        "achieved": 3.4375,
        "minimum": -10,
        "maximum": 10
      },
      "inputError": -0.625,
      "Kp": 10,
      "Ti": 5000,
      "Td": 1200,
      "p": 6.25,
      "i": 0.043,
      "d": -0.1172,
      "actuatorIsNegative": false
    }
  ]
}

Keep up the very good work!

cheers

Hi, With some tweaking, this can be improved.

During the first 4 hours, the fridge cannot reach its setpoint. But the integrator in the cooler PID does not increase, because the output is clipped already.
When the output is not at 100%, the integrator can increase, which it does, because the input is not reaching setpoint.
Your integrator time constant is only half an hour. This means the integrator can increase too quickly, which results in the overshoot and the cooling at 20:30. The integrator is dominating the proportional part. This can be fixed by increasing Kp (try 20 instead of 6) and increasing Ti (try 7200 instead of 1800).

For your beer to fridge PID, you can also make Ti much bigger.
You can also decrease max difference between beer setpoint and fridge setpoint. You’re not reaching it anyway and that way you are clipping the fridge setpoint earlier.