16 Jan

Even Plants are Tweeting Nowadays


As part of our display at the Fairmount Water Works, one our plants will now be tweeting when it needs to be watered. (First the teenagers, now the plants?)

This setup uses an Arduino Uno ($25), a WiFi shield ($80), and a Vegetronix VH400 soil moisture sensor ($37). This WiFi shield has an integrated antenna, which allows us to connect to the wifi at the Water Works and send tweets over its network.

We didn’t want our plant to be someone who only talks to you when they need something, so we have a series of different tweets:

  • “Water me please!” when the moisture value falls below 250.
  • “URGENT! Water me!” when the moisture value falls below 150.
  • “Thank you for watering me!” when there is a change in moisture level of at least 100 and the new moisture value is above 250.
  • “You didn’t water me enough!” when there is a change in moisture level of at least 100 and the new moisture value is below 250.
  • “You overwatered me!” when the moisture level climbs to above 400.

One problem we ran into was that Twitter doesn’t allow repeated tweets, as a way to block spam.  Because of this, we had to add more content to our tweets.  In addition to the text, each tweet displays the moisture level and the tweet number (we added a tweet counter in our code).

You can see our plant’s tweets here.

View the code after the jump.

#include <SPI.h> // needed in Arduino 0019 or later
#include <WiFi.h>
#include <Twitter.h>
#define MOIST 250 // minimum level of satisfactory moisture
#define DRY 150 // maximum level of tolerable dryness
#define SOAKED 400 // maximum desired level after watering

int sensorPin = A0;
int sensorValue = 0;
int lastVal = 0;
int change = 0;
int i = 0;
int status = WL_IDLE_STATUS;
char ssid[] = “NETWORKNAME”;
char pass[] = “PASSWORD”;

Twitter twitter(“TWITTERTOKENHERE”); //twitter token

char msg1[140]; //set up each message, limit to 140 characters
char msg2[140];
char msg3[140];
char msg4[140];
char msg5[140];

void setup()
Serial.println(“Attempting to connect to open network…”);
Serial.println(” “);
status = WiFi.begin(ssid, pass);
if ( status != WL_CONNECTED) {
Serial.println(“Couldn’t get a wifi connection”);
// if you are connected:
else {
Serial.print(“Connected to the network”);
// delay(10000);
void loop()
Serial.println(” “);
Serial.print(“The moisture value is “);
sensorValue = analogRead(sensorPin);
change = sensorValue – lastVal;

sprintf(msg1, “(%d) Water me please! (%f)”,i,sensorValue);
sprintf(msg2, “(%d) URGENT! Water me (%f)”,i,sensorValue);
sprintf(msg3, “(%d) Thank you for watering me! (%f)”,i,sensorValue);
sprintf(msg4, “(%d) You didn’t water me enough! (%f)”,i,sensorValue);
sprintf(msg5, “(%d) You over watered me! (%f)”,i,sensorValue);

if ((sensorValue <= MOIST) && (sensorValue >= DRY))
{twitter.post(msg1); } //Water me please!
else if (sensorValue < DRY)
{twitter.post(msg2); } //URGENT! Water me!
else if ((change > 100) && (sensorValue >= MOIST))
{twitter.post(msg3); } //Thank you for watering me!
else if ((change > 100) && (sensorValue <= MOIST))
{twitter.post(msg4); } //You didn’t water me enough!
else if (sensorValue >= SOAKED)
{twitter.post(msg5); } //You over watered me!

lastVal = sensorValue;
i = i + 1;


Leave a Reply

Your email address will not be published. Required fields are marked *