Yogurt is good. Homemade yogurt is even better. So, let's make yogurt! Before we get to the hardware/software, it's important to understand where does yogurt come from. The key element is a bacteria called Lactobacillus. According to Wikipedia: "Some Lactobacillus species are used as starter cultures in industry for controlled fermentation in the production of yogurt, cheese, sauerkraut, pickles, beer, wine, cider, kimchi, cocoa, kefir, and other fermented foods, as well as animal feeds. [...] Lactobacillus is a member of the lactic acid bacteria group (its members convert lactose and other sugars to lactic acid)".
Ok, so we put the Lactobacillus in the milk and wait for the bacteria to do there job (convert lactose to lactic acid). Theoretically, yes. But there are some important points that must be observed.
- The milk must be free from contaminants. The best way to get this is using powdered milk and filtered water.
- The starter culture can be a small amount of plain natural yogurt from your local grocery.
- The mixture milk + starter must be kept in a closed container to avoid contamination with other fungi and bacteria present in the air. Also, the mixture has to stay for 6 hours at 37°C. This is the ideal temperature for the Lactobacillus life-cycle.
Summing up: Get some milk, add starter (natural yogurt) put it in the closed container and keep it at 37°C for 6 hours.
Step 1: The Reactor
When I say reactor, I mean "a place or container where a (biological or chemical) reaction takes place". This is the term used by chemical engineers. In our case, the reactor is a container with controlled temperature.
Before we continue, I want to make it clear that the solution I implemented is rudimentary and was built on a Sunday morning, when all hardware stores were closed, using only material and components that were at hand. As a matter of fact, that was the funny part... Something like the Apollo 13 challenge - solve the problem with whatever you have at hand. It should be used as a starting for a more elegant solution.
My reactor was made of a large bowl with water. The mixture milk+starter was placed in small pots with lids and these were accommodated in the bowl. Now, all I needed was a system to control the temperature of the water and keep it warm (37°C) for six hours. It clearly can be seen that we have to assemble a closed loop temperature controle. A closed loop control has three main elements - a sensor, an actuator and a controller. In our case:
- sensor = LM35
- actuator = heating resistance (60W, 127Vac)
- controller = Arduino Nano
By now, you must be asking where the heck does the servomotor fit in this project. Let's explain. The heating resistance can be used in two way - on/off mode or linear mode (using PWM, for example). I opted for the second mode and used a 600W light dimmer to implement a "linear" power variation. The potentiometer of the dimmer is coupled with the shaft of the servomotor, emulating a human hand's acting.
Putting it all together we have this flow:
- The LM35 measures the water temperature (10mV/°C).
- The Arduino make the A/D conversion, calculates the error (setpoint minus measured value), throws this value in the control algorithm which generates an output.
- The servomotor receives the output signal from the Arduino and turns the potentiometer, causing a change in the power output from the heating resistance.
- According to the variation of the power delivered by the heating resistance, the temperature increases or decreases.
This flow is performed several times per minute, making a closed loop control system.
Step 2: Mechanical Assembly
I chose to make batches of 1kg divided into 5 x 200g. So I used five pots of 250ml which could hold 200g of yogurt. Besides that, every batch has an additional pot (100ml) to produce 70g of yogurt that will be used as the starter for the next batch. Strictly speaking, each batch produces 1.070kg of yogurt (5x200g + 70g).
So our yogurt machine/reactor is made of five 250ml pots with lids, plus a 100ml pot with lid, all of which are placed inside a big bowl with the water bath. Inside the water we put the temperature sensor (LM35) connected to the Arduino, and the heating resistance connected to the dimmer. The Arduino also connects to the servomotor which is mechanically coupled with the dimmer. And there we have a closed loop.
Some points must be considered her. For example, if the bowl is to big, we'll have to heat too much water, wasting energy. It's diameter should be approximately three times the diameter of the pots (of course considering that my solution was implemented using five pots). Another important point is the heat distribution in the water. The ideal is to generate heat distributed in all the water volume so the temperature will be uniform in all points. I used a heating resistance along the border of the bowl because theoretically this is where occurs most of the heat exchange with the environment. The last point that I want to comment is the water level in the bowl. It should be the same level as the content of the pots. If you put to much water in the bowl, the pots will stay afloat.
Step 3: Electronics
The electronic part is quit simple. The LM35 outputs a voltage proportional to the temperature (10mV/°C). Our target is 370mV. This voltage is fed to analog input 0 of the Arduino. The Arduino calculates the value necessary to make the error equal to zero and sends this value to digital I/O 9, which feeds the servomotor. Since the dimmer is mechanically coupled to the servo, this means that the Arduino is controlling the dimmer.
*** CAUTION ***
The heating resistance is in contact with the water, which means that the water has an electric potential and may cause electric shock. Don't touch the water when the apparatus is energized.
Step 4: Software
The best way to control the temperature would be using a PID control loop. But, as I said before, this solution was implemented on a sunday morning and I wasn't on the mood to do the fine tuning of Kp, Ki and Kd. So I made a very (stupid) simple control loop. Besides controlling the temperature, do program also times itself and turns off the heating resistance after a predefined period (6 hours). The output can assume four different values depending on the error. The logic is:
- If (error > 2°C) then output = 175
- If (2°C > error > 0°C) then output = 160
- If (0°C > error > -2°C) then output = 130
- If (error < -2°C) then output = 100
You may be asking how I chose these values. The maximum value (175) was empirically determined so that the water bath will not exceed 50°C. The minimum value (100) causes the water bath temperature to stay around 25°C. Don't forget that the output corresponds to the servomotor angle.
Step 5: Final Words
This instructable should be seen more as a concept proof instead of a step-by-step construction guide. The solution that I presented is quite rudimentary, almost grotesque. Of course there are more efficient ways to vary the power on the heating resistance then using a stepmotor-dimmer solution. But that's the fun for a boring sunday morning.
Many improvements can be made on this solution. Maybe the simplest one would be to put a buzzer on a digital output to have an audible "yogurt done" signaling. More complex improvements could be an LCD interface or a Bluetooth or WiFi link.
The software solution lacks refinement and calls for a PID control loop, maybe with an auto-tuning algorithm.
Feel free to send me your questions, comments and yummie yogurt to everybody!