Skip to content

Commit eb4b58b

Browse files
committed
0.1.1 WaterMix
1 parent 156c4cc commit eb4b58b

File tree

7 files changed

+288
-54
lines changed

7 files changed

+288
-54
lines changed

libraries/WaterMix/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88

9+
## [0.1.1] - 2023-08-30
10+
- add **void addExact(float volume, float temperature)** (works only for water).
11+
- add **float mass()** (works only for water).
12+
- add **float volume2mass(float volume, float temperature)** (works only for water).
13+
- add **float mass2volume(float mass, float temperature)** (works only for water).
14+
- update readme.md
15+
- fix keywords.txt
16+
- minor edits
17+
18+
919
## [0.1.0] - 2023-08-29
1020
- initial version
1121

libraries/WaterMix/README.md

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,46 @@ Arduino library for mixing water with different temperatures.
2020

2121
Experimental library for elementary math of mixing water with different temperatures.
2222

23-
The library does some indicative math of mixing a volume of water with temperature T1
23+
The library provides math for mixing a volume of water with temperature T1
2424
with a another volume with temperature temperature T2.
25-
In fact the library will work for any single liquid (TODO: liquidMix class).
25+
In fact the library will work for any single liquid (TODO: liquidMix class),
26+
although some functions are **water specific**.
27+
28+
This library is useful e.g. by doing "water math" for aquaria or cooking.
29+
Also the library is well suited for basic educational purposes.
30+
31+
32+
#### Limitations
2633

2734
The library uses a generic volume parameter instead of gallons or liters as
2835
this way any user selected unit can be used.
29-
However you must use the chosen units consistently as you cannot use different
30-
units simultaneously.
36+
However you must use the chosen units consistently as the library cannot handle
37+
different units simultaneously.
3138

32-
To use different units for volume you can get some help of the volume conversion
33-
library named **VolumeConverter** to convert the units.
39+
To use different units for volume you can convert them with the library named
40+
**VolumeConverter**.
3441

3542
The temperature unit can also be chosen by the user and can be Kelvin, Celsius,
3643
Fahrenheit or other.
37-
However you must use the chosen units consistently as you cannot use different
38-
units simultaneously. Check **Temperature** library below.
39-
40-
This library could be useful e.g. by doing "water math" for aquaria or cooking.
41-
Also the library is well suited for basic educational purposes.
44+
However you must use the chosen units consistently as the library cannot handle
45+
different units simultaneously. Check **Temperature** library below for conversion.
4246

4347

4448
#### Accuracy
4549

4650
The working range for temperature is not tested with real water.
47-
It is expected to work (roughly) for water with a range from 5°C to 80°C.
48-
In the (0.1.0) math it is assumed there is no expansion so the mass / volume is
49-
identical for "both volumes of waters".
51+
It is expected to work quite well for water with a range from 5°C to 80°C.
52+
In the basic math the **add()** function assumes there is no expansion so
53+
the density is identical for "both volumes of waters".
5054

51-
Of course this is incorrect, therefore it is expected to have a difference
55+
Of course this is incorrect, therefore it is expected to have a difference
5256
between the theoretical values and doing the mixing in practice.
5357
However the delta's are expected to be small, less than 1% in many cases.
5458
Given the accuracy of volume measurement and temperature measurement,
5559
this delta is often acceptable.
5660

57-
TODO:
58-
- investigate in the effect of the volume expansion and contraction of
59-
the water due to the temperature delta, and how to handle it.
61+
If one wants a more exact answer, one should use the **addExact()** function
62+
as this compensates for the density of the water at a given temperature.
6063

6164

6265
#### Related
@@ -75,29 +78,71 @@ TODO:
7578
#### Constructor
7679

