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:


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:


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


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”)


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

Using ESPHome to program ESP8266 and ESP32 boards

ESPHome (https://esphome.io/) is a fantastic project for writing code for Epressif’s ESP8266 and ESP32 system-on-a-chip boards.  It is not a general-purpose tool, since it targets those two platforms, and the firmware you create with it, while can have some general application, is geared towards connecting your ESP device with the Home Assistant home automation platform (https://www.home-assistant.io/)

For a more general-use tool (but without the connection to Home Assistant), look for Platform.IO (http://platform.io/). Since my goal is connecting devices to Home Assistant, I’ll focus on ESPHome on this series of short posts.


Installing ESPHome

There are two official ways to get ESPHome installed. If you’re running Home Assistant via the hass.io RaspberryPI installer, then it may be more convenient to install ESPHome as an add-on. In that case, follow this guide: getting_started_hassio

My personal preference is to run EPSHome as tool on my main development computer, and not on HA, and as a result the steps below follow this other guide: getting_started_command_line


  • Python: ESPHome (and platform.io) is built on top of python; as of version 1.14.0 (current release), ESPHome supports both python 2.x and 3.x, but support for 2.x will be dropped soon, so go ahead and install Python 3.x (3.8.0 is current)
  • Pip: you also need to have python’s package manager, pip;


$ pip install esphome

That’s all there is to it; after all dependencies have been fetched, you should be all set.

Testing the install and creating a simple device config file

To ensure that the installation succeeded, check the version of the tool:

$ esphome . version
Version: 1.14.0

ESPHome creates the firmware for your devices using configuration files in YAML format which describe the device, what peripherals are connected and what functionality we want to enable.  To create a very simple first config file we can use the wizard feature:

$ esphome my_first_device.yaml wizard

The wizard will ask a few questions; for this experiment, respond as follow:

  1. Step 1 : name
    Answer: my_first_device
  2. Step 2 : ESP device
    Answer:  ESP8266
  3. Step 2: Board
    Answer: NodeMCUv2
  4. Step 3: Wifi ssid
    Answer: the name of your WiFi network (case-sensitive, watch-out!)
  5. Step 3: Wifi ssid
    Answer: the password to your WiFi network
  6. Step 4: OTA
    Answer: a password for over-the-air (OTA) firmware updates

If all goes well, a named my_first_device.yaml should’ve been created, with contents similar to the following:

  name: my_first_device
  platform: ESP8266
  board: nodemcuv2

  ssid: "dummy"
  password: "dummy"

# Enable logging

# Enable Home Assistant API
  password: "dummy"

  password: "dummy"

Don’t worry if the file looks slightly different; some options vary on different versions.

Next steps

Future posts will cover some other topics, including:

  • How to validate and build this configuration
  • Uploading the resulting firmware to an actual device via a serial connection
  • Over-the-air updates
  • Removing secrets (such as the WiFi password) from the config file
  • Adding sensors and other capabilities

Consumer devices getting better security

My ISP just replaced the optical fiber modem and wireless router devices they provided with a model+router combo from Huawei.  Besides being a very good device with (slightly) better WiFi range than the TP-Link it replaced, I’ve noticed that this product (Huawei EchoLife HS8546) has built-in protection against password brute-force attacks:

2019-08 Huawei bot protection.png

Nice to see; this is probably going to become standard across the board soon, but right now this is the first I’ve seen this (not that I’m on the market for WiFi routers frequently, but still…)

Home irrigation system for potted plants

Summer in my neck of the woods (29S, 54W, a mere 50m above sea level) is brutal; temperatures can reach above 30ºC during the day, and stay above 20ºC at night. Under these conditions, potted plants such as shubs, herbs and ivies need to be watered every day to stay healthy. That is a chore, and more complicated if one goes away for a few days. What’s a geek to do? Why, build an IoT irrigation system!

Sourcing the parts

The system is comprised of a kit of tubing, drippers, support stakes and T connectors. To drive the water a small pump was selected, and finally a WiFi relay will allow some degree of smart control.  Here are the parts:

Irrigation kit

Link SKU 32868257464
Price $13.31
Variant 25m Kit / 30pcs


With this kit, you route the black tubing around the area you want to irrigate, and then at each target you cut the hose, insert a “T” and derive a short run of hose ending on a dripper, supported by a stem. The drippers can have their flow adjusted by twisting the cap.

Water pump

The selected pump is a small submersible DC brushless pump, of the type that is commonly used in arts and crafts to make little fountain ornaments.

Link SKU 32792939616
Price $3.46


This pump runs on 12V DC, and to power it I used a DC adapter I had lying around, for which I have no link or reference. Given the small wattage of the pump, almost any 12V power adapter will do.

WiFi Relay

The last piece of the puzzle is to add something to turn the pump on and off periodically; a simple programmable would work, but a WiFi relay is more versatile, and can later be integrated in my home automation hub.


Link SKU 32827328525
Price $4.97
Controlling app eWeLink – Smart Home Control

This is a SONOFF device from Itead (see https://www.itead.cc/). They have a variety of different IoT modules with interesting applications. This Sonoff relay (and most of their devices) is based around the valiant ESP8266 and the fact that it adds its own mains power supply, a relay, connectors and a very neat enclosure, make it a very interesting device to work with.


The app used to program and control the relay (eWeLink) is not bad at all, but in order to have more flexibility in connecting it to my own home-automation hub, I’m probably going to re-flash it with an alternative firmware.  There are a few options for these Sonoff devices, but the most mature and feature-complete one seems to be the Espurna firmware (https://github.com/xoseperez/espurna). More on that on another post.

Measuring the flow rate of the water pump

The water pump is rated for 240 liters of water per our of operation, or 4 liters per minute if you do the math. I wanted to test this out, and it turned out close: on my tests, I’ve got 3.5 liters per minute, or 210 liters per hour. More than enough for my application, although this was measured with a short tube on the output, the actual flow will probably be less, when coupled with the long hose and several drippers.

Putting it all together

Not much to say about that, you just connect the pump to the power adapter, that into the WiFi relay and the relay to mains. For water supply I used a 20l water jug, on which I added a small output valve near the bottom line.

Here are a few pictures of the setup on its “inaugural run”, on 2018-12-16:

Photo 2018-12-16, 18 16 01The pieces all connected together, except for the water hoses.

Photo 2018-12-16, 19 16 58
On the wall, with hoses connected, and with the 20l “tank”, ready for first tests.

Photo 2018-12-16, 19 09 45The main water line running horizontally throughout the balcony, and a “T” derivation feeding a dripper for a potted plant.

Photo 2018-12-16, 19 13 50
Water coming out of a dripper. This one is almost closed, for a small flow. On a larger pot, with the dripper wide open, you get more of a “shower” pattern – depending on water pressure.


LEDs as sensors: putting it to test

There was a workshop at SIGGRAPH 2018 titled LEDs as Sensors, and I was tipped to it via the hackaday post from 2018-08-21, “A LED you can blow out” (with no added sensor it said, which is technically true if you stick to the meaning of “added” in the title).

Basically, the gist of it is to just feed an LED some DC current and watch its forward voltage drop: it varies with temperature, so if after you let it warm up a bit you blow quickly on it, you should notice a sudden change in voltage. Connect that to an analog input on your micro-controller of choice, do some averaging to smooth-out noise, and that sudden change can be used as a trigger to “blow out” the LED.

Note that for any quick voltage change to be observed, there must be minimal thermal inertia around the LED junction.  This means that “normal” LEDs with big plastic casings don’t work for this purpose. The article suggests a tiny pre-wired SMD LED.  Since I wanted to test this out without ordering (and waiting) an LED, I’ve decided to search around the junk drawer; the best candidate I could find was a scrap of LED light strip which had exposed SMD LEDs soldered to the tape and an SMD resistor thrown in for every 3 LEDs. That’s what I tested with, and I’m happy to report that it (sort of) worked.

Some references and links to more info / materials


Figuring out the wiring on an LED strip segment

First things first, I needed to figure out how the LED light strip I had lying around is wired-up. This is not always easy to see by just looking at, as paint makes the conductive tracks barely discernible and a bit hard to identify:

Segment 1

However, shining a strong light underneath the strip did the trick of exposing the copper traces, and the wiring becomes evident:

Segment 2.jpg

It turns out that each segment is wired with three LEDs and one 150-ohm resistor in series, and each of the strip segments is connected in parallel to all others.

Isolating on LED and measuring it out

I’ve decided to use one of the LEDs on the strip segment and the series resistor for this test. This would require me to just solder the three leads – ground, VCC from a digital output and the voltage sensing for the ADC.  Here’s my beautiful sketch of a plan:

WhatsApp Image 2018-08-23 at 15.03.22.jpeg

Determining the LED voltage drop and dimensioning the series resistor

With the leads soldered, I’ve measured the forward voltage drop in the resistor, 2.6v.

A meter reading 2.63v as the forward drop on an LED, shown lit above the meter

Since the series resistor on the strip is 150-ohm, a quick calculation shows that if powered from 5v, the current I=V/R over the LED would be:  (5v – 2.6v) / 150R = 16mA.  This is ok from the standpoint of running this from a digital output pin on an Arduino, but a bit more than the 12mA in the original circuit;  I’ve figured it would work.

And it did!  I do need to blow hard and quick in order to trigger the action in the software (and I had to tweak the parameters in the code a bit, but in the end I did manage to consistently turn off this LED with a quick hard blow.




Mining catcoins – an energy view

Some friends put together an initiative for a cat rescue NGO: catcoins. The premisse is simple: you visit the site, agree to donate CPU time to the cause of helping stray cats, and the site will use your browser to mine a cryptocurrency for the NGO, while showing pictures of cats up for adoption, in the hopes of finding ’em a new home.

The idea is great, as it capitalizes on the current boom in cryptocurrencies, and brings visibility to the NGO, even if the actual monetary value from the mining activity is not that great.  From my part, I wanted to use this as an experiment to get an idea about the cost involved in the mining of this currency.

The experimental setup

I’ve used two rigs for testing this: a Raspberry Pi 3 (Quad Core 1.2GHz Broadcom BCM2837 64bit CPU) and an HP ZBook 15 laptop (Intel i7-4810MQ Quad Core 2.80 GHz). Both systems ran the mining in the Chrome browser – experimentally Firefox ran about 10-20% faster than Chrome, but the numbers below were all captured running on Chrome.

The results with the Raspberry Pi

Power usage idling:    2.4W
Power usage mining:    5.5W

Results from 10min mining:
- Calculations:        2796
- Performance:         4.66 calc/s
- Amount R$:           1.1486654161781946072684642438453e-4

If this setup ran continuously for 1 year (approx):
- Calculations:        146957760
- Amount accrued:      R$  6.04
- Electricity cost:    R$ 22.64

The results with the Intel-based laptop

Power usage idling:    88W (laptop, monitor, router)
Power usage mining:    135W (mining adds roughly 47W)

Results from 10min mining:
- Calculations:        25590
- Performance:         42.65 calc/s
- Amount R$:           0.0010513

If this setup ran continuously for 1 year (approx):
- Calculations:        1345010400
- Amount accrued:      R$  55.26
- Electricity cost:    R$ 555.82
- Electricity cost:    R$ 192.68 (just the added cost of mining)


  • Using the javascript interpreter on the browser to mine cryptocurrency is not cost effective, you spend more on electricity than you accrue in coin; and that is not factoring the cost of the equipment.
  • In fact, with the cost of electricity for consumers in Brazil, the cost ratio is almost 4:1
  • In terms of the amount of coin per KWh of electricity, the Raspberry Pi may be more efficient than the laptop; this is not possible to attest with certainty from this measurements as the Pi was running barebones and headless, and the notebook had two monitors, external keyboard and mice, and an access point, all powered from the same power outlet were the measurements were taken. A comparable setup would require measuring power just for the laptop and having its LCD off during the test.
  • Finally, 10 minutes is a rather small time window for this experiment, should we want results with a higher degree of confidence.

A man with one watch knows what time it is

There is a quote I always liked, by Lee Segall, which is actually known as Segall’s law – it seems like there’s a “law” made out of every witty saying.  It goes like this:

A man with one watch knows what time it is; a man with two watches is never quite sure.

I was duly reminded of it recently: having acquired four DHT22 humidity-and-temperature sensors, I set out to comparte them and see whether they report similar results out of the same environmental conditions.  The experimental setup was simple, a NodeMCU SoC with each DHT22 connected to its own GPIO pin (this sensor module does not implement a bus and thus each require its own dedicated I/O pin).  Readings were taken every 5 seconds and output to the serial port as CSV values (one reading per line).


The results of collecting data for 15 minutes can be seen below. The first set of curves show the temperature, with starts out between 20.3 and 21.0 ºC (a disagreement of 0.7 ºC, or 3% between the sensors.


02 Temperature and humidity with air conditioning.png

The second set of curves, the humidity readings, appears more coherent, but that is a mere effect of the scale of the values being larger due to an overall larger excursion of the sampled data. The humidity starts out with the sensors reading between 66.9% and 77,5% – for a much larger 10.6% disagreement.

Overall during the 15min this test ran the maximum disagreement from the sensors on the temperature was a mild 1.1ºC, while the maximum difference in readings in the humidity was 13.1%

The drop in temperature and humidity displayed in the chart was induced by an ar-conditioned being turned on – it is interesting to note that the humidity drops at first, then start to climb back up after the temperature stabilized; this is an effect which I cannot explain, neither I can infer whether this was “real” or an artifact of the way the sensor works.  Empirically the air felt dryer, but I would not trust the feeling alone and I had no other sensors at hand.


  1. The humidity readings from the DHT22 cannot be trusted to be accurate; one is not going to make a weather station with these guys, not without some serious calibration with more accurate sensors
    1. However, the trend values were consistent – same rate of decline/climb; for the application I have in mind this is all I care about.
  2. Temperature is looking good: they all reported more or less the same values. I’m yet to check these readings against a different sensor module – I have a few DS18B20 modules, and these are fairly precise little things.