Introduction: Pool Level Sensor

A few years ago we moved into a house with a nice little pool. It's an old one, built some time in the '70s. I replaced the pumps and upgraded the pool controller but keeping the pool at the right level was, well, hit and miss. And with all the money I'd spent on the new pumps, I cringed every time the level was too low and the pumps ran dry. Since the refill valve was manual, I had the opposite problem a couple of times too: I overfilled the pool when I forgot the water was on.

This sensor automatically detects low water levels and turns on the pool refill valve to keep it full without accidentally overfilling. As an added bonus, it has a waterproof temperature sensor as well. And yes, I know you can get attachments for your garden hose to do this - but where's the fun in that?!

It's based on the Electric Imp IoT platform. I chose the Imp because it works with my existing WiFi network and doesn't require an on-site controller. I can check the pool level from anywhere by logging in to the sensor's Imp agent in the cloud. The product is really well documented and it eliminates a ton of tedious platform work. I really enjoyed using it.

To trigger the fill valve, I integrated the probe with my home automation system based on the Universal Devices ISY controller. I already have an irrigation controller that can turn my pools fill valve on and off so that capability was already in place. I'm not going to spend too much time on the ISY part of the project (although you can see how it works in the Imp agent code). Instead I'll focus on the build of the sensor itself, which could also be used to monitor water levels in fountains, fish tanks, water storage tanks, or whatever you need to track.

Step 1: Parts and Materials

The probe has 3 main parts:

1) the probe itself, which is simply a strip of copper tape (Sparkfun, PRT-13828) that's glued to the inside of a length of PVC pipe (hardware store) which friction-fits into a PVC reducer. The reducer is epoxied underneath the pool skimmer lid. All the electronics fit inside the reducer and the joint is sealed with Tommy Tape. To change the battery, just cut off the Tommy Tape to get inside the probe.

2) the Imp board, which runs the necessary software and connects to the Imp cloud service via WiFi. You can get an Imp and a breakout board from Sparkfun, part numbers WRL-11395 (about $30) and BOB-12886 (about $13).

3) an evaluation board from TI for their FDC2114 chip. The eval board part number is FDC2114EVM and you can get it for about $30 from TI.

I added a waterproof temperature sensor as well (Sparkfun SEN-11050, $10) and needed a small solderable proto board (I got mine locally at Halted but the Sparkfun PRT-12702 might work) to hook it all up. You'll also need a diode, two 10k resistors, and one 4k resistor.

Step 2: Make the Probe - Mount Sensors

In operation, the TI evaluation board uses the capacitance of the copper tape in the probe to create an RC circuit with a specific resonant frequency. The FDC chip measures the resonant frequency change caused by the probe's changing capacitance. Any substance (like water) in close proximity to the copper tape will affect the tape's capacitance. As the waterline goes up and down around the PVC pipe the capacitance of the probe changes, allowing the FDC chip to accurately measure the level.

Mechanically, the probe itself is pretty simple. It has two sensors. One of them is normally always below the waterline. I use that one strictly to detect if the probe is in or out of the water. The second sensor is longer and mounted so the waterline will affect its capacitance. This one provides the actual water level reading. You could get away with just one sensor but you'll have to change the software if you do since I use the in water/out of water sensor as a key part of the state machine.

If you're making this for your pool, you'll need to determine how long to cut the PVC pipe. First, check how much clearance you have from the bottom of the skimmer lid to the expected waterline. Accounting for the length of the adapter (the black piece in the picture), cut a length of PVC so at least 3 - 4" of pipe will be immersed in the pool when the lid is on the skimmer. But don't make it too long or it'll contact the bottom of the skimmer basket.

Now cut a length of copper tape and mount it lengthwise inside the PVC pipe (mine is 5.5" long and 2" wide). The length of the tape and the mounting position should allow a portion of the tape to be below the waterline at all possible water levels. Make sure you record how long the copper tape is before you mount it - it'll make calibration easier. The in water/out of water sensor is a shorter piece of the same copper tape (about 1.5" long and 2" wide) that mounts at the bottom of the PVC pipe. Mount this tape where it will be below the waterline at all times when the probe's in the water.

