Back to the front page


The Sous Vader

January 2013

If you keep up with what's trendy in cooking, you might be aware of sous vide. This style of cooking involves vacuum sealing your food and then cooking it in a precisely temperature controlled water bath, typically for long periods at low temperatures. Despite the name ('under vacuum'), the vacuum sealing is seldom the critical aspect of sous vide dishes. Instead, it is the superb temperature control which yields such interesting results - you can essentially select which chemical reactions occur in the food, and you can do it in an extremely reproducible fashion. This is exciting for two reasons: you can get some truly excellent cooking results, but you can also do it very repeatably and with minimal effort.

Naturally, commercial equipment exists for sous vide cooking. Possibly the most famous of these is the Sous Vide Supreme, but this product line starts at $600 AUD. Unless you're very serious about cooking or have plenty of disposable income, you probably won't get to play with one of these. Cheaper options are available and expanding as the popularity of the technique grows, such as the $360 Nomiku or the $160 SousVideMagic. The latter is a a sous vide controller, meaning you connect your own rice cooker to it rather than it being a stand-alone unit. In this article I'm going to discuss my efforts in designing my own sous vide controller, for the delightful price of $100 AUD (more like $60 if you already have an AC adapter and enclosure).

I'll take you through the build details, because the fact that you've arrived at this website suggests you're into that sort of thing. Hopefully there's enough information here for you to modify and design one of your own. I don't have a stack of these in a backroom or anything, but if you're interested in having one made (or just getting kit-style parts for one), email me before Disney sends me a stern letter about star-wars copyright infringement.

Part 1: Hardware

The approach we'll take is to operate a rice cooker (or crockpot, or water distiller etc.) as a temperature controlled water bath, under the assumption that one of these appliances is already kicking around in your kitchen. We'll do this by creating a special mains AC socket, one which will control the amount of power going into the cooker in order to maintain a desired bath temperature. A quite nice aspect of this approach is that once you're done, you can just unplug the control box and you have your rice cooker back. (It's important however that the rice cooker is simple - units with digital readouts or other such fanciness probably won't work.)

The first part of this problem is getting control of mains AC electricity. In the simplest case, this means simply being able to switch it on and off in a controlled way. You may be familiar with techniques for switching DC electricity with a transistor, but these won't work for switching mains. If you're distrustful of semiconductor physics and you don't mind the cacophony, a simple solution could be a mechanical relay - the switching frequencies we'll end up using here are quite slow, so this is workable if inelegant. If your tastes run more to the solid-state, the conventional, cheaper solution is to use a triac. I won't go into the details here - in Figure 1 I've shown the configuration of a triac and accompanying driver circuit, and for the rest of this discussion I'll simply abstract this block as an logic-level controlled on/off switch for the AC. The triac I used (Q4025L6) is rated to 25A at 400V, which is more than enough for this purpose - the rice cooker I'm using has a nominal power rating of 350W, which corresponds to about 1.5A at 240V.

The 1/4W 680Ω resistor serves two purposes, which together dictate this resistance value. It limits the current through the 'switch' side of the optocoupler to a safe value, while at the same time allowing enough current into the triac gate to switch it on. The current limit for the MOC3023 ("ITSM") is 1A. The peak current from 240V mains through a 680Ω resistor is (240V*1.414)/680Ω = 500mA, so we're safe. As for triggering the triac, the gate threshold current for the Q4025 is 80mA. This will be reached when the mains AC voltage reaches a value of:
Mains voltage = V_resistor + V_optocoupler + V_gate
= (80mA * 680Ω) + 3V + 2.5V
= 59.9V
where I've used the datasheet values of "VGT" for the triac and "VTM max" for the MOC3023. The 240V mains reaches a value of ±59.9V after 10.1° of each 180° half-wave:
sin-1(59.9/(240 * 1.414)) = 10.1°
How much power goes unused because the triac doesn't trigger until 10.1° into the AC wave? Not much: it uses 99.2% of full power. Teccor's AN1003 has a nice plot that will tell you this, but to calculate it yourself you just integrate the waveform over the region where the triac is turned on. Skipping some steps, in the present case that will lead to:
Ratio of full power = (cos(10.1) - cos(180))/2 = 0.992
In reality it's probably even better, since 80mA is the minimum current to guarantee turning on the triac. The typical threshold can be substantially less.

