Sous Vide (french for under vacuum) is a cooking technique where food is sealed in airtight plastic bags and submerged in a water bath held at a specific temperature. Cooking sous vide usually takes a long time, but it has the advantage that the food is cooked perfectly evenly, you are able to heat a steak to the exact same temperature through out the entire piece of meat. A cut through a normal steak cooked on a pan usually reveals a gradient going from brown/gray to pink/red in the middle – less heat penetrate to the middle, so when the inside is medium rare the outside is usually well done++. A cut through a sous vide cooked steak looks more like the above – constant color and consistency through out the entire steak (the steak is normally finished (very quickly) in a frying pan to caramelize and kill any surface bacteria). The result tastes really great, and it’s hard to mess up – you can leave a steak in the water bath for hours without any problems. Cooking in a bag preserves so much of the moisture in the meat, and the long cooking time breaks down a lot of the connective tissue – leaving you with a perfectly cooked steak that is super-moist and tender enough to eat with only a fork.


Sous-vide BabyTop

Photo by FotoosVanRobin – CC BY-SA 2.0


A professional sous vide setup costs at least >$1000, so it’s a bit out of reach for the normal home cook – except for the DIYers.. It’s not that hard to build yourself if you put your mind to it. What you need is the following components:

  1. Water bath with a electric heater.
  2. Some method of circulating the water.
  3. A way of accurately regulate the heater based on water temperature
  4. Some way of plastic bag packing you meat.

Water bath with heater is easy enough, there are tons of items out there that does this – slow cookers and rice cookers for example. I use a simple rice cooker, the cheaper/simpler the better (we’re going to cycle it’s power on/off, a dumb cooker will behave better facing a power loss). To circulate the water I use a simple ebay aquarium pump (payed $9.90 for mine). To pack the meat in airtight bags you can either buy a cheap vacuum-packer or simply use zip-lock bags (fill your sink with water, add meat to bag, submerge bag in water but keep the opening above waterlevel – pressure from the water will press out all the air, seal the bag..) 

That’s the easy part, the hard part is regulating the heater to accurately hit a specific temperature. A simple thermostat won’t do, because of the long dead time in such a system – you end up with a cycle overshooting and undershooting the target temperature – this is a job for a real PID controller (proportional–integral–derivative controller)

A PID-controller monitors a system and tries to bring it to a specific state by providing a output value. For example, monitors the temperature of a water bath and tries to bring it to exactly 60 degrees celcius by regulating a heater. The forumula consists of three terms, first the gain – how hard to press the pedel to accelerate to a certain speed based on the current speed. The second part is an integral, looking back, how fast where we changing when we applied this much pressure to the pedal in the past.. Third term is a derivative trying to predict the future, when do I need to stop accelerating to be able to make the next turn.

Implementing such a formula seems straight forward and only requires a few lines of codes – but there are surprisingly many things to concider and special cases to deal with when implementing it – read more about it at Brett Beuregard’s blog. Brett has made a nice library for atmel microcontrollers (arduino based), you can find it here: PID v1.

So what I have done is to make a microcontroller based PID controller. It’s based on an Atmega 328p chip running the arduino bootloader, it has three buttons and an 4×20 character LCD to handle user interaction. And a DS18B20 one wire temperature sensor to meassure the temperature of my water bath and a SSR (Solid State Relay) to cycle the power of the rice cooker on and off.

It’s a fairly simple build, all of the components can be bought cheaply on ebay or electronicsshops like futurlec.

If the video doesn’t work, click here: 

See schematic and pictures of the setup below:

Bill of materials:

  • Atmega 328p (futurlec)
  • 3 Buttons (ebay)
  • 20×4 LCD (ebay)
  • Solid state relay (ebay – Futek) – you might need a heatsink, i use the metal plate in my enclosure.
  • Contrast potmeter
  • LED
  • 16 mhz crystal / ceramic resonnator
  • Basic resistors, capacitors, transistors
  • Enclosure, preferably with metal backplate (ebay..)
  • 220 IEC input and output sockets (futurlec..)
  • DS18B20 temperature probe (ebay..)
  • Stripboard (ebay)

In total I think it cost me around $30 to build it (not including the pump and rice cooker), not too bad. You could easily make it cheaper by using simpler items – do you really need a 20×4 LCD? 

The source code is available at Bitbucket, please feel free to use it for whatever you want:

Note that the schematic doesn’t include power curcuit and programming headers.

I’ve built the controller into a simple case (w/ metal backplate) I found on ebay. If you have a powerful heater you should concider adding a heatsink to the SSR, they can get hot when switching large currents. With the metal-backplating, my 350W rice cooker never even make the SSR go above room temperature. See pictures of the case and setup below:

Future work:

  • It needs a bit of calibration (the gain, integral and derivative) to avoid initial overshoot and small ocillations when changing load.
  • Add bluetooth, I have a small bluetooth to ttl module I can connect to get wireless serial (to interface it with pid controller gui)
  • Add internal power supply, should be enough space in the box for a 5v transformer.

