Wednesday, January 2, 2013

Water Level Sensor


Summary:
Used an ultrasonic sensor, 555 timer, netbook, and PHP skills to create a live online database of the water level in Galveston Bay.


This is a project started by my father and me in Spring 2008, with modifications and additions being made intermittently through the years. It is by far the longest running project I've ever done. The setup has been recording water level data in Galveston, TX almost continuously since the beginning (minus a hurricane or two), and the most recent few days of data can be viewed live on the internet:

Most recent 6 days of data. Sometimes looks weird if I've recalibrated something, or if a hurricane has wiped out our house. The dashed blue line is roughly the height of the bulkhead.

Motivation:
Measure the water level in Galveston Bay and display the results on the internet. Simple enough..

Build Details:
1) Sensor
The first issue was how to actually measure the water level. We have a house with a boat slip, so direct access to the water isn't a problem. One method would have been to have some sort of sensor float on top of the water or run down the height of the bulkhead. Exposure to salt water would cause problems for any kind of sensor we could think of, so we opted for remote sensing. We mounted an ultrasonic sensor a few feet above the water pointed down to measure the distance between the sensor and the top of the water. The first sensor we used had a range of 6 to 255 inches with one inch resolution. The connections needed to control the sensor (Vin, GND, TX, RX) were made through an ethernet cable running from the mounted sensor all the way back into our house (~50' of cable) where the rest of the electronics were. We did this to limit the amount of circuitry exposed to the elements.


2) Controller
The second part was figuring out how to trigger the sensor to take a measurement and how to read the result. All that is needed to trigger a measurement on the sensor we chose is a single pulse at least 20us long on the RX line. I wired up a simple astable 555 timer circuit that would send such a pulse 4 times per second, enough to capture the change in water level due to individual waves moving by. Once the sensor has made a measurement, the result is sent back on the TX line as regular serial data in the format R###, with the number corresponding to the distance between sensor and water. The TX line runs straight into an adjacent netbook for processing.

3) Processing
Running on the netbook is a short C# code that reads the incoming serial data and parses it. After converting the R### message from the sensor into a water height using a known calibration, the code stores the result into a buffer. After collecting about 100 measurements (25 seconds of data), the mean and standard deviation of the buffered data is computed. Since the measurements are being taken a few times per second, the standard deviation is taken as an approximate wave height and stored along with the mean water level. Once a few of these water level / wave height pairs are collected, the code sends them off to the internet for logging.

4) Logging
One measurement every 25 seconds is still a lot of data to store if you are interested in keeping track of years of data. The data set sent from the netbook gets stored in two different databases. The first stores every measurement received, but clears out any data that is over 7 days old. This way, recent data can be viewed at high resolution and only requires about 25k data points. The second database stores 15 minute averages of the incoming data, so even years of data only needs 100k data points. In all, both databases combined only take up a few megabytes of memory.

5) Plotting
To generate live plots of the most recent few days of data, I wrote a somewhat lengthy PHP script that would read data from the database and output a png file plotting the data. Instead of using a library for plotting things, I for some reason hand-wrote how to set up the axes, autoscale them, draw grids, print labels, and plot the water level line by line. While this allowed for a significant amount of customization, in hindsight I think we could have survived with a pre-built library like Google Chart Tools. Still, the plot works well and allows the user to set both the image dimensions and the time extent to display.

To this day, the water level plots have been useful for figuring out water conditions, tide patterns, and incoming storms. At some point I'll write a post showing some of the long-term recorded data and how it can be analyzed. All kinds of interesting features can be seen, like the interplay between solar and lunar tides and the effects of incoming storms.



Insights:
1) Weather-proofing an outdoor sensor is difficult, but not impossible. Over 4.5 years the sensor had only been compromised once, and that was from a hurricane that was able to take someone else's boat and place it on our lawn.
2) The 555 timer is too simple and static, while the netbook is too complicated and overpowered. A simpler solution would be to use a single Arduino board to trigger the sensor, process the measurements, and send data to the internet.