Everyday IoT: Tank Water Levels

A few years ago I moved house and became the owner of a nice backyard with a garden.  However with early arrival of summer, I quickly discovered the challenge of keeping everything alive!  As holidays and heat-waves approached it became pretty clear we needed an automated watering, and one that could keep track of tank levels to avoid running the tank dry and damaging the water pump. Add to that the fact I'm always out to save a buck, I was inspired to do a little IoT project...

Final set-up, sorry about the spoilers

I iterated on this idea for quite a while with ideas ranging from full computer controlled watering system to something much simpler.  In the end I decided my requirements were:

  1. Have a watering system with an automatic timer
  2. Be able to switch off the pump remotely 
  3. Be able to check tank levels remotely
I eventually realised that two of these would be much easier (and probably no more expensive) to buy as off-the-shelf components but there was still and IoT project at hand.

The solution I decide on was:
  1.  use regular store bought tap timer (since 24V solenoids seemed like too much of a hassle)
  2.  use a smart power plug to switch off the pump when required
  3. Water level logger = IoT Project!
Tank water level sensors were not cheap and it was not clear if it would be possible to view the water level remotely so I started scheming.  The water level sensor would require:
  • Ultrasonic distance sensor - weatherproof (~$25)
    • Seems to be the easiest and cheapest sensor for the task and there were plenty of tutorials online
  • Raspberry Pi Zero W (~$18)
    • I already had some experience with Pis and I figured the baby of the family would be up to the task
  • Python logging script
    • I wouldn't claim to be a strong python programmer but I can usually hack something together and again, I'd used it for logging before
  • Google sheets as a way to view the data
  • Optional temperature sensor (DS18B20) (~$5)

With a little breadboard and a few jumper wires (soldered directly to the pie because I was too cheap for headers) everything wired together pretty easily.  There quite a few tutorial on wiring up ultrasonic sensors (and temperature sensors).  The only difference was that most of the ultrasonic's seems to run on 3V but this one had a 5V input labelled so that's what I used but I really struggled to find documentation for this sensor to confirm it.


The script was really where things got interesting.  I largely duplicated a script from one of the tutorials to get it logging from the GPIO pins, calculate a time between trigger and response and convert to distance.  However I noticed that reading were very inconsistent, particularly when it was in the (congregated steel) tank, when I was taking multiple readings for consistency.

I had seen other set-ups that used a long piece of pvc around the sensor to improve readings which seemed like big challenge for my set-up, I did find two things that helps improve the readings:

  1. I worked out that I got much better consistency with a larger gap between readings, something closer to 5 seconds rather than 1 or 2 seconds.
  2. Adding a filter in the script to clean noisy data and remove outliers
  3. Adding a small tube to help reduce reflections


Ultrasonic sensor with reflection shield and temperature sensor (installed later)

The filtering script was designed to remove outlier and try and identify the group of measurements which represent the actual measures.  It was based on removing outliers that were more than 'x' standard deviations from the mean but flagged an automatic fail if the pre-filtered results had a SD greater than 'y',  the post-filtered SD was greater than 'z' or there were inefficient measurements after filtering. The remaining measurement were averaged and the results have been quite consistent.  I may revisit this script and try using a median for outlier removal in future.

The logger was set-up up to take water levels every 2 hours, and to ensure the measurements are captured even if there was no internet connection, they are logged to a file on the Pi.  Shortly after each measurement the pi runs an upload script that writes any new lines to the google sheet.  All scheduling is done using a cron job.

Writing to google sheets uses the Google API via the Google client library for Python.  The biggest challenge using this is setting up authentication, however if the process is run for the first time using the GUI the authentication is done is a web browser and the token is then stored locally.

 While the project was successful to allow monitoring with away from home, there are still some improvements I'd like to add.

The graph of the the water levels over time when the water level is constant looks like a wave due to temperature (and humidity) variation influencing the measurement. The next step is to improve this is to add a temperature sensor in the thank and use the temperature in the distance calculation.

Graph of tank water levels. The up-tick in each step is caused by temperature affecting the distance measurement, not having more water in the tank

Currently the process is running without clean-up script that archives old data both on the pi and on google.  This should be relatively easy to implement however it seems to be working fine for now...









Comments

Popular posts from this blog

Kiva Exploratory Data Analysis on Kaggle

Victorian Property Overlay Map

Know your bias