The recent modifications to the cabinet warranted a small software upgrade. The power and heat transfer of the two modes are drastically different. The heating side, a SSR-throttled in-line water heater element, can increase the temperature of the fluid much faster than the thermoelectric chips I was using previously. The cooling side, a copper coil sitting inside the refrigerator, is much slower; in fact, it has to slowly cool the fluid reservoir before it even approaches a useful rate of heat transfer from the fermenter. Previously, I’d used a single set of control parameters for both the heating and the cooling side, but the parameters are now too different. I had to rewrite the code to use different PID parameters for each. This is trivial, but rewriting the TCP communication protocols to include the parameter values so that I can change them for the purpose of tuning took a little time.
Here’s the current control scheme:
This is essentially a dual-loop control configuration with a bit of switching logic included. In simple terms, one controller uses the temperature of the fermenter to determine what temperature the heat exchange fluid should be. The heating and cooling controllers measure the current temperature of the heat exchange fluid, compare it to the desired temperature, and adjust the power output to bring the temperature to the setpoint. A bit of control logic (which actually includes another controller) determines whether the the cabinet should be in heating or cooling mode. This is necessary to keep the cabinet from inappropriately switching between the two modes when the temperature of the fermenter is near setpoint.
By “controller” I mean PID. Many brewers are familiar with discrete hardware units that are called PID controllers, but PID control is really just an approach to controlling a measured variable by changing a process output. I wrote a software PID object in C++ based on my father’s Visual Basic implementation (check out his blog to see that I am a small chip off a very large block) that I use in the software for the microcontroller that runs the cabinet. I omitted derivative control, opting only for proportional and integral. As my father would say, derivative control isn’t often that important.
An important thing to know about PID controllers is that they have to be tuned. Plainly, this setting how the controller reacts to the error it detects. A well tuned controller will quickly reach setpoint. An overtuned controller will oscillate aggressively about the setpoint. A loosely tuned controller will take forever to get there. An incorrectly tuned controller will blast off in the wrong direction, an undesirable and possibly unsafe scenario.
Rigorous controller tuning would require a decent process model. I don’t have even a simple one and don’t care to make one, so I opted for manual tuning. This is an iterative process that involves perturbing the system, watching its response, and adjusting the PID tuning parameters accordingly.
Here is the data from the last bit of cooling mode tuning. I decided to get the fluid temperature controller tuned for the cooling loop first since it is the more sluggish side. It’s interesting to see the oscillation that was happening with the second-to-last set of parameters (left side of the graph). It looks like there are two dominant frequences, which I presume were an interaction between the two control loops. I loosened the fluid temperature controller by decreasing the magnitude of the integral parameter (see the software reset near the middle of the graph), and it evened out. Cooling mode kept the fermenter within 0.25 degC of setpoint, which I think is acceptable considering the design of the system and excellent considering how little a quarter of a degree actually matters to the quality of the beer.
Next comes the heating mode, which I knew would be a breeze. I left the fluid temperature controller parameters alone and only tuned the heater controller parameters. This side is a much better controller compared to the cooling side. After a 10 degC setpoint change, the system brought the fermenter to within 0.25 degC of setpoint in a little over two hours with no overshoot. Thereafter, the 12-bit thermometers I use couldn’t resolve the error. I may add a bit of logic to cycle off the pump when the heater controller output drops below a threshold because this effective of a control loop isn’t even worth the power to run the tiny aquarium pump.
It’s time to drain the 10 gallons of water in the fermenter and replace it with some wort!