7780
- **WaterMix()** constructor, starts with no water of 0°
78-
- **void begin()** resets to no water of 0°.
81+
- **void begin(float volume = 0, float temperature = 0)**
82+
sets initial values, default no water of 0°.
83+
84+
#### Math
85+
7986
- **void add(float volume, float temperature)** add an amount of water
8087
with temperature to the "WaterMix".
88+
- **void addExact(float volume, float temperature)** Water only!
89+
add an amount of water with temperature to the "WaterMix".
90+
The math is calculated including using the density of the water.
91+
This is slower as **add()** but more exact.
92+
Note the temperature must be in °C.
8193
- **void sub(float volume)** subtract a volume from the "WaterMix".
8294
Temperature won't change.
8395
- **void div(float nr)** divide the amount of liquid, same temperature.
8496
- **void mul(float nr)** multiply the amount of liquid, same temperature.
97+
98+
#### Getters
99+
85100
- **float volume()** get the current volume.
86101
- **float temperature()** get the current temperature.
102+
- **float mass()** get the mass of the current volume. Water only!
103+
104+
#### Converters
105+
106+
- **float volume2mass(float volume, float temperature)** idem, Water only!
107+
Use volume == 1 to get the density at a certain temperature.
108+
- **float mass2volume(float mass, float temperature)** idem, Water only!
109+
110+
111+
## Performance
112+
113+
Most functions are just fast, the only that do the core math are add()
114+
and addExact().
115+
The WaterMix_exact.ino sketch provides some performance figures shown
116+
here.
117+
Note that the **addExact()** differs in runtime as it uses a linear lookup
118+
for the density so the numbers below are indicative.
119+
120+
| Function | time (us) | Notes |
121+
|:------------:|:-----------:|:--------|
122+
| add() | 72 |
123+
| addExact() | 576 | most accurate |
124+
125+
Note it is possible to tune the linear lookup of the density by reducing
126+
the amount of interpolation points in the tables (at your own risk).
127+
This will reduce the accuracy however still be better than the fast **add()**.
128+
129+
Performance of **addExact()** can be improved by caching the mass of the water.
130+
To be investigated.
87131

88132

89133
## Volumetric Coefficient of Expansion
90134

91135
The VCE is not supported in the library.
136+
(0.1.1 supports an **addExact()** for water only, temperature in °C)
92137

93-
It is useful as background information as the theoretical volumes calculated in this
94-
library will differ from reality due to the VCE effect.
95-
This difference depends on the liquid used and the delta temperature.
138+
The VCE is useful as background information as the theoretical volumes calculated
139+
in this library will differ from reality due to the VCE effect.
140+
This difference depends on the liquid used and the delta temperature.
96141

97142

98143
#### Water
99144

100-
The VCE of water depends on the temperature, doing the math needs to be investigated.
145+
The VCE of water depends on the temperature.
101146

102147
Source: - https://www.engineeringtoolbox.com/water-density-specific-weight-d_595.html
103148

@@ -158,45 +203,47 @@ Source: - https://www.engineeringtoolbox.com/cubical-expansion-coefficients-d_12
158203
#### Must
159204

160205
- update documentation
206+
- library can be used for water and salinity and other linear related things.
207+
- investigate linear expansion
208+
- VCE as parameter.
161209

162210

163211
#### Should
164212

165213
- create base class **LiquidMix** and derive a specific **WaterMix** from it.
166-
- code is quite identical
167-
- **WaterMix** can include specific heat, VCE etc.
168-
- include expansion of water VCE effect due to heat.
169-
- 4°C is smallest for water.
170-
- must use defined liquid and temp scale.
171-
- or add an expansion function?
172-
- needs investigation
214+
- code is quite identical, easy to split/strip water specific functions
215+
- **WaterMix** can include specific heat, density, VCE etc.
216+
- 0.2.0
217+
- **WaterMixF()** Fahrenheit, as derived class too.
218+
- **WaterMixK()** Kelvin?
219+
- do not make the library too complex (see could below).
220+
- extend unit tests
221+
- investigate the caching of the mass of the water.
222+
- add Exact only, 4 bytes..
173223

174224

175225
#### Could
176226

177-
- performance measurements
178227
- cool(time) == depends on many factors
179228
- need to configure curve constant (only option).
180229
- must use defined liquid and temp scale.
181-
- energy functions to calculate how hot an amount of water
182-
should be to reach a certain temperature.
183-
- Think Aquaria or cooking.
184-
- add "unit string" + Printable interface?
185-
- -idem Temp scale?
186-
- extend unit tests
187-
- rename to **LiquidMix** class
188-
- WaterMixCelsius as derived class?
189-
- WaterMixFahrenheit as derived class? etc.
190230
- catch temperature below zero?
191231
- must use defined liquid and temp scale.
192-
- library can be used for water and salinity too
193-
- other linear related things.
232+
- user responsibility for now.
194233
- **void AddEnergy(float joule)** to raise temperature (joule)
195234
- must use defined liquid and temp scale.
196-
- specific heat needed.
197-
198-
199-
#### Wont
235+
- specific heat needed. (Water only?)
236+
- replace div and mul with operators \* and \/
237+
- use double iso float?
238+
239+
240+
#### Wont (or on special request)
241+
242+
- add "unit string" + Printable interface?
243+
-idem Temp scale?
244+
- energy functions to calculate how hot an amount of water
245+
should be to reach a certain temperature.
246+
- Think Aquaria or cooking.
200247

