Tuesday, March 7, 2017

Logging the water height in a well cheaply and non-intrusively

I made a little gadget to observe the water height in my water well over a period of days or weeks. I'd previously found the height by tapping on the top of the well and recording the echoes with a phone, but I wanted to see how the water height varies over the course of a day, week, or month. Unfortunately, I have to eat, sleep, go to work, clean the house, socialize, and do a variety of other tasks that get in the way of tapping on the top of my well every 30 seconds or so around the clock and analyzing the recorded sound file to determine the water height. Luckily, microcontrollers have none of those obligations and are perfectly happy to tap, listen, and analyze all day and all night, so I whipped up a water well watching robot to record the data to an SD card, where I can download it at my leisure.

Broadly, the device consists of a solenoid (the tapper), a microphone with amplifier (the listener), and a Adafruit M0 Adalogger microcontroller (the analyzer).

The microcontroller activates the solenoid, which taps the top of the well. The sound wave travels down the well, reflects off of the water surface, and travels back up the well, where the microphone detects the sound. The controller records the sounds coming from the microphone, listening for both the initial tap and the reflected echo. I chose the M0 because of its 32 kB of RAM. To get the finest precision possible, you need to record the microphone data at high frequency. With the ADC set to record the microphone reading every 40ish microseconds, I can record up to roughly seven thousand data points, or about 0.3 seconds of data. A plain-jane Arduino with an ATmega328 has only 2 kB of RAM, and would only be able to record about 0.02 seconds of data - not enough to catch the echo.

After recording, the microcontroller stores the data to the attached SD card.

The raw recorded data looks like this:

Just by inspection, it's clear that the echos occur about every 60,000 microseconds. We could easily write some code to teach the microcontroller to estimate the time between the start of the first two pulses, convert that to a distance, record it, and we'd be ready for the robots to take over!

Except it wasn't always so reliable. I found that occasionally, there would be noise that confused the logic, causing it to mistakenly think a random noise was the echo, and incorrectly estimate the depth to the water. Or the solenoid would come un-moored from the brick I placed on it to keep it pinging in the same place, and would dance over to a spot on the well that made a much quieter tap on the well. Or both:

What's going on in this case? I'm pretty sure the water depth didn't change by 25% in the 30 seconds between readings, so I bet the peak near 70,000 microseconds is probably the true echo and the large peak at 50,000 microseconds is likely noise.

One side note on this - the microphone amplifier I'm using is an adjustable-gain amplifier. I set the gain to the least sensitive setting (40 dB) for the first 30 milliseconds so the initial tap doesn't saturate the detector, then ramp it up to the second most sensitive setting (50 dB). That's why the initial tap and the echo sometimes appear to have similar amplitudes - in reality, the echo is at least 10-15 decibels or so quieter than the initial tap.

Aside aside, I noticed that the true echoes all had a peak-to-trough time (inverse frequency) of roughly 1200 microseconds, or peak-to-peak time of roughly 2400 microseconds, or roughly 415 Hz frequency. 

The noise, however, was typically of a different frequency, often much higher. Note the same x-axis span below as above.

If we can create a bandpass filter to only pass signals that approximately match this 415 Hz frequency, then we can eliminate the noise from contention. As a simple bandpass filter, I settled on the absolute value of difference between two moving averages, one 1200 microseconds behind the other. For true signals at the proper frequency, when the moving average reaches the peak, it subtracts the negative part of the peak from the positive part, giving a double amplitude response. For high frequency noise, each 1200-microsecond average will smooth out the high frequency peaks and troughs. For low frequency noise, the signal will not have moved much in the 1200 microsecond time between the two averages, so the difference will be close to zero. Here it is applied to the above noise (and the following true echo signal).

Boom! The high frequency noise disappears, while the true echo is amplified.

I don't actually know the fundamental reason that the frequency of the echo is 415 Hz. I suspect it has to do with the well's casing diameter (4" Schedule 40 PVC), but I frankly don't know. Sound travels roughly 16 inches in 1200 microseconds, which is roughly 4 x the casing inner diameter? Someone who knows more about acoustics could probably educate me on this subject, or I should bang on some wells of different diameters and see what frequency response they have.

Now time to see how the water level changes over time! I ran it overnight and got the following results. I've omitted a few outliers.

The data suggests that the water level varies by a few tenths of a foot over a day period with no draw. It's hard to say this definitively, though, as there are several potential sources of error that could be masking any level change. For instance, the speed of sound varies with temperature. A one-degree Fahrenheit increase in the average temperature of the air in the well would cause a perceived depth increase of 0.04 feet, even if the actual level did not change. The well should be fairly well-insulated (ha ha), but over the course of a season, the ground temperature could change appreciably, so I wouldn't trust the measurements to an accuracy of more than about 3-5% over long periods of time on this factor alone.

I changed the ping interval to four seconds and watched the level after drawing water from the well. The pump kicks on and off with a pressure switch in a pressure bladder at the surface. You can see several draw down and build up cycles in the first 150 seconds, at which point the flow of water was stopped and the pump remained off. The water level was initially drawn down to about 36 feet from its initial 33.4 feet, taking about five minutes to recover 95% of the level, and about 15 minutes to fully recover to the initial level. I'll have to run the pump for a much longer period and see what the drawdown is for higher usage rates to estimate a maximum well deliverability. I still have no idea at what level the pump in my well is set or what the total depth of the well is.

Here's the code if you're curious.


  1. This comment has been removed by the author.

  2. Peter,
    Thank you for your informative post. I used the cell phone method to test our newly drilled well, and it worked perfectly. Unfortunately, now that they put a pump in, I cannot see any echo or resonance. I've tried several different instruments to tap on the well cap, but all I see is noise. Do you have any suggestions? Thanks

    1. I had the same problem when my pump was running, the noise overwhelmed the signal. I never found a solution other than turning the pump off when I wanted to take a measurement.