# Code for calculating final temperature of ice added to water

Hi.

I have constructed a water meter for a bakery. It uses a flow meter, solenoid and ds18b20 to dose water for mixing bread dough in a bakery environment.

Basically one punches in a volume of water into a keypad and then a solenoid opens dumping water into a mixer. The water is measured with the flow meter and interrupted when total volume measured = target volume.

All the while the temperature is monitored and averaged.

My problem is when I need to use colder water than is available via mains water supply. I would like to add a function to calculate the amount of ice to add to bring to a specific temperature.

Example: dumped 30L at 25C. how much ice in grams would I need to add to that water to bring temp down to 20C?

The information I would have is V=volume of water, OT= Starting Temperature and TT = Target Temp.
I want to find out how to use the Arduino to give me the volume of ice in grams I need to add to reach TT from OT.

If anyone is interested in having a crack at It I would be very thankful.

I’ll also attach my code, knowing its not beautiful .

watermeter_working.ino (5.22 KB)

Hunt down a formula for this and then if you need help converting it to code I'm sure someone here can assist.

Not trivial

The physics
There are three temperature coefficients you need to know to calculate the amount of energy needed to melt ice from ice to water.

• assume ice has temperature of -Y °C
• assume water has temperature of P °C (ist temperature)
• assume X °C is the temperature you want to have (soll temperature)

then the steps are

1. getting the ice from -Y°C to 0°C- => 2.108 J/gram (search for specific heat ice)
2. getting ice from 0°C to water 0°C => 334 J/gram (this one is often forgotten)
3. getting water from 0°C to X°C => 4.187 J/gram

In total to get 1 gram of ice from -Y to X costs Q1 = 2.108Y + 334 + 4.187X energy

This amount of energy should balance
4) getting water from P °C to X °C => 4.187 J/gram

In total to get 1 gram of water from P to X costs Q2 = (P - X) * 4.187 energy

Example

30Liter @25° --> 30L @ 20° ==> Q2 = 30000 gram * (25-20) * 4.187 = 628050 joule

Assume you have ice from -18°C then it would take

Q1 = 2.10818 + 334 + 4.18720 = 454.064 Joule per gram to heat to 20°C

The amount of ice would be 628050 / 454.064 = 1383.17 gram of ice of -18°C to end up at 20°C
in practice 1.4 Kg should work (depends on precission of parameters of course).

The code
Assuming my above physics is right we can derive the formula needs

1. amount of water in Kg (30.000)
2. IST temperature of the water in C (25.0)
3. SOLL temperature of the water in C (20.0)
4. temperature of the ice in C (-18.0)
``````float calculateIce(float water, float ist, float soll, float icetemp)
{
float Q2 = 1000 * water * (ist - soll) * 4.187;
float Q1pergram = -2.108 * icetemp + 334 + 4.187 * soll;   // note the - sign
float gramsIce = Q2 / Q1pergram;
float kgIce = gramsIce * 0.001;

return KgIce;
}
``````

You can modify the code to round the number to 100 grams or have the weight in grams etc

This formula does not take into account the environment temperature, which has effects too.
Furthermore the specific heat of water depends on the temperature but above formula should work well enough in practice. If not you need to extend the formula in a similar way.

Please do a number of testruns and let us know if it works.

Note: ° char == ALT 0176 on windows

updated the value for latent heat (ice2water) as Harlane spotted an error (see below)

robtillaart:
2) getting ice from 0°C to water 0°C => 0.334 J/gram (this one is often forgotten)

334 not .334

I always remember the latent heat as 80 from the old days of calories, when the specific heat of water was 1, so in any units it must be 80x that of water.

So 4.2 x 80 ~ 330 not 0.33

OK thanks for spotting the error, I'll update the post and the code asap (done)

Jeremy_nz:
I would like to add a function to calculate the amount of ice to add to bring to a specific temperature.

What you say implies handling actual ice, therefore it may be simpler not to worry about the ice, but work on water flowing from it in the same manner as you are already doing, and using the method of mixtures.

