Garden sensors: crow's nest chicken coop thermometer

Clockwise from top: Fonera, Mess of cat5 cable, Arduino

The chicken sensor is in full operation.

It's a yogurt container filled to the brim with:

  • an Arduino Duemilanove
  • an ethernet shield
  • a Fonera 2100 running OpenWRT/olsrd
  • ...and a 10k thermistor sticking out the side

I was so proud when I had my little prototype all put together... but then I did a test run with the USB unplugged and, lo and behold, nothing worked.  After a solid hour or two of sifting through the internet, I found this gem-of-a-page at Pachube!  This was doubly lucky:  first off, the pachube crew concisely explained the problem I'd run into and secondly, I'd forgotten about pachube's web service... and I promptly rewrote my code to use it instead of my janky homemade web API.  Pachube's site is totally awesome... what a great showcase for Drupal as a web application framework.  I love purl.

lead-flavored yogurt mmmm!So in the end, I re-programed the Arduino with a special bootloader customiezd by Ladyada.  I've gotta say, this was a very steep learning curve for me.  I didn't really catch on at first that, after programming the new bootloader, the Arduino wouldn't work with the default IDE:  to trigger the bootloader, you have to send a special message over the serial line.  I did this with a little python script written by Johannes Hoff.

Another issue:  I tried to figure out the arduino IDE toolchain, but wasn't able to.  So I ended up compiling from within the IDE and uploading the created hexfile manually, via this command:

pulsedtr.py /dev/ttyUSB0 && /usr/bin/avrdude -V -F -p m328p -P /dev/ttyUSB0 -c avrisp -b 19200 -U flash:w:Pachube_client.cpp.hex
This worked like a charm. Also worth noting: the sample code posted on the Pachube page I linked above is a bit out-of-date.  I modified it to, among other things, only post once per minute and use the v2 API:
  
diff --git a/Pachube_client.pde b/Pachube_client.pde  
index 1f7bd1c..d3da9bc 100644  
--- a/Pachube_client.pde
+++ b/Pachube_client.pde
@@ -30,9 +30,7 @@ byte mac[] = {
   0xDA, 0xAD, 0xCA, 0xEF, 0xFE,  byte(ID) };


-byte server [] = {  //www.pachube.com
-  209, 40, 205, 190
-};
+byte server [] = { 173, 203, 98, 29 };

 boolean ipAcquired = false;
@@ -100,7 +92,7 @@ void loop(){
   //main function is here, at the moment it will only connect to pachube every 10 sec
   if ((millis() - previousEthernetMillis) > ethernetInterval) {
     previousEthernetMillis = millis();
-    ethernetInterval = 10000; //10 sec
+    ethernetInterval = 60000; //10 sec
     wdt_reset();
     Serial.println("wdt reset");
     updateLocalSensor();
diff --git a/functions.pde b/functions.pde  
index 3b559bd..329aba8 100644  
--- a/functions.pde
+++ b/functions.pde
@@ -33,38 +82,35 @@ void useEthernet(){
   if (client.connect()) {

     Serial.println("connected");
-    int content_length = length(analog1) + length(analog2) + length(analog3) + 2 ; 
-    //this line is to count the lenght of the content = lenght of each local sensor data + ","
-    //in this case we have 3 data so we will need 2 commas 
+    int content_length = length(analog1); 

-    client.print("GET /api/feeds/");
+    client.print("GET /v2/feeds/");
     client.print(REMOTEFEED);
     client.println(".csv HTTP/1.1");
-    client.println("Host: www.pachube.com");
+    client.println("Host: api.pachube.com");
     client.print("X-PachubeApiKey: ");
     client.println(APIKEY);
-    client.println("User-Agent: Arduino (Natural Fuse v`1.1)");
+    client.println("User-Agent: Arduinonioni");
     client.println();

-    client.print("PUT /api/feeds/");
+    client.print("PUT /v2/feeds/");
+    client.print(REMOTEFEED);
+    client.print("/datastreams/");
     client.print(LOCALFEED);
     client.println(".csv HTTP/1.1");
-    client.println("Host: www.pachube.com");
+    client.println("Host: api.pachube.com");
     client.print("X-PachubeApiKey: ");
     client.println(APIKEY);

-    client.println("User-Agent: Arduino (Natural Fuse v1.1)");
+    client.println("User-Agent: Arduinonioni");
     client.print("Content-Type: text/csvnContent-Length: ");
     client.println(content_length);
     client.println("Connection: close");
     client.println();

And finally, some less-geeky perspective:  This device is indeed serving a purpose as a temperature sensor for my chicken coop, but mostly I'm using it as a learning platform to experiment with outdoor sensors.  I'll eventually be deploying similar sensors in hoop-houses to help my farmer friends monitor efficiency and better plan their growing.

I forgot one other thing:  there was a third benefit to stumbling upon Pachube:  I found another garden sensor experimentor!!!  They really had it figured out, and it drastically shifted my plans.  See their sensor system here: http://www.pachube.com/feeds/12401 with photos here:http://picasaweb.google.com/ryanferreri/HoopHouses#.  I'd never heard of the JeeNode equipment before, and it seems to be absolutely perfect for low-cost wireless sensors... and they're so nice and skinny... could just stick em right in some PVC pipe... oh the possibilities!  The U.S. JeeNodes transmit in the 900ish-MHZ spectrum.  I can't wait to set up a test system... the rough plan would be a network of a few JeeNodes, each placed on the edge of a hoop house with one sensor inside and one outside.  They would transmit back to a wifi router that would serve as the web uplink.  I have to find a low-power wifi router with an on-board USB chip...

But for now, my only sensor resides in that chicken coop.  Future plans: a relay switch for the coop's light, for remote control / timer capabilities.  Gotta maximize that layer productivity.