Build a Wireless Water Meter for Your Home

Watch over your usage with an Arduino and a Raspberry Pi

Advertisement

California, where I once lived, is in the midst of a severe drought. Thankfully, I now reside in North Carolina, a much wetter state. But even here there have been years when water was in short supply and people were asked to conserve.

Most folks are happy to comply with such requests. But that’s not easy to do when information about your usage comes only once a month on your water bill. You could, of course, track usage more finely by hoofing it out to your water meter periodically and noting the readings. But who has the discipline for that? So I cobbled together a monitor that can show how much water my household is using in real time.

My system doesn’t require plumbing alterations, and it transmits the information via my home wireless network, so I can view water use on a connected device anywhere in the house. Now when my teenage kids take profligate showers, I can berate them with quantitative measurements!

To measure water flowing from the municipal supply, I employed a digital compass—that is, a 2-axis magnetometer—that I originally purchased some time ago from SparkFun Electronics to use as a direction finder. SparkFun no longer sells that module, but for even less money (US $15), you can now purchase a 3-axis magnetometer, which I suspect would work just as well or even better.

A magnetometer is valuable here because of the way mechanical water meters work. To isolate the gears of the actual meter from water exposure, a rotor is typically attached to a magnet in a separate chamber through which the water flows. As the water spins the rotor, this magnet turns another magnet in the meter’s gearbox. Consequently, these coupled magnets produce a magnetic field around the meter that varies depending on how fast the water is flowing.

I figured that the field changes produced by the magnetic coupler mechanism would provide a booming signal outside the meter. But in fact, the magnetic signal is quite subtle. There are probably a few reasons for this: The steel housing of the meter likely shields the meter’s internal magnetic field, and the moving parts inside the meter probably include various steel components that generate spurious magnetic fields at higher frequencies. At least that’s what I suspected was going on. In any event, the signal I had to work with was a mess.

So my first challenge was to program an Arduino attached to the magnetometer to transform that noisy magnetic signal into a flow rate. I toyed with the idea of using a Fourier transform to pick out the dominant frequency corresponding to the flow rate, but instead I plumped for autocorrelation. That is, the program multiplies a short sample of the signal by a time-lagged version of itself and sums up the results. To find the dominant frequency, the Arduino code increments the lag between the two samples and looks for a peak in the summed results. That requires much less processing and seems pretty robust with respect to noise and harmonics.

Some testing with the garden hose showed that this arrangement could discern flow rates between gentle and gushing. The low end is limited by how long you let the Arduino collect measurements before processing them. I settled on about 3 seconds, which lets me measure down to a near dribble. But at the very highest flow rates (as when I used an outdoor spigot with no hose attached), my system faltered.

You might expect that high rates would produce a signal that was easier to measure than at low rates, but that’s not the case. When the flow is really high, the magnets inside the water meter rotate at a clip that exceeds the magnetometer’s fastest possible sampling rate, leading to a phenomenon called aliasing. (It’s what makes wagon wheels in those old Westerns look like they’re spinning backward instead of forward once a certain speed is reached.) As a result, the data simply weren’t valid above a certain flow rate.

Short of experiencing a burst pipe, though, nobody in my house would be running water at or above that threshold, so I decided not to worry about this limitation and proceeded to work on how to communicate the information. There was also the issue of how to power the Arduino and magnetometer I had placed at the water meter, which is well separated from my house.

The solution was a 15-meter length of four-conductor telephone cable. Two conductors brought 9-volt DC power to the Arduino; the other two carried the digital output (transformed to RS-232 voltage levels using another board from SparkFun) to a Raspberry Pi, which I placed on my porch next to a regular AC power socket. From there, it was easy to have two “wall warts” power the Pi and the Arduino, and the Pi was close enough to my router for it to get onto my home wireless network.

I programmed the Pi in Python to serve up a single Web page, using the Flask framework for creating Web apps. That page shows flow rate and total water usage, updated every 10 seconds, and has a button to reset the water-usage counter to zero.

I have not yet attempted to calibrate my setup so that the rate is shown in sensible units, say liters per minute. So the number for total usage is also given in arbitrary units at the moment. But the Arduino and Pi in combination do an admirable job of informing me about relative flow rates. The whole family can now compete to see who can linger the least in the shower.

This article originally appeared in print as “Water Stats on Tap.”

Advertisement