The rest of the schematic shows the fused mains input on the left (240V/50Hz) and a control socket on the right which we'll plug the rice cooker into. At the top of the figure there is a DC plugpack, also fused. This produces a low voltage DC supply line for the rest of the electronics, and most importantly it allows me to avoid rolling my own AC->DC adapter ... that's a project for another day.

I haven't built any zero-crossing detection into this, so the control electronics have no idea about the phase of the mains AC. I didn't think it was necessary, but if you like you could easily add it in with a couple of resistors and an extra pin on the microcontroller. There are several nice application notes from Atmel and Microchip discussing how to do this.

Let's now move on the digital side of the board:

An ATMega328 microcontroller is doing all the thinking in this project. Cheaper controllers would certainly work, but I'm using that 32kB pile of memory to facilitate a text-based menu system. This is also the processor used in the Arduino, so you should have minimal trouble adapting the project if that's the way you lean. The temperature sensor is the venerable DS18B20 in a waterproof housing. This sensor is rated to 125°C, which is plenty for sous-vide cooking - I seldom go higher than 65°C. A 4 line, 20 character LCD allows the display of status information, and with the help of 3 tactile buttons also permits a menu system for setting parameters. A bluetooth module (JY-MCU board from ebay) provides a cheap form of wireless serial output, which as we shall see shortly can be quite useful. Lastly there's a speaker in there. A sous-vide cooker doesn't really need a speaker, but is anything not improved by the ability to play a bleepy version of The Imperial March?

Excluding the AC adapter, all of that comes to about $50. Add another $5 for a small aquarium pump to circulate water in the bath - this is quite important for obtaining a stable temperature. These are cheap on ebay, but they don't tend last long if you're cooking above about 65°C.

The assembled system is shown below. The final total cost comes to around $100 AUD, which includes a $20 AC adapter. You can get those much cheaper on ebay, but I've had bad experiences with cheap wall adapters.

Lastly, we should do something about the fact that it's ugly by putting a nice faceplate on there. I made something up in Inkscape, printed and laminated it then stuck it on with double sided tape. This gives labels for the buttons, a super cool logo and a nice LCD window (cut out a rectangle before laminating). Importantly, it also hides any scruffiness you might have introduced when dremeling the cutouts in the case.

And with that, the Sous Vader is created. Physically, at least - without a program on that microcontroller it's not very useful. What shall we have it do?

Part 2: Firmware and PI loops

The complete firmware for the ATMega328 is available here (start with sousvide.c). The essence of the project lies with being able to set a variable output power through the triac, and knowing how to set it in a way that maintains a desired temperature.

