Smart Freezer – Part II

Collecting some data

In part I the temperature probe was configured to collect time-series data for the internal freezer temperature. The initial goal was to troubleshoot an elusive problem, and alert in case of over-temperature.

Here are some things which were learnt after the first 48h of data have been collected.

Normal operating ranges

The normal range of internal temperatures is colder than I intuitively expected. Of-course I knew that it had to be several degrees below zero degrees Celsius, but if I had to guess I’d say -5 to -10 would ok. Turns out that’s too hot for a freezer, it likes to stay below -15C (5F), with anywhere from -18C down to -25C being normal temperatures for my specific unit.

In the image below one can see the results of playing with different temperature setpoints in the front panel (markers 1, 2 and 3), as well as the quick temperature rise provoked by opening the door for a few instants (markers 4 and 5).

Also visible is the effect of the duty-cycle of the compressor, which stays on for a while (temperature drops) and then turns off for a while (temperature starts to rise). This is normal of models which don’t have an inverter compressor (one which can vary it’s speed to suit the instantaneous demands). On non-inverter models the temperature control mechanism on the unit (often just a simple thermostat) controls the amount of “cooling power” by changing the ration of the on cycle compared to the off cycle.

The head pump in action

A refrigerator is a form of heat pump: since it is not possible to create cold out of the blue (like you can with heat), the mechanism work by moving heat from the inside of the freezer into the environment outside. I had installed two sensors in this experiment, one inside the freezer, and the other outside, just above its metal body. Looking at the image below it is really easy to see the heat pump mechanism in action:

  • Every time the compressor turns on, the internal temperature starts to go down
  • Immediately, the external temperature starts to climb up
  • Once the compressor is turned off, the cycle reverts itself
  • Notice the range difference: for an excursion of approx 2C in internal temperature, the external temperature varies by just about 0.7C
    • This is easily explained by a combination of the much bigger volume outside, as well as the poor isolation of the room the freezer is in against its adjacent rooms

Duty-cycle in detail

The saw-tooth-like chats above show the effect of the on-and-off working cycle of the compressor. Zooming-in a bit it is possible to measure the time in each phase, as seen below:

Nenhuma descrição de foto disponível.

The image above shows in detail one particular moment. Changing the settings between “min” and “max”, the “ON” part of the cycle (compressor working, temperature going down) varied from anywhere between 20min to 50min (depends on how high the temperature was to begin with, how full/empty the freezer is, and if there are warm foodstuffs that still need to be frozen)

What did not vary perceptively though is the duration of the “OFF” phase: it was always around 21 minutes. This seems to suggest that this particular model (under normal circumstances) always shuts its compressor down for 21min, varying how long it keeps it ON in order to meet the demands of the moment.

Smart Freezer – Part I

The back story

The vertical freezer in our home has stopped working twice in the last six months (I’ll detail the probable cause in a separate post later). In both instances this was discovered before a catastrophic taw happened, but the safety margin was razor thin, and in any case, I decided to start watching it closely to troubleshoot and eventually call for repairs if needed. What I decided to do is to start monitoring its internal temperature (and eventually adding an alarm if it raised too much)

Smart temperature monitor

Since I run Home Assistant in the house, a natural fit is to use an ESP8266 board running an ESPHome-based firmware for data capture, and leave most of the smarts to Home Assistant. In the end I’ve decided to put together a device with the following basic features:

  1. Based on the NodeMCU development board (that’s my go-to ESP8266 dev board)
  2. With two Dallas temperature sensors (DS18B20), one for internal temperature, the other for room temperature (because why not?)
  3. With a piezo-electric buzzer, to sound an audible alarm in the device itself if needed, no external connection required
  4. With a status LED, for basic health info (in the initial version, using the on-board LED on the NodeMCU board)

First-versions need to demonstrate that the concept works, not necessarily be pretty or robust. This one is no exception: a breadboard-based mess of wires, glue and tape, but it works:

