Christmas Tree Watering
.
The Problem
I Have a 2 year old son, Henry. Like most two year olds, he loves everythig to do with Christmas.
So, to make the most of the festive season, we got a real Christmas tree at the weekend. And he *loves* it :
Here is it in all it's glory. the problem is that it is still over two weeks from Christmas, and we'd like there to be some meat left on it.
The best way to preserve them is keep them cool, and give them *lots* of water. I mean lots... they drink water at a heckuva rate.
The holder thingy that it is mounted in hold about 2 litres of water, but that empties at an alarming rate...
Note the bits of wood jammed in there to keep it sturdy, upright and safe. The circular casting it is all sitting is about 8" across and about 4" deep.
To ensure it always has water we have a system: I top it up in the morning, and my wife tops it up in the evening. However, I dont have such a good memory. Here is what happened last time I forgot to water the tree* :
*I have been asked to point out that this has never actually happened.
The Solution
In the name of marital harmony, I broke out my mbed, an original BoB, a clothes peg and a glue gun.
Theory
Casting my mind back to D&T at school, I seem to remember the project of choice was an alarm that hooks over the bath, so that when the bath water level reached the predetermined height, a current passed between two probes, triggering a circuit that switched on a lame buzzer to alert the happless incompetant that the bath is full. In this case we want to detect when the water is *below* a certain level, and the happless incompetant is someone who cant even remember to water the 7' tree that has just appeared in his lounge, even though it is covered in flashing lights.
Setting Up
So my plan is to get some 0.1" header strip and glue it to clothes peg with some flying wires. I can then clip the clothes peg over the side of the casting my tree is mounted in so that the 0.1" header will stop touching the water when it drops below a predetermined level. If I can sense the current, or lack of then the water stops shorting out the contacts, I can raise some kind of alarm.
So far so good. The 0.1" strip is just poiing out the front of the peg, the flying leads are securely attached by a long bead of hot glue.
Experiment 1
The first thing to do is see if I can measure a current through water with *just* the mbed. In the days of D&T there was always a transistor involved.
#include "mbed.h" DigitalIn sensor(p20); DigitalOut led (LED1); int main() { sensor.mode(PullDown); while(1) { led = sensor; } }
I connect the flying leads between Vout (3.3v) and p20. Nothing. I lick the header, there is a slight tingle, but clearly not enough to detect.
I move the live flying wire to the Vu (5v), give it a lick... yup.. that has more bite...(LED still doesnt light though). Still this is a water level detector, not a tongue detector, so lets try properly.
Bingo! It works a treat. [video to follow]
So I can now go about working out the alert.
Experiment 2
To detect that the tree needs more water, we are looking for a falling edge on my DigitalIn. Since the tree drinking process is slow, and the refills are not often i probably dont have to worry to much about debouncing and stuff. However, I do want to send multiple reminders, so I might just activate a ticker when I detect the water is low, and deactivate it when is filled.
#include "mbed.h" DigitalIn sensor(p20); DigitalOut led (LED1); Ticker activated; void alert (void) { led = !led; } int main() { sensor.mode(PullDown); while (1) { // while the water is deep enough, wait while(sensor) { } // we are here because the water is low activated.attach(&alert,0.1); // crude debounce wait (30); // while water remains low, wait while (!sensor) { } // We hare here as the water level is back up activated.detach(); // crude debounce wait (30); } }
Wow, that worked like a charm first time! Here is the test rig :
Experiment 3 Some alert system
Okay, I say "some".. I have a good idea :-)
At the moment I am highly inspired by Rolfs work on the HTTP Client. I Have a Netgear HomePlug adaptor (XE103) and there is one hooked up to my broadband router, so I *could* get onto the internet pretty easily.. there is a socket right behind the Christmas tree, and I am using a BoB with an RJ45 connector. Coincidence? I think not :-)
The first port of call is Rolfs page:
https://os.mbed.com/projects/cookbook/wiki/HTTPClient
It all looks too simple to be true.
I import the prebuilt library from :
https://os.mbed.com/projects/cookbook/svn/EMAC/lwip/precomp
I fuse Rolfs example code with my own. I decide that whatever I'll do I will do it in the ticker, and that I should make the ticker run on a 300 second interval. I can chande this easily enough... it will depend on the final alert mechanism.
I register a hosting account at http://www.000webhost.com for this experiment.
Here is the code :
#include "mbed.h" #include "HTTPClient.h" DigitalIn sensor(p20); DigitalOut led (LED1); HTTPClient http; Ticker activated; // new alert function calls a PHP script // I registered an account on www.000webhost.com void alert (void) { char result[64]; led = !led; http.get("http://mbed.comxa.com/tree.php", result); } int main() { sensor.mode(PullDown); while (1) { // while the water is deep enough, wait while(sensor) { } // we are here because the water is low activated.attach(&alert,10); // crude debounce wait (30); // while water remains low, wait while (!sensor) { } // We hare here as the water level is back up activated.detach(); // crude debounce wait (30); } }
PHP Scipt
The ticker is just going to call a PHP script at the address in the listing. So I need to write that script.
I'm no PHP wizzard, but I know PHP has a nice function called mail()
<?php$to = 'chris_styles@yahoo.com';
$subject = 'The tree needs water';
$message = 'Quick, before it dries out';$headers = 'From: "The Christmas Tree" <chris_styles@yahoo.com>' . "\r\n" .
'Reply-To: chris_styles@yahoo.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();mail($to, $subject, $message, $headers);
?>
The first test is to call it by typing in the the URL of the script directly into IE, and see what happens...
IE seems to load the page and complete silently (I should have put some debug in there). Behold, 60 seconds later :
Right, that seems to work a treat. Can I trigger one from my mbed now. Moment of truth, I have to compile and download the code. Oh, and run a teraterm so I can see the mbed fetch it's IP address.
Phut, nothing, not even an IP address. I download Rolfs example program, run it, and teraterm happily reports 192.168.0.36.
So I try a program that is simpler :
#include "mbed.h" #include "HTTPClient.h" DigitalOut led(LED1); HTTPClient http; int main(void) { char result[64]; http.get("http://mbed.comxa.com/tree.php", result); printf("Done!\n"); while(1) { led = !led; wait(0.5); } }
This works like a charm :
After 30 seconds I get an email. Yay!
So why didn't it work with the ticker i wonder?
I'll remove the ticker and strip my code back a bit. Start simple.
#include "mbed.h" #include "HTTPClient.h" DigitalIn sensor(p20); DigitalOut led (LED1); HTTPClient http; int main() { sensor.mode(PullDown); while (1) { // while the water is deep enough, wait while(sensor) { } led = !led; char result[64]; http.get("http://mbed.comxa.com/tree.php", result); // crude debounce wait (30); // while water remains low, wait while (!sensor) { } // crude debounce wait (30); } }
That works great!
But what if i'm not picking up email? Surely there is some other method :)
Experiment 4
For this experiment I paid a visit to http://www.txtlocal.co.uk and registered and account. They have very nice APIs which allows you to send and receive SMS messages in all sorts of ways, the one that is of interest is via PHP script.
For more details have a look here:
http://www.txtlocal.co.uk/api/#code
For now, I intend to tweek thier script slightly, upload it to my 000webhost account, so that calls to http://mbed.comxa.com/tree.php will cause an SMS to be sent to me.
Using the txtlocal code as and example, I add my authentication details, customise my message and add my cell number :
<?php
// Authorisation details
$uname = "";
$pword = "";// Configuration variables
$info = "1";
$test = "0";// Data for text message
$from = "Xmas Tree";
$selectednums = "447957363xxx"; // my cell number
$message = "I'm your tree - I need water please!";
$message = urlencode($message);// Prepare data for POST request
$data = "uname=".$uname."&pword=".$pword."&message=".$message."&from=". $from."&selectednums=".$selectednums."&info=".$info."&test=".$test; // Send the POST request with cURL
$ch = curl_init('http://www.txtlocal.com/sendsmspost.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch); //This is the result from Txtlocal
curl_close($ch);
?>
As always, the first and best test is to call the script directly from IE. I do this and get :
Cant argue with that!
Last job before it all gets deployed under the tree is to fuse email and SMS code so I get both. I'll test it from IE first - and yes, I'll rename stuff so no one can send me loads of emails and SMS :-)
Done.
It is all happily installed under the tree, powered, with network connection thanks to the Netgear XE103 homeplug.
All that remains to be seen now is when the first trigger happens. It is 00:55 GMT, so i'll see what my inbox and cellphone has for me tomorrow morning ;-)
'Night.
To do..
- Add some cool video clips
- Figure why I got nothing when the HTTP call ran in a ticker
8 comments
You need to log in to post a comment
Nice one! My upgrade would be to add a windscreen washer pump and jerrycan. I guess that would need a second waterlevel sensor to alert you to fill up the reserve tank...