201248

202249
## Support

libraries/WaterMix/WaterMix.h

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
// FILE: WaterMix.h
44
// AUTHOR: Rob Tillaart
55
// PURPOSE: Arduino library for mixing water with different temperatures.
6-
// VERSION: 0.1.0
6+
// VERSION: 0.1.1
77
// URL: https://github.com/RobTillaart/WaterMix
88

99

1010
#include "Arduino.h"
1111

1212

13-
#define WATERMIX_LIB_VERSION (F("0.1.0"))
13+
#define WATERMIX_LIB_VERSION (F("0.1.1"))
1414

1515

1616
class WaterMix
@@ -23,10 +23,10 @@ class WaterMix
2323
}
2424

2525

26-
void begin()
26+
void begin(float volume = 0, float temperature = 0)
2727
{
28-
_volume = 0;
29-
_temperature = 0;
28+
_volume = volume;
29+
_temperature = temperature;
3030
}
3131

3232

@@ -39,12 +39,30 @@ class WaterMix
3939
}
4040

4141

42+
void addExact(float volume, float temperature)
43+
{
44+
if (volume <= 0) return; // false
45+
float mass0 = _volume * _density(_temperature);
46+
float mass1 = volume * _density(temperature);
47+
float totalMass = mass0 + mass1;
48+
49+
_temperature = (mass0 * _temperature + mass1 * temperature) / totalMass;
50+
_volume = totalMass / _density(_temperature);
51+
}
52+
53+
4254
void add(WaterMix &wm)
4355
{
4456
add(wm.volume(), wm.temperature());
4557
}
4658

4759

60+
void addExact(WaterMix &wm)
61+
{
62+
addExact(wm.volume(), wm.temperature());
63+
}
64+
65+
4866
void sub(float volume)
4967
{
5068
_volume -= volume;
@@ -67,7 +85,7 @@ class WaterMix
6785
}
6886

6987

70-
float volume()
88+
float volume()
7189
{
7290
return _volume;
7391
}
@@ -79,9 +97,60 @@ class WaterMix
7997
}
8098

8199

100+
float mass()
101+
{
102+
return _volume * _density(_temperature);
103+
}
104+
105+
106+
float volume2mass(float volume, float temperature)
107+
{
108+
return volume * _density(temperature);
109+
}
110+
111+
112+
float mass2volume(float mass, float temperature)
113+
{
114+
return mass / _density(temperature);
115+
}
116+
117+
82118
private:
83119
float _volume;
84120
float _temperature;
121+
122+
123+
// _density is in fact multiMap code
124+
float _density(float temperature)
125+
{
126+
// strip table size?
127+
uint8_t size = 22;
128+
uint8_t _in[] = { 0, 1, 4, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100};
129+
float _out[] = {
130+
0.9998495, 0.9999017, 0.9999749, 0.9997000, 0.9991026,
131+
0.9982067, 0.9970470, 0.9956488, 0.9940326, 0.9922152,
132+
0.9902100, 0.9880400, 0.9856900, 0.9832000, 0.9805500,
133+
0.9777600, 0.9748400, 0.9717900, 0.9686100, 0.9653100,
134+
0.9618900, 0.9583500
135+
};
136+
137+
138+
// take care the temperature is within range
139+
// temperature = constrain(temperature, _in[0], _in[size-1]);
140+
if (temperature <= _in[0]) return _out[0];
141+
if (temperature >= _in[size-1]) return _out[size-1];
142+
143+
// search right interval
144+
uint8_t pos = 1; // _in[0] already tested
145+
while(temperature > _in[pos]) pos++;
146+
147+
// this will handle all exact "points" in the _in array
148+
if (temperature == _in[pos]) return _out[pos];
149+
150+
// interpolate in the right segment for the rest
151+
uint8_t pos1 = pos - 1;
152+
return (temperature - _in[pos1]) * (_out[pos] - _out[pos1]) / (_in[pos] - _in[pos1]) + _out[pos1];
153+
}
85154
};
86155

87156

0 commit comments

Comments
 (0)