Next, solder a lead wire to the top of both pieces of the copper tape - this wire will attach to the FDC board (don't attach it just yet). A single wire for each sensor should work, but I used shielded cable just to make sure the readings would be less affected by noise or the wire's position once I stuffed all the circuitry into the reducer. For ease of assembly/disassembly, I used a Molex connecter to connect the copper tape leads to the FDC eval board.

In the picture, you might be able to make out one other smaller sensor (copper tape) at the top of the tube. The software doesn't use this sensor so don't worry about it. I'm experimenting with it to see if I can compensate for temperature drift. Right now I'm not sure how much the readings will drift with temperature - compensation might not be needed for my relatively low-res application. However, TI describes a 3-sensor method of measurement and calibration in the app note so I'm giving it a try.

I experimented with a bunch of different probe designs. You might try a different approach - I found that even a single insulated wire responded to changing water levels remarkably well. I also tried a etching a PCB and coating it with varnish - that would probably be great for high production volumes. Both the wire and the PCB worked but I settled on this design because it was easy to build, should hold up to moderate abuse in the field, and has enough capacitance to be less susceptible to noise issues.

Step 3: Make the Probe - Finish Mechanicals

Next you'll cap the PVC pipe with a standard PVC cap mounted on the wet end of your probe. If you want to include a temperature sensor, now's the time to mount it on the PVC cap. Drill a hole in the cap just large enough for the business end of the sensor. Drop the sensor through the hole and seal it. I used Marine Super Goop to affix the sensor and then put a liberal amount of silicon caulk inside the bottom of the cap for good measure.

Once you have the copper tape installed, the lead wires soldered on, and your optional temperature sensor mounted on the cap, you can assemble the cap to the PVC pipe using standard PVC cement. Since the thickness of the PVC cap increases the distance between the tape and the water, it will spoil the linearity of the probe where the copper tape extends into the cap's coverage area. It might not matter in your application (it doesn't in mine), but consider trimming some length from the cap to ensure the entire cap is always underwater.

Now for the mount on the skimmer lid. I used a PVC adapter available at my local hardware store. You need a watertight bond between the skimmer lid and the adapter. I had to Dremel out the plastic ribs on the lid so the adapter would sit flush. Once you have a good fit, epoxy the adapter to the skimmer lid.

In use, you're going to friction-fit the PVC pipe into the adapter and use Tommy Tape to make the joint watertight. You can just cut the tape off when you need to change the battery or access the electronics. But don't do that yet, there's still lots left to build!

Step 4: Characterize the Probe

I'm not going to lie, this part was pretty tough. If your probe is similar to mine (meaning the copper tape is about 5.5" long and 2" wide), you can skip this step - the characterization values in the software will likely work for you. If you've gone rogue and made your own probe then you'll need to characterize it so the FDC chip has the right values. Note that we are NOT using the Imp at this point - we are using the EVM's microprocessor module via USB.

Connect the EVM to your PC via USB (sorry Mac folks, PC only). Fire up the EVM software TI provides for the evaluation module (documentation here http://www.ti.com/lit/ug/snou138/snou138.pdf). You can get a feel for how the software works by using the demo touch pads provided on the EVM. Specifically, get yourself to the point you can see live capacitance measurements in the software's data streaming module as you touch the demo pads. If you can do that then the EVM software's working as it should.

Ok, now take a deep breath and snap off the demo pads. Connect your level sensor to the CH0 thru holes on the EVM. Connect your in water/out of water sensor to CH1. You could solder the probe lead directly to the EVM but you're going to wish you'd used a connector for easy assembly/disassembly. :) Get a bucket of water, you're about to dunk your probe!