A possibly better option is to have a heat exchanger using recirculated iced water with a temperature controlled circulation pump. No actual ice needed, just a water cooler.

Real bakeries would use crushed ice that melts immediately when added to the dough.

Paul

If you’re just dumping ice in do you need to allow for the fact that to end up with 30l of water you need to start with a bit less because the melted ice will add some volume?

Steve

slipstick:
If you're just dumping ice in do you need to allow for the fact that to end up with 30l of water you need to start with a bit less because the melted ice will add some volume?

Steve

Good observation
just poor same amount away AFTER temperature stabilization.

If you want to do end on 30L exactly the equation becomes more complex.
far easier is to do a binary search. you will get a sequence like

30L + calculated amount ICE = too much
15L + ca ICE = too little
22L + ca ICE = too little
26L + ca ICE = too little
28L + ca ICE = too much
27L + ca ICE = ...

The ice will add non-negligible extra volume of water, you need to measure the temperature before completely
filling the vessel, then calculate the ice proportion, then add the ice and the right amount of water to complete
the volume.

If the ice is colder than 0C you might need to take that into account too as it has a non-zero heat capacity.

Wrote a small sketch to calculate the amount of water and ice needed directly,

``````//    FILE: calculateIce.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: demo

void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);

float endAmount = 30;     // liter
float waterTemp = 24.5;   // Celsius
float endTemp = 20.0;     // Celsius
float iceTemp = -18.7;    // Celsius

float iceNeeded = calculateIce(endAmount, waterTemp, endTemp, iceTemp);
float waterNeeded = endAmount - iceNeeded;

Serial.println();
Serial.print("ENDAMOUNT:\t");
Serial.println(endAmount, 1);
Serial.print("WATERTEMP:\t");
Serial.println(waterTemp, 1);
Serial.print("ENDTEMP:\t");
Serial.println(endTemp, 1);
Serial.print("ICETEMP:\t");
Serial.println(iceTemp, 1);

Serial.println();
Serial.print("WATERNEEDED:\t");
Serial.println(waterNeeded, 1);
Serial.print("ICENEEDED:\t");
Serial.println(iceNeeded, 1);
Serial.print("TOTAL:\t\t");
Serial.println(iceNeeded + waterNeeded, 1);

Serial.println();
Serial.print("check: ");
Serial.println(calculateIce2(waterNeeded, waterTemp, endTemp, iceTemp), 1);

}

void loop() {}

float calculateIce(float endAmount, float ist, float soll, float icetemp)
{
// calc 1 liter water
float Q2 = 1000 * (ist - soll) * 4.187;
float Q1pergram = -2.108 * icetemp + 334 + 4.187 * soll;   // note the - sign
float gramsIce = Q2 / Q1pergram;
float kgIce = gramsIce * 0.001;
// so 1 liter water needs kgIce to get to right endTemp

float endTotal = kgIce + 1;
float factor = endAmount / endTotal;  // how often does this fir in endAMount

return kgIce * factor;
}

float calculateIce2(float startAmount, float ist, float soll, float icetemp)
{
float Q2 = 1000 * startAmount * (ist - soll) * 4.187;
float Q1pergram = -2.108 * icetemp + 334 + 4.187 * soll;   // note the - sign
float gramsIce = Q2 / Q1pergram;
float kgIce = gramsIce * 0.001;

// so we will end up with startAmount + KgIce
return kgIce;
}
``````

output

``````ENDAMOUNT:    30.0
WATERTEMP:    24.5
ENDTEMP:      20.0
ICETEMP:      -18.7

WATERNEEDED:  28.8
ICENEEDED:    1.2
TOTAL:        30.0

check: 1.2
``````

@robtillaart Thanks so much for your time working on my problem. It means a lot to me.

I think I can implement the code from your latest comment to calculate the ice needed on the fly while dumping the water, so the amount of water added + ice needed = amount input by user.

I'll try this out over the next few days and post the results.

Thanks to everyone that replied to this thread.