Building a better thermostat
May 20, 2019 2:58 PM

I'm setting up an automated temperature control system for brewing beer. My computer is only going to be communicating with heating and cooling elements using on/off control (no ability to set the elements to operate at 50% power, say). I'm hoping there's a better way to control this system than just having a hysteresis range.

The system I'm working on building consists of the following pieces: a heating wrap around the fermentation vessel; a chest freezer the vessel lives in; solid-state relays to turn on and off these two elements, a Bluetooth thermometer in the fermentation vessel, and a computer-on-a-chip with GPIO pins to tie all of these elements together. So the thermostat is basically purely a software construct: given a continuous stream of temperature readings, it should enable one or the other SSR (or neither) as circumstances dictate. Since I can code up literally anything I want, it seems like just setting a hysteresis interval isn't necessarily the best approach.

The gold standard in such control systems, as I understand it, is a PID model. However, as far as I know, PID really wants to have nonbinary control mechanisms, and while I could translate that into a duty cycle, doing so seems like it'd be awfully hard on the chest freezer and possibly on the relays.

What seems like a good idea is some sort of model of thermal momentum and inertia. I know little thermodynamics, so this may be terribly inaccurate language, but what I'm thinking of is that once a mass starts cooling (or heating), the propagation of that temperature through the mass (to the location of the sensor) continues even after the cold/heat source is removed, at a rate which could presumably be determined by historical knowledge of the sensor's reported temperature, and short-term analysis of its reported temperature change (this term being essentially the "D" term of a PID controller, which makes me feel like I'm reinventing the wheel). This effect would likely, to complicate matters, be asymmetrical: the chest freezer is acting on a larger volume and mass than the wrap, whose heat source is directly up against the beer, and of course the two units have quite different heat-modifying capabilities as well, which leads to wildly different thermal momentums associated with their use.

This seems like something somebody has already worked out the details of, so I'm wondering if such a system (specifically for an on/off controller and not making use of short duty cycles) already exists. As the above paragraph might suggest, I'm an utterly ignorant thermodynamicist, a fairly skilled mathematician, and a reasonably competent coder. An out-of-the-box prewritten system (especially in Python) would be awesome, but if there's a good theoretical writeup of such a system I could roll my own implementation as well, so I'd welcome that too. Ideally such a system would be self-tuning (i.e. the parameters translating temperature measurements to "thermal momentum", starting from naïve values, would self-correct based on observed responses while the control system runs).
posted by jackbishop to Technology (11 answers total) 3 users marked this as a favorite
Look into BrewPi. It's changed since I built mine (which for various reasons I haven't used in years) but I think it does just what you are looking for, with the ability to have a sensors in the "chamber" (e.g., chest freezer) and in the beer (in a thermowell).
posted by exogenous at 3:03 PM on May 20, 2019


Yeah, exogenous's solution was my thought as well - no need to futz around with theoretical numbers that may or may not take into account all the relevant factors of your specific set-up, when with a second thermometer you can really easily collect empirical data about how long that set-up takes to reach equilibrium in various circumstances.
posted by solotoro at 3:33 PM on May 20, 2019


Do you really need both heating and cooling? Seems that the brewing temperature will either be above the room temperature or below the room temperature, in which case you only need a heater or a cooler, not both. Does the room temperature vary on both sides of brewing temperature?

What are your tolerances for temperature variation? 1 degree? 0.5 degrees? For how long?

You can't design a system without specifications.
posted by JackFlash at 3:53 PM on May 20, 2019


For the refrigerator you're not going to do better than having a hysteresis, aka bang-bang control. You probably also want a minimum on and/or off time because of the realities of how refrigerant compressors work. If you'd try to cycle it many times a minute, for instance, it would quickly fail.

It's true for the heater you could run it with PWM or PDM, and I think this could actually work for you, but I think you are vastly overestimating the need for it here, since the thermal mass of your brew is going to dwarf the thermal mass of the heat wrap itself, and of the air in the enclosed freezer. When you turn off your heat wrap, the brew just isn't going to keep getting warmer for very long, because your vessel and heater are both going to be about the same temperature as the brew because they are touching it. (You are right that the D term would typically compensate for this. Using my own inaccurate language, the P term adjusts according to the present, I according to the past, D according to the future.)

So I think if you also write bang-bang for the heater (you can use a much smaller hysteresis) you will get perfectly fine performance and no amount of complexity will markedly improve it. I predict the limiting factor in your whole design will be the digital format/resolution of your temperature sensor, and are you sure you want to build it out of wireless parts? It's all in a box, and wires seem like a good idea for hooking things inside a box together.