This is great fun when you can see the streaming output graph change as you raise and lower your probe in the water. Woo hoo, it really works! Your goal now is to find the values for the FDC that give you the most dynamic range without "railing" the readings out of range of the chip's registers.

Section 10.2 in the TI data sheet (http://www.ti.com/lit/ds/symlink/fdc2214.pdf) has a good overview of all the possible elements needed to characterize your probe. It's pretty complicated, but here are a few simplifying epiphanies I had along the way:

  • If your probe is like mine, it is a "single ended" probe. Set the defaults accordingly.
  • You don't need to worry about how responsive the measurements are - I take one reading every 15 minutes, so there's no need to optimize for measurement latency. Don't spend too much time futzing with RCOUNT and SETTLECOUNT values - just open them up.
  • If you're only using one channel, all the channel MUXing configurations get pretty simple too.
  • The software I wrote polls the sensor. So don't worry about configuring the interrupt.
  • You'll work mostly with GAIN and OFFSET to maximize dynamic range while still keeping the readings between maximum and minimum bounds. The real-time streaming display is a great tool to help you zero in on the values here.

The EVM software lets you load a previously-saved configuration from a JSON file. The attached file is what I use for my probe and might help you get started. Note that I'm using 3 channels, although you can just ignore the channels you aren't using.

Once you have all the values you need for your probe, save the config to a JSON file. You'll also need to record the following values to put into the software. Note that these are all raw values (I call them "ticks"), not actual capacitance. The tool provides both so make sure you use ticks:

  • The slope of the probe. Determine how much the sensor reading changes per inch of immersion. This will be a negative number - raw readings get smaller as the probe is immersed. If you remembered to record the length of your copper tape, you can take one reading when it's dry and one when it's completely below the waterline. The slope will be (wet reading - dry reading)/(length of the copper sensor strip).
  • The value of the immersion probe (CH1) when the probe is immersed and when it it out of the water. The value (wet - dry)/2 is a good point to use as your in water/out of water dividing line.

Good luck! This part was difficult but also pretty interesting.

Step 5: Build the Electronics

Now it's time to build the circuit itself. There are a couple of pull-ups for the i2c bus, and a diode and resistor for the 1-wire circuit (only needed if you're including the temperature sensor). The tricky part is building the interconnections so they'll fit inside of your PVC adapter housing. As you can see in the picture, I used a small solderable prototyping board to tie things together. I know, it's not pretty, but it's small enough to fit into the sensor housing.

Now's the time to snap off the microprocessor from the EVM. Once you do this it's going to be hard to connect the EVM to the TI software, so consider adding headers so you can swap back and forth between connecting the board to the Imp and to the microprocessor board. Be careful though - I zapped a chip once by failing to properly line up the header pins!

I used a standard 9V battery for power. Everything runs from the 3.3V regulator on the Sparkfun breakout board, which is rated for up to 17V. I'm not sure how low it'll go though - it definitely worked with 4AA batteries but I'm guessing it won't work with voltages lower than ~4V.

Step 6: Load the Software

The Electric Imp platform uses two software entities. The "device" code runs on the Imp in your sensor. The "agent" code runs on Electric Imp's servers in the cloud. The code is here.

You'll need to "personalize" the software as follows:

Agent, line 4: replace with your own API key from LOGGLY. It's free for low-volume, personal stuff and a really cool tool. If you don't want to use Loggly then change the code to use whatever logging target you want. Or none, doesn't matter to me. :)

Agent, line 41: the "recipe" variable needs the JSON array you ended up with once you characterized your sensor. Open that JSON file you saved a couple of steps ago and copy the text. Use it to overwrite the recipe variable on line 41. Make sure all the extra braces and brackets are as you see them in the original. Note that if your sensor is similar to mine in terms of construction and dimensions, you may not need to change this.

Agent, line 114 - 118: replace with the values appropriate for your sensor. The previous comment applies here too - things might work without changes if you made your sensor like mine.

