Testing out my new BrewPi setup and need some advice on tweaking the settings. Have a 5 gallons carboy of water that I added to my chest freezer last night. Water started at 82F (Florida well water doesn’t get very cool in the summer) and set to rise cool to 65. It looks like it overshot a bit much, and kicked the heater on. Problem with the heater (shielded halogen light) that it is pulsing on and off. The SSR switches on for a second and turns off for 5 seconds. My old Arduino didn’t behave like that. Here is the graph for the past 10 hours or so, recommendations on what to change?
Can you share your settings? You can copy the control algorithm tab and paste it here, surround it with 3 backticks.
I think your beer-to-fridge Kp is too low, causing the integrator to do most of the work. The integrator is always slow to respond. With a higher Kp, the integrator will not wind up.
The pulsing is normal, that’s PWM. It allows us to heat at less than full power.
P.S. which version of the firmware are you running?
The light doesn’t seem to be staying on long enough to make a difference at this point, may need to look at a different heating solution. Firmware is .0.5.2.
Control algorithm is here,
{
"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": 20,
"connected": true,
"address": "28EB7F8008000031",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 21.0859
}
},
"output": {
"kind": "ActuatorPwm",
"dutySetting": 45.6758,
"period": 4,
"minVal": 0,
"maxVal": 100,
"target": {
"kind": "ActuatorMutexDriver",
"mutexGroup": {
"kind": "ActuatorMutexGroup",
"deadTime": 1800000,
"waitTime": 1799812
},
"target": {
"kind": "ActuatorDigitalDelegate",
"name": "heater1",
"delegate": {
"kind": "ActuatorPin",
"state": false,
"pin": 24,
"invert": false
}
}
}
},
"inputError": -1.0781,
"Kp": 10,
"Ti": 600,
"Td": 60,
"p": 10.7813,
"i": 34.8164,
"d": 0.0781,
"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": 1799796
},
"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": 20,
"connected": true,
"address": "28EB7F8008000031",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 21.0859
}
},
"output": {
"kind": "ActuatorPwm",
"dutySetting": 0,
"period": 1200,
"minVal": 0,
"maxVal": 100,
"target": {
"kind": "ActuatorMutexDriver",
"mutexGroup": {
"kind": "ActuatorMutexGroup",
"deadTime": 1800000,
"waitTime": 1799779
},
"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": -1.0781,
"Kp": 10,
"Ti": 1800,
"Td": 200,
"p": 10.7813,
"i": 0,
"d": 0.1563,
"actuatorIsNegative": true
},
{
"kind": "Pid",
"name": "beer2fridgepid",
"enabled": true,
"input": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorDelegate",
"name": "beer1",
"delegate": {
"kind": "OneWireTempSensor",
"value": 16.6875,
"connected": true,
"address": "28024C7F080000AF",
"calibrationOffset": 0
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "beer1set",
"value": 18.332
}
},
"output": {
"kind": "ActuatorOffset",
"target": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorFallback",
"onBackupSensor": false,
"sensor": {
"kind": "TempSensorDelegate",
"name": "fridge",
"delegate": {
"kind": "OneWireTempSensor",
"value": 20,
"connected": true,
"address": "28EB7F8008000031",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 21.0859
}
},
"reference": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorDelegate",
"name": "beer1",
"delegate": {
"kind": "OneWireTempSensor",
"value": 16.6875,
"connected": true,
"address": "28024C7F080000AF",
"calibrationOffset": 0
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "beer1set",
"value": 18.332
}
},
"useReferenceValue": false,
"setting": 2.7539,
"achieved": 1.668,
"minimum": -10,
"maximum": 10
},
"inputError": -1.6758,
"Kp": 2,
"Ti": 7200,
"Td": 1200,
"p": 3.3516,
"i": -0.4492,
"d": -0.1484,
"actuatorIsNegative": false
}
]
}
The fridge temperature is following the setpoint exactly, so your heater is fine.
Maybe you want to increase the PWM period so it doesn’t turn on and off this often.
You have a beer-to-fridge Kp of 2. I would try 8 instead. That way, if the beer temperature is 1 degree too low, the fridge temperature will be 8 degrees above the fridge setpoint.
What happened is this:
Because of Kp being low, the fridge setting was not enough to drive the beer temperature to the setpoint quickly. This causes the integrator to slowly increase. The integrator does not increase when the fridge setting is clipped to the maximum (18F in your case). With a higher Kp, the proportional part will do more work and the integral will not increase as much. You could also decrease the clipping range (10F instead of 18F for example).
Made the changes and I believe this looks better. Testing ramping up the beer temp and then will cold crash it to see how it performs.
{
"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": 9.9375,
"connected": true,
"address": "28EB7F8008000031",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 10
}
},
"output": {
"kind": "ActuatorPwm",
"dutySetting": 0,
"period": 4,
"minVal": 0,
"maxVal": 100,
"target": {
"kind": "ActuatorMutexDriver",
"mutexGroup": {
"kind": "ActuatorMutexGroup",
"deadTime": 1800000,
"waitTime": 1799417
},
"target": {
"kind": "ActuatorDigitalDelegate",
"name": "heater1",
"delegate": {
"kind": "ActuatorPin",
"state": false,
"pin": 24,
"invert": false
}
}
}
},
"inputError": -0.1953,
"Kp": 10,
"Ti": 600,
"Td": 60,
"p": 1.9531,
"i": 0.0547,
"d": -4.5313,
"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": 1799401
},
"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": 9.9375,
"connected": true,
"address": "28EB7F8008000031",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 10
}
},
"output": {
"kind": "ActuatorPwm",
"dutySetting": 36.1484,
"period": 1200,
"minVal": 0,
"maxVal": 100,
"target": {
"kind": "ActuatorMutexDriver",
"mutexGroup": {
"kind": "ActuatorMutexGroup",
"deadTime": 1800000,
"waitTime": 1799384
},
"target": {
"kind": "ActuatorTimeLimited",
"minOnTime": 120,
"minOffTime": 180,
"maxOnTime": 65535,
"state": true,
"target": {
"kind": "ActuatorDigitalDelegate",
"name": "cooler",
"delegate": {
"kind": "ActuatorPin",
"state": true,
"pin": 25,
"invert": false
}
}
}
}
},
"inputError": -0.1953,
"Kp": 10,
"Ti": 1800,
"Td": 200,
"p": 1.9531,
"i": -22.9063,
"d": -15.1953,
"actuatorIsNegative": true
},
{
"kind": "Pid",
"name": "beer2fridgepid",
"enabled": true,
"input": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorDelegate",
"name": "beer1",
"delegate": {
"kind": "OneWireTempSensor",
"value": 19.0625,
"connected": true,
"address": "28024C7F080000AF",
"calibrationOffset": 0
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "beer1set",
"value": 15.5547
}
},
"output": {
"kind": "ActuatorOffset",
"target": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorFallback",
"onBackupSensor": false,
"sensor": {
"kind": "TempSensorDelegate",
"name": "fridge",
"delegate": {
"kind": "OneWireTempSensor",
"value": 9.9375,
"connected": true,
"address": "28EB7F8008000031",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 10
}
},
"reference": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorDelegate",
"name": "beer1",
"delegate": {
"kind": "OneWireTempSensor",
"value": 19.0625,
"connected": true,
"address": "28024C7F080000AF",
"calibrationOffset": 0
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "beer1set",
"value": 15.5547
}
},
"useReferenceValue": false,
"setting": -5.5547,
"achieved": -5.6172,
"minimum": -5.5547,
"maximum": 5.5547
},
"inputError": 3.5273,
"Kp": 8,
"Ti": 7200,
"Td": 1200,
"p": -28.2188,
"i": 0,
"d": 4.0625,
"actuatorIsNegative": false
}
]
}
That looks better indeed!
I think the jumpiness in the fridge setting is from the derivative.
You can make the setting smoother by increasing the filtering on the derivative and decreasing Td.
For those modifications, what would you suggest. TD is currently set to 1200 - take to 600? For the filter, I assume that is the Beer-to-Fridge Derivative filter delay time value and take that from 159 seconds to 318?
I would set the filtering to max and 600 sounds good.
I have all of the derivative time constants set to zero in my current setup, which AFAIK means the contribution from the derivatives is eliminated. Nonetheless I still have very “grassy” behavior in my fridge setting. So either my understanding is wrong re: what setting Td = 0 does, or there are ways in which fridge setting can be grassy which are unrelated to Td.
- Beer-to-Fridge derivative time constant (Td) = 0
- Cooler derivative time constant (Td) = 0
- Heater 1 derivative time constant (Td) = 0
- Heater 2 derivative time constant (Td) = 0
{
"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": 14.25,
"connected": true,
"address": "28A6A273060000B1",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 14.6953
}
},
"output": {
"kind": "ActuatorPwm",
"dutySetting": 77.9102,
"period": 4,
"minVal": 0,
"maxVal": 100,
"target": {
"kind": "ActuatorMutexDriver",
"mutexGroup": {
"kind": "ActuatorMutexGroup",
"deadTime": 1800000,
"waitTime": 1799865
},
"target": {
"kind": "ActuatorDigitalDelegate",
"name": "heater1",
"delegate": {
"kind": "ActuatorPin",
"state": true,
"pin": 11,
"invert": false
}
}
}
},
"inputError": -0.4688,
"Kp": 100,
"Ti": 600,
"Td": 0,
"p": 46.875,
"i": 31.0352,
"d": 0,
"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": 1799787
},
"target": {
"kind": "ActuatorDigitalDelegate",
"name": "heater2",
"delegate": {
"kind": "ActuatorNop",
"state": false
}
}
}
},
"inputError": null,
"Kp": 0,
"Ti": 0,
"Td": 0,
"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": 14.25,
"connected": true,
"address": "28A6A273060000B1",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 14.6953
}
},
"output": {
"kind": "ActuatorPwm",
"dutySetting": 0,
"period": 3000,
"minVal": 0,
"maxVal": 100,
"target": {
"kind": "ActuatorMutexDriver",
"mutexGroup": {
"kind": "ActuatorMutexGroup",
"deadTime": 1800000,
"waitTime": 1799699
},
"target": {
"kind": "ActuatorTimeLimited",
"minOnTime": 180,
"minOffTime": 180,
"maxOnTime": 65535,
"state": false,
"target": {
"kind": "ActuatorDigitalDelegate",
"name": "cooler",
"delegate": {
"kind": "ActuatorPin",
"state": false,
"pin": 16,
"invert": false
}
}
}
}
},
"inputError": -0.4688,
"Kp": 30,
"Ti": 1800,
"Td": 0,
"p": 14.0625,
"i": -3.4023,
"d": 0,
"actuatorIsNegative": true
},
{
"kind": "Pid",
"name": "beer2fridgepid",
"enabled": true,
"input": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorDelegate",
"name": "beer1",
"delegate": {
"kind": "OneWireTempSensor",
"value": 12.3125,
"connected": true,
"address": "28DF41A9080000C5",
"calibrationOffset": 0
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "beer1set",
"value": 12.4297
}
},
"output": {
"kind": "ActuatorOffset",
"target": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorFallback",
"onBackupSensor": false,
"sensor": {
"kind": "TempSensorDelegate",
"name": "fridge",
"delegate": {
"kind": "OneWireTempSensor",
"value": 14.25,
"connected": true,
"address": "28A6A273060000B1",
"calibrationOffset": 0
}
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "fridgeset",
"value": 14.6953
}
},
"reference": {
"kind": "SensorSetPointPair",
"sensor": {
"kind": "TempSensorDelegate",
"name": "beer1",
"delegate": {
"kind": "OneWireTempSensor",
"value": 12.3125,
"connected": true,
"address": "28DF41A9080000C5",
"calibrationOffset": 0
}
},
"setPoint": {
"kind": "SetPointSimple",
"name": "beer1set",
"value": 12.4297
}
},
"useReferenceValue": false,
"setting": 2.2656,
"achieved": 1.8203,
"minimum": -10,
"maximum": 10
},
"inputError": -0.1133,
"Kp": 20,
"Ti": 0,
"Td": 0,
"p": 2.2656,
"i": 0,
"d": 0,
"actuatorIsNegative": false
}
]
}
The fridge setting is Kp * (error + integral / Ti + derivative * Td). So yes, it can be grassy from just Kp due to bit flips, but the effect on the derivative part is higher when there is not much filtering and a high Td.