(Control loops aside, I'm also curious about needing both heating and cooling!)
posted by fritley at 4:48 PM on May 20, 2019


Well I didn't need cooling, seems like you would only need that for lagering I guess unless you live in a crazy climate, but I did this with heat for pretty cheap.

Put the carboy in one of those cheap plastic tubs meant to fill with ice/drinks/kegs. Place carboy in, fill with water. Use an aquarium heater to heat up the water.

Now you could just set the thermostat on the aquarium heater and call it a day but if you wanted more granular automation/data collection then I would just hook up the heater to a relay and have your microcontroller (Pi/esp8266) turn that on and off (combined with as many temp sensors as you need).

Might want to look at home automation software (ie. Home Assistant, OpenHAB, or esphome for esp8266) because they all provide easy ways to turn a simple relay+sensor into a thermostat. If you go that way it would not be hard to add cooling.
posted by bradbane at 4:48 PM on May 20, 2019


Instead of a PID model, you could go for a fuzzy logic model. If I remember my reading about it from two decades ago, it can be better at baking in operator knowledge such as the non-symmetric nature of the heating vs. cooling.
posted by ctmf at 8:22 PM on May 20, 2019


I bought a base-model Inkbird (ITC-1000) with a single thermometer and two outlets, for powering a heater and a cooler. Usually these get used in the manner you describe; wrap a heat blanket around your carboy and put it in a freezer (or, alternately, put the carboy and an aquarium heater in a 5-gallon bucket of water, all inside the freezer). My basement is cold (high 50s F) even in the New England summer so I only use the heating outlet.

Are you trying to move beyond this set-up because you want to do data collection, and then build a (mental|software) model? Or would the above solution work for you if you could collect the temperature readings?
posted by wenestvedt at 5:45 AM on May 21, 2019


The gold standard in such control systems, as I understand it, is a PID model. However, as far as I know, PID really wants to have nonbinary control mechanisms, and while I could translate that into a duty cycle, doing so seems like it'd be awfully hard on the chest freezer and possibly on the relays.

Personally I'd run two separate control loops, one for the cooling and one for the heating, with separate temperature sensors for the chest freezer's air temperature and the brew vessel's liquid temperature, with the cooling loop's set point below that of the heating loop.

The design concept here is that because you can safely switch a resistive heater much much faster than you can switch a mechanical compressor, the heater should be the control element that sets the final temperature of the brew.

You can't avoid temperature cycling from the cooling system, because the rapid power cycling required to remove it would quickly destroy your compressor. So the only way to stop the fridge's temperature exerting unwanted influences on your brew tank is to offset it with the heater, and the only way that can happen is if the heater is always to some extent fighting with the cooler.

If the overall system works as designed then the heater will totally hide the cooling system's temperature cycling from the tank temperature sensor, making it useless for controlling the cooler; this is why you need a separate air temperature sensor for that.

Because the cooling system is going to be cycling anyway, there's no point using a fancy PID control loop for it. Give it a set point some tuneable number of degrees below the tank set point, enforce reasonable minimum time intervals after a compressor power transition during which temperature sensing is ignored, and leave it at that.

Design in a mains voltage zero crossing sensor and use solid state relays with instantaneous triggering. That way you can get the mains phase angle at which your relays will switch under software control, allowing you to use peak-voltage switching for your compressor motor and zero-voltage switching for your resistive tank heater. This should minimize surge currents, RFI and stress on all components.

Control functions should be evaluated right when any switching they control is due, so do the heater checks right on a zero crossing and the compressor checks 90° later. Do these evaluations only on every other zero crossing, so that both outputs consume mains power in whole-cycle increments; that way you're not being rude to your electricity supplier's pole transformers by inducing a DC component in your mains draw.

The heater control function should yield a weighted sum of seven inputs:

1. Current tank temperature minus tank set point.
2. Current input (1) plus previous input (2).
3. Current input (1) minus previous input (1).
4. Current freezer air temperature minus tank set point.
5. Current input (4) minus previous input (4).
6. The fixed value 1.
7. Previous input (7) times 0.875, plus (1 if the heater is currently on, -1 if off).

If that sum is negative, turn the heater relay on; otherwise turn it off.

All the "previous" values should be zeroed at power-on. Reasonable default weights would be 100 for input 1, 0 for inputs 2 through 6, and 1 for input 7. Graph the inputs and tune the weights until you're happy with the control results.

Inputs 1, 2 and 3 implement PID control for the tank temperature sensor, with supplementary proportional and differential influence from the air temperature outside the tank via 4 and 5. There is no point in allowing integral influence from that air temperature since we're not trying to cancel out any long-term offset between it and the tank set point: that offset is there by design.

Input 7 implements something vaguely akin to sigma-delta ADC for the control function's output, and is what allows you to simply use that output's sign to control the heater relay. If the weighted sum of all the other inputs was zero, input 7 would result in the heater switching on and off on alternate whole mains cycles, yielding a 50% duty cycle and thereby giving the heater the widest range of temperature control in both directions. Adjusting the weight for input 6 lets you set this "idling" duty cycle anywhere you want it.
posted by flabdablet at 6:48 AM on May 21, 2019


All this PID stuff seems way overkill for your application. For example, a plain old $20 wall thermostat banging on and off for a furnace is perfectly capable of holding room temperature to within 0.5 degrees Fahrenheit even when outdoor temperature differs by many tens of degrees.

Your application is even simpler. Due to the thermal mass of the water in the vessel, the temperature is going to drift very slowly. Room temperature surrounding it is going to be fairly steady and not that far from the desired temperature. Simple on/off control when the measured temperature drifts by 0.5 degrees should be fine.

As mentioned above, the limiting factor is going to be the accuracy (absolute value) and precision (repeatability) of your Bluetooth thermometer.
posted by JackFlash at 9:46 AM on May 21, 2019


Of course PID is overkill. The yeast is not going to give a shit about a degree either way.

Tweaking a PID model to make it lock a controlled output in a fist of iron is a lot of fun, though, especially given that a computer has already been designed into the control loop to begin with.
posted by flabdablet at 7:31 PM on May 21, 2019


Has drewbage commented in this thread yet? He should have a useful opinion here.
posted by wenestvedt at 2:54 AM on May 22, 2019


« Older How to buy a ferry ticket from Busan->Tsushima...   |   Where can I find old handwriting worksheets on the... Newer »
This thread is closed to new comments.