Back at the end of 2009 I started playing about with an Arduino solution to monitor the water level in a water tank about 300m from the house. The tank isn’t visible from the house so a standard visual tank indicator wouldn’t work. In a nutshell, this sensor measures resistance through an array submerged in the tank to determine the water level, then sends that data back to a server in the house for humans to read. I covered the prototype and the first iteration of the sensor in this post.
There were a few more steps beyond the prototype required to make it really useful and along the way I discovered some issues with the first model which I’ve improved on, but that’s why you call it a prototype.
Here is the Arduino with an added WiFly shield – an add-on that gives the Arduino the ability to (mostly) seamlessly communicate over the farm’s existing 802.11 WiFi network. Arduino shields piggy-back on top of the board, and in this case the WiFly shield has a handy prototyping area – perfect for projects like this where you need to add a few components to a solution. The red and black leads you can see here connect to the water level sensor in the tank. The whole thing is mounted on an aluminium bracket I made up to fix it securely in the project box.
And here’s the whole assembly in the waterproof (IP66) project box. It’s designed to sit out in all weather, diligently saving me endless trips to the tank to manually check the water, so it needed a good enclosure. The battery taking up most of the box is a bog-standard sealed 12v motorcycle battery. I’ve tried to keep as many components as possible off-the-shelf to keep costs down and make future maintenance easy. The external antenna for the wifi is at the bottom left of the enclosure and the 4-way connector on the right is for signal from the sensor and solar power to come in.
The close up shows it’s a pretty snug fit in there. The Arduino is mounted on an angle so the USB port on the right hand side is accessible without unpacking everything. I learned from version one that there will always be lots of tweaking before it works well, so I wanted to make future software changes easy.
The enclosure mounted on a post just above the water tank. The 4-way connector makes it easy to connect up without taking the lid off (important if the weather is rubbish) or take the whole thing back to the workshop when I need to make physical changes.
The sensor array of resistors and an earth return wire lie inside the plastic pipe. The whole thing is submerged in the tank. Originally I had joined the string of resistors together with soldered nichrome wire but after a few months some corrosion (and what seemed to be electrolysis) was starting to look unsightly. I replaced the connections with plain light gauge insulated lead-out wire and it seems to be fine now. The sensor sends 5v DC through the water for a few milliseconds to take a reading so I don’t expect too many problems long term (the tank and all its fittings are plastic). The original post has photos of the array being built.
To power the sensor, I’ve used a 10W solar top-up charger with a built in charge controller. It’s a standard item from most automotive suppliers. At such low power it’s difficult to over charge a 12v battery but having the charge controller adds a bit more margin for error. This panel provides more than enough power to keep the battery topped up. The Arduino draws a tiny amount of power, but the WiFly shield does use a bit of power when it’s transmitting. The ideal angles for a solar panel are: facing due North (in the Southern hemisphere) and inclined to an angle from the horizontal equal to your latitude (about 42 degrees here). I had to cope with the curved surface of the water tank so it’s a best-guess effort.
The distance back to the house is over 300m. We have a fairly powerful wireless access point attached to the outside of the house so small wifi devices can connect to the network pretty easily if they have line of sight.
Back in the house, we can visualise the data, thanks to some great work on the server software from our friend Dave. Making this prettier and adding some smarts like alarms will be the next phase of this project.
The Arduino code is still a work in progress, but I’m more than happy to share it if anyone might find it useful. The software is quite modular so it can be fairly easily adapted for other sensors. We use it for several temperature sensors around the farm and I’m currently working on another sensor to record wind data at a remote site we are thinking about putting some wind turbines on.
Update November 2011 – Triumph!
After a few more tweaks to improve reliability and error tolerance I’m happy to publish the code. I’ve just started playing with Fritzing, so hopefully soon I can put up a proper schematic for the project.
While the sensor worked well most of the time, when you’re dealing with a device a long way from the house that needs to just work, “most of the time” isn’t quite good enough. The problems I had with the WiFly shield were the reliability of communications and recovery from errors.
The code supposedly resets the WiFly client for each data-gathering cycle, but every now and then (from 1 hour to 1 week) it would fail to initialise properly and hang. This would hang the Arduino entirely. From the research I did, and asking people smarter than me, it looked like the WiFly shield wasn’t properly shutting down or clearing its buffers. I’d noticed that it always worked first time, just after a power reset. To replicate that I connected the power to the WiFly shield via a small relay, controlled by the Arduino. Now I have the ability to cut power to the WiFly shield at the end of each data-collection cycle, and power it up each time. This seems to have solved the comms problems and has the added advantage of not wasting power on the WiFly shield between transmissions.
The second problem was the Wifly shield’s fairly fragile handling of errors. If for example, the wifi network or remote server were not available to connect to, the WiFly shield would hang. No retries, no resets, just hang. After much playing around I came across the documentation for the watchdog timer, that allows you to define a reset clock in the code that will reset the Arduino if certain points in the code aren’t reached in a timely manner (ie it has hung). So now, if for any reason, the WiFly can’t post data to the remote server, it resets and tries again (and will keep resetting until it has successfully completed a data post).
The basic function of the sensor is: Take sensor reading > join Wifi network > sent http GET request to remote server > wait >repeat
It’s in three parts; the main .pde file, the settings file, and the water level reading function in it’s own file – just put all three in the same place. To use it you’d need to change any settings specific to server and wifi network settings to suit you. There is also a serial printout of the sensor data and comms status so you could easily modify the code to send data somewhere else, print to LCD, write to an SD card etc.
I appreciate this isn’t exactly a comprehensive how-to. This project (and documentation) has been evolving over a year and a half. If there’s interest I can put some time into making this more of an “instructible” to make replication a bit easier.