Even if we only milk one of our goats for the moment (and she is a low producer that give approximately half of her milk to a very hungry kid when they are together in the pasture), the milk bottles is filling up the fridge faster than we can consume it. We’ve already quit buying milk for drinking, coffee and cooking, so the next product to make ourselves will be yoghurt.
The process is rather simple, take some milk, pasteurize it if you don’t trust your hygiene, add bacterias and keep the temperature at the optimal level for as long as it takes for the bacterias to consume all accessible lactose and lower the pH to uncomfortable levels.
You can do this in your oven, but the temperature control will be crude, which results in runny and uneven yoghurt. There are yoghurt machines, not that expensive, that controls the temperature very well, but they don’t know when to turn themselves off, so you still have to watch it, or set the timer out of your best guesses.
Since my Diy wireless pH-sensor gives me the two variables I need to control the process (temperature and pH), I figured that I only needed a heat source. Then I found something even better at a second hand store; a portable 12V peltier cooler/heater from Waeco, made in the early 90’s, featuring such elegant solutions as switching between heat and cold by turning the electricity cord, thus switching polarity.
This makes the perfect completely automatic yoghurt maker, since it both keeps the heat at an even level, and when the right pH is achieved, cools the yoghurt down to fridge temperature. Just throw in some milk and culture in a jar (or a teapot) and leave.
The controller is very simple. Since the only functionality needed that the waeco box didn’t handle, was the ability to turn on and off and switch polarity remotely, I connected a L298b motor driver and a NRF24L radio to an Arduino nano. The L298b module is normally used to turn DC motors forward and backward, but that could be applied to the peltier element in the box to make it hot or cold as well. Unfortunately, the L298b was only capable of 4 amps in throughput, and the waeco transformer supplied more even though it was specified for 4, resulting in a very hot chip. The solution was to use 2 L298b in parallell. Power cables as well as signal cables to the arduino.
The chips were still hot, but with a cooling fan from a PC chassi, they are now cold and very cool. I connected the fan to the input side to let it consume some power and make it easier for the L298b. That means that the fan is always on, which might be unnecessary.
The Arduino code for the controller is also really simple. I used the mysensors.org sample code for relay and made two adjustments: increasing the numbers om relays to at least 3 (I actually enabled 6, as there might be need for using the second channel on the L298b in the future, but for this functionality, you only need 3) and enabling pwm on the pins that controls on/off. I haven’t used pwm for anything yet, but that will allow me to control the current from the L298b output (speed, heat etc.).
The logic is placed in the home automation system I have running on a Raspberry pi. It is currently Fhem, but any system with support for the Mysensors library will work. Fhem is a quite complex system with lot of forum material in german, but if you are comfortable with both German and Perl, there is no more powerful home automation system in my opinion.
The controller presents itself in Fhem when the gateway is in inclusion mode, and this is the fhem.cfg code that is generated (with som additions):
define MYSENSOR_10 MYSENSORS_DEVICE 10
attr MYSENSOR_10 IODev gateway
attr MYSENSOR_10 alias Youghurt maker
attr MYSENSOR_10 mapReading_switch1 1 switch
attr MYSENSOR_10 mapReading_switch2 2 switch
attr MYSENSOR_10 mapReading_switch3 3 switch
attr MYSENSOR_10 mapReading_switch4 4 switch
attr MYSENSOR_10 mapReading_switch5 5 switch
attr MYSENSOR_10 mapReading_switch6 6 switch
attr MYSENSOR_10 mode repeater
attr MYSENSOR_10 room Dashboard,Mysensors
attr MYSENSOR_10 setReading_switch1 on,off
attr MYSENSOR_10 setReading_switch2 on,off
attr MYSENSOR_10 setReading_switch3 on,off
attr MYSENSOR_10 setReading_switch4 on,off
attr MYSENSOR_10 setReading_switch5 on,off
attr MYSENSOR_10 setReading_switch6 on,off
attr MYSENSOR_10 version 2.0.0
We can se that all 6 relays shows up, but I have only found use for three.
The logic doesn’t show up by itself so here I had to do som actual brainwork.
I found some excellent thruth tables here and got the following pin/switch setup:
Switch1/ENA: Main power 1=on, 0=off
Switch2=IN1
Switch3=IN2
Positive direction / heat: switch1 = 1, switch2 = 1, switch3 = 0
Negative direction / cold: switch1 = 1, switch2 = 0, switch3 = 1
Power off: switch1 = 0
The yogurt culture I am using prefers a temperature of 43 C and I will let it work until it has reached a pH of 4.20. I’ve hardcoded those levels in my config file for now, but an improvement will be to create a device that changes these values.
I want the machine to:
- Rise and hold the temperature on 43 C.
- Do that until pH has dropped to 4.20
- Then cool it down as much as possible
That is achieved with the following code in fhem.cfg:
define phNotify notify MYSENSOR_118:temperature.* {if (ReadingsVal("MYSENSOR_118", "temperature", 0) > 43 ) { fhem("set MYSENSOR_10 switch1 off") } elsif(ReadingsVal("MYSENSOR_118", "temperature1", 0) > 4.25) {fhem("set MYSENSOR_10 switch1 on;; set MYSENSOR_10 switch2 on;; set MYSENSOR_10 switch3 off")} elsif(ReadingsVal("MYSENSOR_118", "temperature1", 0) < 4.25) {fhem("set MYSENSOR_10 switch1 on;; set MYSENSOR_10 switch2 off;; set MYSENSOR_10 switch3 on")}}
Worth mentioning is that the pH-sensor is called MYSENSOR_118 and its temperature sensor reports as temperature, while its pH-sensor reports as temperature1.
So this is the result. The red line is temperature, starting at fridge temperature at 6C and rising steadily to 43C where it plans out. Meanwhile the green bars representing the pH goes from 6.5 to 4.4 (at the time of the screenshot).
Obviously, the Waeco box isn’t made for heating, rather than keeping a temperature. The slow rise of about 8-9 degrees/hour making it 5 hour until optimal temperature is reached, is not acceptable. Heating the milk before putting it in the box is one easy solution, another is to never cool it down and let it go directly from the udder to the box.