Agent, lines 147 - 151: replace with values appropriate for your ISY. Note you'll need to modify the program if you're not using this feature and just want to track levels. Or yank this part out if you don't need it. Look at the comments to find relevant dispensable ISY lines/modules.

Device, lines 441 - 446: fill in details for your WiFi network or networks. BlinkUp works, but I'm not sure what happens after a wake from sleep event. Will it start with the BlinkUp config? Or will it try to contact the last known network? (I think so). Hard-coding the network also let me provision a second network that had better coverage up in the garage. :)

Device, lines 428 - 430: these values determine how often the level is sampled and the server updated. Lower values will update more often but will also use more power.

Run it and check to see everything's working. You can ignore the "no handler" error you see in the server log console. That happens because the two pieces of software "race" when starting from scratch. That should happen only once per start.

Step 7: Final Assembly

Now you're ready to stuff all those electronics into the probe housing and button it up. Attach the 9V battery, sensor leads, and temperature probe leads. Carefully put the circuit boards in the PVC adapter and try to dress the wires so they don't get pinched. Slip fit the PVC pipe into the adapter and use some Tommy Tape to make a watertight joint between the two. You're ready to get in the pool!

Step 8: Use It!

If you click on the agent software link (look in the agent SW panel, upper left corner) it'll launch a simple web display of levels, temperatures, etc. (see the example screen shot). Note that this display shows "no data" until the first reading comes in. The sensor doesn't try to give you an absolute measurement - only a measurement relative to the target "perfect" pool level. At first the target level will be a default which isn't what you want. To set the target level, click the "recalibrate" button and tell the sensor if the current water level is high or low and by how much. Click save. Again, nothing on the main screen will update until the sensor comes on line to give us a reading.

A few things to note:

  • When the probe first fires up it'll be in "responsive" mode, meaning you can access the device to upload new software.
  • After 3 minutes the probe goes into "deep sleep" to save battery. It'll consume between 10 and 15 microamps in this state, so the battery should last a good long time. However...you can't access the probe at all when it's in deep sleep. You can queue a software update but it won't take effect until the probe wakes up.
  • Three things will wake the probe from deep sleep:
    • The probe takes readings every 15 minutes and stores them without contacting the server. After the Imp's storage is full (about 12 readings), it'll wake up and send all 12 readings back to the agent, which will then store the readings in Loggly. You can change the number of readings stored from 12 to some other number on line 431 in the device code. My guesstimate was that 12 would fill up available memory. Bad things might happen if you overflow.
    • A status change of any kind will cause the probe to contact the server immediately after its measurement. The probe has 5 statuses: out of water, too high, too low, in range, and unknown (used when the readings vary too much, probably because someone is swimming). If you need to contact the probe after you've sealed it up and you don't want to wait 3 hours until the readings table is full, you can take it out of the water to force a status change on the next measurement.
    • If you power cycle the probe it'll immediately restart in responsive mode. But that's hard to do once the Tommy Tape is on. :)
  • When the pool's filter pump is running, I've found the water level in the skimmer basket drops by .75 to 1 inch. In my case I use the ISY to detect when equipment is running (yes, my ISY is integrated with the pool controller :) ) so I don't log false "too low" readings.
  • You can change how often the device takes a sample, how long the device sleeps, and how long it stays in responsive mode by changing the variables on lines 428 - 431 in the device code.

Step 9: What's Next?

  • The Imp integrates with a number of web services, so with a little modification you could easily use IFTTT to send twitter or SMS notifications.
  • I'll probably add some code to auto-calibrate the probe as I see more data. At that point I'll probably also put lots more time in between readings to really maximize battery life.
  • The probe logs reading variance, which means the probe can tell when someone's in the pool. You could spot unauthorized use or even set up an alarm if you have non-swimmers around. But I'd have to drastically up the reading frequency and that'd probably have a big impact on battery life.
  • I used a small solar cell on another project - it'd be fun to do the same here.
  • It'd be cool to build an LCD unit to display the pool temperature.