Stay tuned for more posts on how to calibrate the beast πŸ™‚

Also, check out eGullet for more information about cooking Sous Vide (temperature tables.. recipes.. safety concerns..)


36 thoughts on “SousVide-O-Mator

  1. What about the cooking part. I’ve looked for some resources on sous vide cooking times n temperatures, but they where a bit contradictory on these parts.Some said you should leave the meat on a temperature above the well done point, for some time (more the half an hour, I think). Can you share your experience on this part?

  2. Italo: I will post about some of my cooking experiences soon, however, I would recommend using the eGullet website as a resource for the cooking part. They have temperature tables for different kinds of meat and a large section for Sous Vide in general.Check out the index post at: hope you find answers to your questions there πŸ™‚ I’m still just getting started with Sous Vide cooking myself.

  3. Thanks so much for sharing the build instructions and code. I’ve just completed my own sousvide-o-mator and its working quite nicely. I have noticed however that it’s tending to overshoot when items are added into the pot and the temperature takes a while to come back down.For cooking eggs at 64C for 60 minutes, the temperature remains at around 67-68C for the first 30 minutes and just barely reaches 64 for the last 10 minutes or so. I am using quite a small rice cooker with no water pump so might this be the reason? Stirring the water lowers the measured temperature slightly but once the stirring stops the temp goes back up. When there is only water in the pot it holds the temperature quite nicely after about 30 minutes or so.Thank you for your help in advance!

  4. HxorN00b: the PID-controller needs to be calibrated to avoid overshooting – for many systems overshooting is not a problem, for hot water in a insulated container it is – takes ages to cool back down (pump certainly helps, and also achieves an even temperature).. I’m in the process of doing it with my own controller, the settings are dependent on the system (how efficient / powerful is the heater, how much water is in the pot, how well is it insulated, etc).My current settings are like this:PID pid(&pidInput, &pidOutput, &pidSetPoint, 1.8, 0.3, 50, DIRECT);P:1.8, I:0.3 and D:50Try these values out, fill water that is say 40 degrees in the pot, set target value to 50.. It will most likely do one (hopefully very) small overshoot and one small undershoot before stabilizing. If it still overshoots too much, try increasing the D.. if that doesn’t work out too well, try decreasing the other values slightly.You can also use Brett’s PID GUI to plot a temperature graph, that’s very helpful for calibrating: (PID Frontend V3)

  5. How did you power your board? Did you have an external power supply or did you suck it from the 240v with an internal transformer?

      • You can barely see it on the pictures, left side of the box contains microcontroller and board, right side contains SSR and 220v In and Out.
        I don’t have any better pictures now, sorry. But I have plans for a few modifications the next weeks (if I have the time..), including adding a thermal fuse for safety, as I want to go for a more powerful heating source. Also considering better heat sinking – we’ll see.

        I’ll take some more detailed pictures the next time I have the box open.

        Also need to update the software a bit (pde -> ino, etc..).

  6. Did you use a pull up resistor on the three button pins? Also did you put a current limiting resistor between ground and the three buttons? (I am quite new to circuit building, this will be my first arduino project)

    • Both yes and no πŸ˜‰ There are no resistors added, but the atmega328 has configurable 20k ohm pull-up/down resistors on it’s pins that you can set in software.

      In the code it’s done by a button library:
      Button btnUp = Button(BTN_UP, PULLUP);
      Button btnDown = Button(BTN_DOWN, PULLUP);
      Button btnSet = Button(BTN_SET, PULLUP);

      But behind the scenes on a arduino this is simply:
      pinMode(pin, INPUT); // set pin to input
      digitalWrite(pin, HIGH); // turn on pullup resistors

      • Thanks for the reply. This is a little different to using the GPIO on the rapberry pi. I guess the atmega328 is purpose built rather than the Pi. Received most of my components and looking forward to

      • Having a litte trouble compiling the sketch. Very new to Arduino!

        Getting the following error: (I was getting the button errors, but corrected that using the suggestion in the comments section of the sketch)

        /Users/john/Documents/Arduino/libraries/PID_v1/PID_v1.cpp: In constructor ‘PID::PID(double*, double*, double*, double, double, double, int)’:
        /Users/john/Documents/Arduino/libraries/PID_v1/PID_v1.cpp:26: error: ‘millis’ was not declared in this scope
        /Users/john/Documents/Arduino/libraries/PID_v1/PID_v1.cpp: In member function ‘void PID::Compute()’:
        /Users/john/Documents/Arduino/libraries/PID_v1/PID_v1.cpp:43: error: ‘millis’ was not declared in this scope

        Thanks for any help

      • Great that you figured it out! πŸ™‚
        I havn’t had the time to update it to Arduino 1.0, and I guess that was also what broke the PID library (1.0 had some breaking changes). I’ve recently added a 5v external power to mine, as bluetooth was a battery hog. Will soon(tm) update the software and also add a thermal fuse that just arrived in the mail. Will post an update when it’s done πŸ™‚

  7. I am going to power mine from a usb–>serial adapter that is hard wired in the circuit. That way I can either power it from my PC for programming it or via a USB mains adapter. I may have to see if I can run the bluetooth at the same time as powering from the USB adapter.

    • Sorry for the late reply.
      The source as it is does not send to PID frontend.

      But it’s pretty easy to add..

      void SerialSend()
      Serial.print(“PID “);
      Serial.print(” “);
      Serial.print(” “);
      Serial.print(” “);
      Serial.print(” “);
      Serial.print(” “);
      Serial.print(” “);
      if(pid.GetMode()==AUTOMATIC) Serial.print(“Automatic”);
      else Serial.print(“Manual”);
      Serial.print(” “);
      if(pid.GetDirection()==DIRECT) Serial.println(“Direct”);
      else Serial.println(“Reverse”);

      and then you call it from the main loop like every 500/1000 ms.

      Check out the examples in pidfrontend.

  8. Hi Stian, trying to build your SousVide-O-Mator, new to arduino using vers 1.0.1 and get “‘button’ does not name type” tried the fix in the code “button_pullup” same thing.I downloaded “button.pde” and is in the library. The link for “button.ino” does not work and I can’t find it anywhere, any help would be great.

      • Thanks Stian, that worked and also fixed a bunch of PID errors that were coming up.


      • Eventually built my arduino circuit.

        Having issues with the LCD and buttons. The LCD is probably an incorect connection at some point – will look in detail of the pin-outs

        However the buttons are acting as if the internal pullup resistors aren’t activated. They just randomly activate. Any ideas? I had to change PULLUP to BUTTON_PULLUP in line 75-77. Do you have an old version of the button library I can try?

      • Replying to my own post….. I think it should be BUTTON_PULLUP_INTERNAL rather than PULLUP or BUTTON_PULLUP. I need to go to work so cant test it but pretty confident this should work, I will report back if it does.
        Just need to sort out my LCD now!

  9. The BUTTON_PULLUP_INTERNAL worked a treat
    I have added the PIDFRONTEND output to the code as well with success.

    I have created a fork for my own reference, not sure if it is any help to you (quite new to bitbucket/coding so excuse any mistakes)

    It also includes a pdf of my veroboard layout in case anyone wants a design, I will add photos at of the board and finished project at some point.

      • This Arduino coding is quite easy! Haven’t really done any serious programming before but I have been able to cobble together quite a lot of changes from examples elsewhere.

        I am now going to use an illuminated RGB rotary encoder (SparkFun for selecting modes and changing temp. Pressing the rotary encoder button with change from cooking to setup mode. Rotating it will change the temp in 0.5 degree increments. In cooking mode it will illuminate green and in setup mode it will be red.

        The output LED will also change brightness depending on the pidOutput (divided by 5, I think the maximum pidOutput is 2000?, so that the output is between 0-256). I found flashing on and off was a bit disconcerting!

        I have made a new branch for these changes as I haven’t actually got my rotary encoder yet.

        I am happy for any of my ‘code’ (actually copy and paste from elsewhere!) to be incorporated if you want.

      • That’s a really good idea πŸ™‚
        Rotary encoders are great for this stuff, especially the one you found with rgb.

        Btw, check out map() from the arduino library.
        It’s badly named, since map is usually means something else (map/reduce/filter), but what it does here is map a value from one range into a value of another range.

  10. Hello, I’m trying to use a 16 x 2 LCD, changed changed all cursor begins to (0,0) and (0,1) and limited characters to 16, just get some jibberish in the left four positions. Sure I’m not doing something right, anyone sorted this out?

  11. Just a quick note that I have made significant progress on your code

    – bar graph on LCD to show PID output ‘strength’
    – configurable to use push buttons or a rotary select
    – configurable to use an RGB LED to show status (with fade effects!)
    – defaults to push button input and RGB LED disabled (but can easily be changed in first few lines of setup code)
    – changed header file so changing options e.g. PID values is easier

    Turn LED blue when it is ‘under’ temperature
    Timer for how long the water has been at temperature for

    Feel free for anyone to use and copy code (as I have done!)

    • just updated again:

      – added RGB LED which varies depending on status (fade red on/off for setup, blue for cold, green for at temp, red for over temp)
      – cooking timer – starts when above set temp and stops each time below temp (allows 0.5c variability)
      – high timer starts when temp 0.5c above set temp (cooking timer continues)
      – low timer starts when temp 0.5c below set temp (cooking timer pauses)
      – 0.5c error can be changed in #define error header line
      – whilst in cooking mode ‘cooking’ timer is always on. Low/high temp can be alternatively displayed by up/down button or turning rotary dial
      – timers reset if enter setup mode

      Will be my last update in a while as have a new baby in the house.

      If anyone wishes to fork the code please do, and let us know any updates/enhancements so I can use them!

      Any questions how I setup my board etc please ask. I do have photos I can send on.

      • Oh, and there is a word document with circuit diagram and explanation notes on the bitbucket site.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s