Image shows a breadboard with electronic components sitting atop a vertical freezer. From the breadboard a wire descends into the freezer itself.
First version of the temperature monitor
Close-up view of the breadboard, showing the NodeMCU board, some discrete components and the wire connections.
Close-up of the breadboard

In the close-up above it is possible to see that the NodeMCU variant used is the “V3” or “LoLin”, which occupies the whole width of the breadboard, hence the few jumper wires are connected from below the board, and not at its sides. The Vcc, Signal and GND connections for the two temperature probes are soldered to a 90-degree header pin and further held in place with hot glue. And finally, the buzzer itself is driven by a BC-547 NPN transistor so as to not overload the ESP GPIO, and has a flyback diode (1N4001) in parallel for protecting against induced voltage.

ESPHome firmware

The current version of the firmware is available on github here. It is fairly self-explanatory, the most important bits are below, with comments:

# Configure the Dallas DS18B20 temperature sensor platform on pin D7, GPIO13:
dallas:
  - pin: D7

# configure the two temperature sensors, with an alarm for the internal one:
# note: the addresses are device-specific, you need to query your own temperature
# probes to figure out their addresses and update your code accordingly
sensor:
  # inside temperature (sensor E - 0x28FFE382B11603B1)
  - platform: dallas
    id: freezer_internal_temperature
    address: 0xB10316B182E3FF28
    name: "Freezer Internal Temperature"
    on_value_range:
      - above: -10.0
        then:
          - script.execute: sound_alarm
  # outside (room) temperature (sensor C - 0x28FF1C8CB11605B0)
  - platform: dallas
    id: freezer_external_temperature
    address: 0xB00516B18C1CFF28
    name: "Freezer External Temperature"

  # NOTE: the sound_alarm action uses RTTTL to play a tune in the buzzer.
  # see the github link above for the details of how this is implemented

First results

Once connected to Home Assistant, instantly the current temperature is visible:

Home-assistant sensor info display reading "Freezer Internal Temperature -18.8 °C"

And with the sensor returning new samples every 60 seconds, HA starts logging the time-series data for you:

Home assistant sensor details with time-series chart

"17:46 Freezer Internal Temperature Freezer Internal Temperature 2 minutes ago -18.0"

Coming up next

Insights into the operation of the freezer and some cool notification automations in Home Assistant; also, a hypothesis on why the freezer stopped working twice in the last six months.

Experimenting while drying seeds

When you boil grain, beans for instance, it is common to let them soak on water overnight to hydrate and thus get soft quicker when cooking.  I regularly prepare a “snack” of roasted soy beans which goes through a similar process: soak overnight, cook on a pressure cooker, drain, then gently dry at a moderately high temperature.  I’ve decided to monitor the amount of water on each step, using the weight of the grain as a proxy, since I don’t have an easy way to estimate or measure water contents on grain.

The steps in the process

  1. The soy grains are weighted as they come out of the package, to get a baseline
  2. Grains are washed a couple times, then rinsed; weighted again to estimate how much water was left after rinsing
  3. Left to soak in water overnight (for about 14 hours)
  4. Cooked on a mechanical pressure cooker, for about 1h total, or about 45min under pressure
  5. Drained and left to air-dry for 10min
  6. Dried in an oven, over slow heat, for 24h

Results of weighting at each step

Step Weight (in grams)
Out of the bag 1020
Washed and drained 1130
Soaked 2290
Added salt 30
Added spices 7
Cooked and air dried 2430
Oven dried 788

 

Conclusion

The final product weights about 80% of what the original beans weighted out of the bag. Judging only by looks and feel to the touch, I’d expected less, perhaps 60%.  Also, soaking more than doubles the weight of the grain, and at that step my instinctive feel pointed to less, perhaps a 50-80% weight gain due to hydration.  Goes to show how interesting it is to measure those things.

Hailstone Sequence

Take a number; if it is even, divide it by two (N’ = N/2), if it is odd, multiply it by three and then add one (N’ = N*3 + 1).  Keep repeating these simple steps until you reach the result of N=1.  This simple sequence is often called a “hailstone sequence” because the intermediate results sometimes go up, sometimes down, sort of like the path a small piece of ice follows inside a cloud, until it grows too large and falls down as hail.