The variable output power comes from a very simple form of pulse width modulation. One of the internal timers in the mega328 counts through 100 'ticks' over the space of about 2.6 seconds. The variable `Mains_OutputPower' is used to set how many of these ticks the triac should be held on for. A value of 100 means the triac is on the entire time, and the load sees a normal mains socket. A value of 40 would means that the triac is on for 40 ticks then off for the remaining 60, then on for another 40, then off for 60 ... Averaged over several tens of seconds, this is no different to providing a steady 40% of full power. Note that because the load is a plain old resistive heating element and because it has a lot of thermal mass, it's quite forgiving of both having such a slow duty cycle and of cutting the power in and out with no regard for the phase.

The more interesting part is how to establish a feedback loop so that the output is automatically adjusted to maintain a temperature. Feedback and control systems constitute an entire academic field, and I'm no expert. In the end I've gone with a classic proportional-integral loop, which is of course 2/3 of a PID loop.

The idea is to regularly measure the difference between the parameter you're trying to control and the desired value of that parameter, with this difference called the error:

Error = Setpoint - TemperatureReading

Each iteration you multiply this error by some fixed number (ProportionalTerm, abbreviated P), and if this were purely a proportional loop you'd be done:

OutputPower = ProportionalTerm * Error
Assuming your ProportionalTerm has the correct sign (i.e. pushes the system towards setpoint rather than away), the error will grow smaller - it might overshoot and bounce around a little, but eventually you'll land on a value of OutputPower that keeps things roughly where you want them.

Actually what you tend to find is that you'll come quite close to your setpoint without sitting exactly on top of it. This is because when you're perfectly on setpoint, the error term is zero and so your output power is also zero. But with no output power, the temperature will droop ... the only stable configuration is one with a little bit of error in order to 'drive' the proportional loop.

For this reason you can include an integral term (making it a PI loop). The idea is to keep some memory of how bad the error has been lately. So now we do one more thing in each iteration:

IntegratedError = IntegratedError + Error

If the error does not settle on zero, this IntegratedError term is going to grow larger and larger with each iteration (in fact the only way to reduce it is to have a negative error, i.e. to overshoot). We capitalize on this behaviour by putting it into our OutputPower calculation with a multiplying IntegralTerm (abbreviated I):

OutputPower = (ProportionalTerm * Error) + (IntegralTerm * IntegratedError)

Now we have the proportional part of the loop doing most of the work, with the integral part getting rid of the droop and making the zero-error state stable. I stopped here - you could also add a derivative term to help prevent overshooting if you like, but in this particular application it's not really necessary.

The process of picking good values for the P and I terms is called tuning, and the aim is to find values that take you quickly to the setpoint without too much overshooting and oscillation. The classic (though not the only) technique for tuning a PID loop is the Ziegler-Nichols method. It begins by operating the system under purely proportional control, and slowly increasing the P value until the output begins to oscillate without decaying. Bear with me, there's an example coming. Call this the critical P value, PC, and measure the time period of the oscillation, TC. In the case of a PI controller, you then set P=PC/2.2 and I=1.2*PC/TC.

Upon hearing this, you may be curious about where these magic numbers have come from. The original 1941 paper is free online, and if you read it you'll learn that there's nothing particularly fundamental about Ziegler-Nichols tuning. It's educated trial and error, so by all means use it as your starting point but don't assume that it's some analytically derived optimum.

Before we move on to looking at the tuning experiments, I have to point out this unusual disclaimer from the Zeigler-Nichols paper:

"...no attempt will be made ... to make acknowledgement of material from published literature"
And sure enough, there are no references anywhere the paper.

Back on task. Carrying out this tuning procedure requires you to record the temperature as a function of time, and at this point the bluetooth transmitter included in the Sous Vader proves itself invaluable. A typical temperature curve with no integral feedback term looks like the one shown below:

The rice cooker takes about half an hour to bring the water up to temperature, overshoots and then settles close to the programmed setpoint. How long this takes very much depends on the starting temperature - filling the bath from the hot tap can easily save half an hour.

The first part of the tuning process is to find the value of P at which the temperature first starts to oscillate. To do this I set up some custom firmware to loop through different values of the P constant, then just left it going for a day or two. The results are shown in Figure 6, and I've highlighted in green the trace at P=1200, which is where I think the steady oscillations first start. The frequency of these oscillations is very close to 9 per hour, a period of 130 samples (3 seconds/sample).

According to Zeigler-Nichols, the optimum P value is therefore 1200/2.2 = 545, and the optimum I value is in the vicinity of (1.2*1200)/133 = 10.8. Armed with that information, I started another series of measurements, this time fixing the P value at 600 and sweeping through I values:

This plot demonstrates the effect of the integral term. With only a proportional term (black trace), the control loop does a respectable job but is drooping outside the desired 0.1°C regulation band. Adding a small integral term immediately fixes this, but too much and the loop becomes unstable. In this particular case it looks like I=2 is about right, which goes to show that Ziegler-Nichols should be used just a starting point. I imagine that if you changed the appliance used for the bath (e.g. swapped in a crockpot or a different rice cooker) these terms would need adjusting. Probably there is enough computational power in the microcontroller to set up some kind of auto-tune function, but that's a job for another day.

And with that we've got a tuned sous vide cooker, ready to go! I don't have any epic food photos to tantalize you with, but I can assure you that the Sous Vader works very well. For the last few months it's been busy cooking eggs, steaks, pulled pork and creme brulee custards. I don't own a vacuum sealer, but as I mentioned earlier this is not really a deal breaker. When food needs to be bagged you can get by just fine using ziplock bags, dipped in a sink full of water to squeeze all the air out. (You might want to spend a few minutes reading about plastics and food safety though).

Finally, here's a photo of development in progress, in a wardrobe. It's good to either have a spare room or a tolerant partner.


Back to the front page