DIY PID Controlled Sous Vide Using a Crockpot
I recently picked up a copy of Jeff Potter’s excellent book, Cooking for Geeks: Real Science, Great Hacks and Good Food (Amazon Link). In the book, Potter discusses Sous vide cooking, French for “under vacuum”, this is a method of vacuum sealing food and cooking in a temperature controlled water bath for an extended period of time. The effect is that the temperature gradient across sous vide cooked food is small and has an even “doneness” the entire way through. By carefully selecting the temperature of the water bath, the chemical reactions that take place during cooking can be selected.
Potter presents a DIY method of building your own sous vide cooker with a crock pot and temperature cutoff switch. This is probably good enough for any use I’d have, but as somebody with a bit of controls background, I felt like I could do better: a PID controller to maintain the water bath temperature. PID control allows for closed-loop feedback to regulate the temperature to respond to disturbances and minimize control deviations such as setpoint overshoot.
Consumer temperature controlled sous vide units exist, but typically sell for around $500. I decided to build my own, as my controls engineer friend put it: “you have the rightful indignation of somebody who knows they’re getting ripped off.”
I decided to combine Potter’s approach with my controls knowledge to build the plug and play crock pot PID controller that can control the cooking temperature to within 1°F, which is probably far more precision than is necessary.
The controller is generic and works with any crock pot with an analog on/off switch. The crock pot is set to the on position (‘high’) and a temperature probe is inserted into the pot. The user sets the desired cooking temperature and the controller does the rest.
By itself, a crock pot does a poor job of maintaining an arbitrary constant tempature (not sure what the disturbances at the beginning are):
Using the temperature cutoff method suggested by Potter, the control is fairly good:
Notice how the temperature overshoots the target by 2 – 3°F and how the temperature spends time below the desired setpoint. The overshoots are caused because heat is applied until the measured temperature exceeds the setpoint, there is a delay between when heat is applied at the bottom and the water around the temperature sensor in the middle of the pot heats up. By that time, too much heat has been applied. This is pretty good, but we can do better.
At the heart of the controller is an Arduino Pro Mini. This receives temperature input from a Dallas 1-Wire DS1820 sensor inserted into a thermowell. The Arduino manipulates an opto-isolator/triac combination to switch the power on/off to the crock pot, which is a standard 5 qt crock pot. Status is displayed on a Sparkfun Serial LCD screen and settings are changed through a button pad. A zero-cross detection IC (H11A1) detects the zero point on the AC line to allow for heat control. Power to the crock pot is controlled by quickly turning the triac on and off, truncating the AC waveform, similar to an incandescent light dimming circuit.
A single 120V AC line powers both the microcontroller and the crock pot. A gutted 9V DC wall wart taps into incoming AC lines. A voltage regulator (not shown in the schematics) converts the power into 5V that the microcontroller can use.
A summary of the major components:
- Arduino Pro Mini – Sparkfun DEV-09218
- Sparkfun Serial Enabled 16×2 LCD – Sparkfun LCD-09395
- 1-Wire Temperature Sensor – Maxim Dallas DS1820 (hint: request free sample)
- Thermowell compatiable with 1-Wire sensor – Brewer’s Hardware
- Wall Adapter Power Supply 9VDC – Sparkfun TOL-00298
- Simple Crock Pot, any will work – Crock-Pot SCR500SS
- Optoisolator MOC3020 – 3023 – Incorrectly shown as MOC3042M in the schematic
- Zero-cross Detector H11AA1 – Incorrectly shown as H11AA1M in the schematic
- Isolated Gate Triac Q6008L5- Incorrectly shown as BT136 in the schematic, any triac should work
- AC Connector Male – Digikey CCM1400-ND
- NEMA AC Receptacle – Digikey Q337-ND
- Resistors values as shown – Note that some readers have found it necessary to decrease the value of R4 to ~240 ohm to get the optoisolator to fire
The Eagle schematics and layouts are provided in the downloads section. Please see the parts list above for the correct part numbers.
To aid in the discussion, I use the following terminology:
- PV – Present Value, the current value of the temperature sensor in the water bath, in °F.
- SP – Set Point, the desired temperature of the water bath, also in °F.
- OP – Output, the amount of heat that the crock pot is currently applying to the bath. My controller allows for 255 levels of heat, 0 is none and 255 is full on.
- Mode – Operating mode of the controller. ‘Auto’ uses the PID algorithm. ‘Cutoff’ applies full heat until the PV exceeds the SP, at which point the heat is turned off. ‘Manual’ allows the user to set the OP directly with no control algorithm.
- K – Proportional constant
- τI – Integral constant (min)
- τD – Differential constant (min)
I won’t go over the theory or background of PID controllers, there are already plenty of sources that cover that in detail, however, details regarding the tuning of this controller are covered in the aptly named Tuning section.
I opted for the discrete PID type B equation to calculate the required output:
- k = control index, incremented each cycle
- e = error = SP – PV
- ƒ = control frequency (min)
The traditional equation (type A) uses error for the proportional, integeral and differential elements. This can lead to large changes in the OP when the SP is changed. In type B, the error is used on the proportional and integral terms and the PV is used on the differential.
The zero-cross chip is connected to one of the interrupt pins on the Arudino. When the AC signal crosses the zero point, approximately every 8.3 ms, an interrupt routine calculates the next time the power to the crock pot should be turned on based on the OP and the microseconds since the program started (micros()). For low and high OPs, the power is either completely on or off due to main program loop overhead and input checking.
At the start of each program loop, micros() is checked to see if its time to turn on the triac and power the crock pot. If it is time, the power output pin is set high and the triac is set. After a small delay to ensure the triac sets, the output pin is set low, the triac will remain on until the next AC zero-cross, at which time it will reset.
Next the program loop checks if a new temperature from the 1-Wire bus is available to read (every 10 seconds). The temperature sensor is setup in a parasite power configuration, so it can take upwards of 750 ms for the read to be complete. If the temperature is available, it is read off the bus and checked for validity.
If the control Mode is ‘Auto’, and it is time to take a control action (every 30 seconds). The new OP, based on the current temperature, is calculated using the above PID equation. It is ranged to be within [0…255]. Old values of the PV, OP and errors are stored to aid in the calculation of the PID equation (the k-1 and k-2 terms).
If the Mode is ‘Cutoff’, then the PV is checked against the SP. If it is above the SP, then the OP is set to 0, otherwise the OP is set to 255.
The display is updated and the button inputs are checked. Any changes to the SP or Mode are handled. Then a temperature read is started on the 1-Wire bus if necessary. The whole process starts again. The timing in the main loop isn’t perfect (i.e. button presses will slighly throw off the heat rate), but the deviations are smoothed out over the long run.
There are additional features in the code (e.g. various safety checks and interlocks, PID initialization, LCD control) that have not been discussed. The full code is available below in the downloads section.
The key to an effective PID control is the proper selection of the K, τI and τD tuning constants. These constants depend on the system gain (change in PV for change in OP) and the system deadtime (delay between a change in OP and a response in the PV). These are in turn factors of the size of the crock pot, the amperage delievered to the heating coils, the volume of water in the bath and so forth.
Note that cheaper crock pots may or may not have different peak temperatures depending on the setting. I always kept my crock pot set to high to get a better range of controlability.
This system is simple and can be modeled as a first-order system with dead time (see uncontrolled response graph above). The transfer function for this system:
Where G is the system value. The parameters that define the system (and hence its tuning) are present. K is the gain, td is the dead time and τ is the time constant. s is in the frequency domain and can be converted to the time domain using a Lapase transform. A rigorous application of first principles, transfer functions and Lapase transforms yields a model that would allow us to pick tuning constants and see the time dependent behavior. Though useful, it is extremely academic and not often applied in the real world.
Instead, we’ll use an open-loop tuning method. For this, we allow the system (the crock pot) to reach steady-state (a constant temperature) by applying a constant amount of power. Once at steady-state, we make a step change to the power and again allow the system is come to steady set. This allows us to determine the gain, time constant and dead time of the system.
Allowing the system to come to steady state, the open-loop step response curve was developed:
The time constant, τ, is defined as when the process reaches 1 – 1/e = 63.2% of its final value. The dead time, td, is the delay between changing the OP and a response in the PV. For my particular crock pot,
- τ = 266 min
- td = 17 min
- K = 3.44 °F/#
There are a variety of open-loop tuning methods that determine the K, τI and τD tuning constants based on the previous constants: Ziegler-Nichols, Cohen-Coon and ITAE. The formulas for these various methods yielded the following results:
Each of these methods are designed to tune in different ways and serve as a starting point for manually tuning the process. Ziegler-Nichols tunes for an aggressive quarter-decay ratio and tends to overshoot the SP, but it does better at rejecting distribances. Cohen-Coon is intended to be an improvement to Ziegler-Nichols. Regardless, all these methods assume the classic PID type A equation.
I used the Cohen-Coon values as the starting point for my tuning. Then I disturbed the system (added ice) and watched how the system responded. I ended up with my final tuning values of:
- K = 0.1
- τI = 150
- τD = 0.45
The small proportional constant limits large OP changes due to large deviations from the SP and maintains some stability. The larger integral term limits the time spent away from the SP, at the risk of some overshoot for large changes. The derivative term limits the overshoot, it is small to limit the introduction of noise into the system from noise in the temperature measurement. Due to the jumpiness it can cause, often the derivative component is not used, creating a PI controller.
These constants work quite well. Notice how the overshoot from the SP is limited to 3.5°F and once the control is working properly, the deviation is limited to ~1°F (the square pattern is the effect of the low resolution DS1820 temperature sensor, only accurate to 0.5°C). Heat is applied over time to maintain temperature and the PV never drops below the SP over a course of 2 days!
For awhile, I’ve been wanting to try Ponoko. You upload a design and they will fabricate it using a laser cutter or 3d printer. I found a coupon code for 50% off materials and making (now expired) and decided that it was time to try the service.
Ponoko provides an extensive set of instructions and templates to help get you started. I laid out the six sides of my enclosure with an interlocking joint pattern to hold the pieces together. I then added cutouts for the LCD and button pad. Also etched on the front is a handy safe meat internal temeratures chart from the FDA. I choose to have them laser cut and etch my design onto 1/8″ silver acrylic. The manufacturing turn-around was 2 weeks.
The cuts were precise and everything fit together perfectly. The enclosure is held together with epoxy and holes for screws were drilled by hand.
The EPS file sent to Ponoko for manufacturing is included in the downloads section. I ended up using Adobe Illustrator to do the design instead of the free Inkscape software. When verifying my design by printing it on paper, I found that the dimensions from Inkscape didn’t match reality. With Illustrator my desired dimension and actual dimensions matched up correctly.
I estimate the cost of all the eletronics was ~$50. The enclosure, including shipping, was $34. Allowing for the cost of miscellaneous materials, the total cost was ~$100 plus time and labor. The end result is a robust temperature control that succeeds in cooking to within 1°F of the target.
For the inaugural test I decided to try a 48 hour brisket recipe: Salt to taste, flavor with worcester sauce, vacuum seal and cook for 48 hours at 142°F. The result is an evenly-cooked, moist and delicious brisket.
Projects Inspired by this One
Several people have built their own variations on the PID controller presented on this page. Send a link to your write-up and I’ll add you to the list.
- Kris Fredrick’s Crock-Pot Yogurt Controller
|Controller Board Schematic: Eagle schematic for the controller board. (66.77 kB)|
27 Mar 2011 2589 downloads
|Controller Board Layout: Eagle layout for the controller board. (18.82 kB)|
27 Mar 2011 1504 downloads
|Button Pad Schematic: Eagle schematic for the button pad. (51.95 kB)|
27 Mar 2011 1200 downloads
|Button Pad Layout: Eagle layout for the button pad. (8.16 kB)|
27 Mar 2011 1148 downloads
|Sous Vide Code: Arduino code for the sous vide controller. (15.82 kB)|
27 Mar 2011 3753 downloads
|Sous vide Enclosure: The layout used for fabricating the enclosure with Ponoko (73.02 kB)|
27 Mar 2011 986 downloads
I release the software and design into the Creative Commons. Feel free to modify, but let me know what you do with it.