If you start with N=1, you’re already at the end, so no further operations allowed.  for N=2, you divide it by 2 and then you’re done, in one iteration. For number 3 it starts to get more interesting, as it takes a total of 7 iterations to complete the sequence:

3 ->  10 ->  5 ->  16 ->  8 ->  4 ->  2 ->  1

Number four is boring (4 -> 2 -> 1) and five is not much better (5 -> 16 -> 8 -> 4 -> 2 -> 1). We only get to do better than three above with six, which take one more iteration than three to complete:

6 -> 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1

Most numbers have fairly sort “runs”, while a few yield longer sequences.  If we investigate the length of the next biggest sequence for ever increasing values of N, we see something like this for the first one thousand integers:

1: 0
2: 1
3: 7
6: 8
7: 16
9: 19
18: 20
25: 23
27: 111
54: 112
73: 115
97: 118
129: 121
171: 124
231: 127
313: 130
327: 143
649: 144
703: 170
871: 178

It gets progressively harder to beat these scores. Does every sequence always eventually collapse to one? Supposedly, yes, and this is known as the Collatz conjecture, after German mathematician Lothar Collatz. The hard part has been to formally prove the conjecture to be true.  This problem is so infamous among mathematicians that I rather think the following xkcd is rather appropriate:

Collatz Conjecture

If you think about each number in the form of a node in a directed graph, then a particular node N for any number will have an outgoing edge towards N/2 (if N is even) or towards N*3+1 (if N is odd).  As for edges incoming towards N, there’s *always* an edge from node N*2 towards N – that is because for any integer N, N*2 is always an even number, and thus will have an edge directed towards N. There may be an additional incoming edge towards node N if the result of (N-1)/3 is an integer odd number – for instance, if N=16, (N-1)/3 is 5, and thus there is an edge 5 -> 16 (because the next iteration for 5 is “times 3 plus 1”, and 5*3+1 = 16.  This can be depicted as follows:

graph_1

Generalizing the above, we can see that for the space of the positive integers, we can construct a graph where in the form N->N’ and every node will have a single outgoing edge. Because sometimes a node will have two incoming edges, some sequences will “merge” and follow a single path from that point forward.  No sequence ever “splits” (that is, there is never more than one outgoing edge for each node), and so eventually all sequences merge in the final sequence 2->1

Plotting the graph for the first 1000 sequences, we can see some of the paths that emerge:

graph_2.png

If we adjust the layout to better isolate the sequences, things look prettier:

graph_3

Which can lead to some neat animations: (the image below is a rather large animated GIF, it may take a while to load and start “animating”)

graph_4

Finally, while I was composing this post, I left my simple hailstone calculator running in order to see what would be the largest sequence it would find. As of this point, the largest sequence found by the program has 956 iterations, and it starts with number 226,588,897.  The complete set of ever increasing “records” is the following:

1: 0
2: 1
3: 7 
6: 8 
7: 16 
9: 19 
18: 20 
25: 23 
27: 111 
54: 112 
73: 115 
97: 118 
129: 121 
171: 124 
231: 127 
313: 130 
327: 143 
649: 144 
703: 170 
871: 178 
1161: 181 
2223: 182 
2463: 208 
2919: 216 
3711: 237 
6171: 261 
10971: 267 
13255: 275 
17647: 278 
23529: 281 
26623: 307 
34239: 310 
35655: 323 
52527: 339 
77031: 350 
106239: 353 
142587: 374 
156159: 382 
216367: 385 
230631: 442 
410011: 448 
511935: 469 
626331: 508 
837799: 524 
1117065: 527 
1501353: 530 
1723519: 556 
2298025: 559 
3064033: 562 
3542887: 583 
3732423: 596 
5649499: 612 
6649279: 664 
8400511: 685 
11200681: 688 
14934241: 691 
15733191: 704 
31466382: 705 
36791535: 744 
63728127: 949 
127456254: 950 
169941673: 953 
226588897: 956