Project tutorial
Water Plant System for Plants in Vases

Water Plant System for Plants in Vases © GPL3+

Create an automation to water plants in vases. It requires some Arduino skills but also some manual dexterity.

  • 8,476 views
  • 4 comments
  • 16 respects

Components and supplies

A000066 iso both
Arduino UNO & Genuino UNO
×1
20120702130508859
DHT11 Temperature & Humidity Sensor (4 pins)
×1
moisture sensore
×1
sd card logger and RTC
×1
09590 01
LED (generic)
×1
plastic water solenoid valve
×1
Fairchild semiconductor 2n7000. image
Logic Level FET N-Channel
×1
Fairchild semiconductor bzx79c3v6 image
3.6V 0.5W Zener Diode
×1
battery packace 5v ( >= 4000mA )
×1
battery packace 12v ( >= 5000mA )
×1
push button
×1
Mfr 25frf52 100k sml
Resistor 100k ohm
×1
20L water container
×1

Necessary tools and machines

teflon tape
cutter
small saw
Hy gluegun
Hot glue gun (generic)

Apps and online services

About this project

Purpose

The purpose of this project is to create a system to water my plants while I am on holidays in vacation. I do not have a garden, but just few plants in a vase. Most of the projects I’ve seen are for watering plants in a garden, so they do not fit in my situation.

Moreover, I do not have water pipe on my balcony so I had to find a different solution. In all this, I also like to have some statistics and so I added an SD logger board.

Description

I’ve thought to implement it using an Arduino UNO board and few other sensors and components.

It should work in this way: if the humidity of the most needing plant is under a certain level, Arduino opens the valve to water the plants. But what happens if too much water arrives in the least needing plants? It never happened; you will discover why!

To moderate the quantity of water, I created more or less tiny holes in the tube that goes in the plants. More holes, more water. However, to realize it, I had to cut and glue some components like a potato salad’s box, some tunes, and some woods sticks.

The detailed instructions can be seen here as .odt file:

https://github.com/zioalex/Arduino/blob/master/Water_plants_system/Project_details.odt

or like .pdf version:

https://github.com/zioalex/Arduino/blob/master/Water_plants_system/Project_details.pdf

Code

humidity_temperature_log.inoArduino
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// RTC PART
#include <Wire.h>
#include "RTClib.h"

#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
   #define Serial SerialUSB
#endif

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

DateTime now;

// DHT11
#include <dht11.h>  	// import DHT11 libray
dht11 DHT;   					// class declaration
#define DHT11_PIN 11  // Define a constant to use as DHT pin

// For some weird reason it doesn't work if PIN is 11!!!

String readString;

// SD CARD
#include <SPI.h>
#include <SD.h>

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 							// mills between entries (reduce to take more/faster data)
#define SYNC_INTERVAL 600*LOG_INTERVAL 	// mills between calls to flush() - to write data to the card

// how many probes to check the humidity?
#define PROBE_NUMBERS 5
// Define how many millis between next soil humidity check - 6 hour
#define HUMIDITY_CHECK_INTERVAL 21600000 // 6 hour // 60000 // 1 hour // 5000 // 5 sec // 30000 // 30s // 

// Maximum time for the Open Valve - 60s
#define MAX_OPEN_VALVE 300000 // 5 min // 60000 // 60 sec // 300000 // 5 min // 

// Interval between Soil humidity check
#define SOIL_HUMIDITY_INTERVAL 60000 // 10 sec

// Himudity Low limit
#define SOIL_HUMIDITY_LOW_LIMIT 400

// Himudity High limit
#define SOIL_HUMIDITY_HIGH_LIMIT 550

uint32_t syncTime = 0; // time of last sync()

// the digital pins that connect to the LEDs
#define redLEDpin 13

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

// YL-39 + YL-69 humidity sensor
byte humidity_sensor_pin = A1;
byte humidity_sensor_vcc = 6;
int moisture_humidity;

// Solenoid Valve
int ValvePin = 4;                	// Solenoid valve connected to pin 4
int SwPin = 12;
int buttonWas = 0; 								// The state of the switch (pushed = 1, not pushed = 0) last time we looked
int buttonIs = 0; 								// Current state of the switch
int val = 0;

// ECHO_TO_SERIAL 0 - no serial debug / 1 - serial debug
#define ECHO_TO_SERIAL 0

void setup () {
// Setup RTC  
Serial.begin(57600);
Serial.println("Setup STarted");

#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif 														//WAIT_TO_START

#ifndef ESP8266
  while (!Serial); 								// for Leonardo/Micro/Zero
#endif

  // Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (30);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
  
  // SETUP ERROR
  
  pinMode(redLEDpin, OUTPUT);
  // DHT11
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  Serial.println("Humidity (%),\tTemperature (C),\tTemp (Analogica)");
  Serial.println();
  pinMode(DHT11_PIN, OUTPUT);
  
    // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  else { Serial.println("card initialized."); }
  
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);
 
   logfile.println("stamp,datetime,humidity,temp,soil_humidity");    
  //if ECHO_TO_SERIAL
    Serial.println("stamp,datetime,humidity,temp,soil_humidity");
  //endif //ECHO_TO_SERIAL

  // Init the humidity sensor board
  pinMode(humidity_sensor_vcc, OUTPUT);
  digitalWrite(humidity_sensor_vcc, LOW);
  
  // Valve setup
  pinMode(ValvePin, OUTPUT);      					// sets the digital pin as output
  pinMode(SwPin, INPUT);
  buttonIs = digitalRead(SwPin); 						// Read the initial state of the switch!
  
  // Setup OVER
  Serial.println("Setup finished");
  
}
 
void loop () {
  //closeValve();
  //temphumi();
  
  //DateTime now;
  
  float moisture_humidity_avg = 0;
  
  // Moisture sensor calibration
  for ( uint8_t i=0 ; i<PROBE_NUMBERS ; i++) {
    // log milliseconds since starting
    uint32_t m = millis();
    
    // logfile.print(m);           				// milliseconds since start
    // logfile.print(", ");    
    #if ECHO_TO_SERIAL 
      Serial.print(m);         						// milliseconds since start
      Serial.print(", ");  
    #endif
    
    rtcnow();
    
    //blink();
    //error("test");
    //temphumi();
    moisture_humidity = read_humidity_sensor();
    
    #if ECHO_TO_SERIAL
      Serial.print("Soil Humidity Level (0-1023): ");
      Serial.println(moisture_humidity); 
    #endif
    
    // delay for the amount of time we want between readings
    delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
  }
  
  // log time
    logfile.print(now.unixtime()); 				// seconds since 1/1/1970
    logfile.print(", ");
    logfile.print('"');
    logfile.print(now.year(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.day(), DEC);
    logfile.print(" ");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print(":");
    logfile.print(now.second(), DEC);
    logfile.print('"');
    logfile.print(", ");
    logfile.print(DHT.humidity, 1);
    logfile.print(", ");
    logfile.print(DHT.temperature, 1);
    logfile.print(", ");
    logfile.print(moisture_humidity); logfile.print("\n");
 
  // Log to serial
    #if ECHO_TO_SERIAL
      Serial.print(now.unixtime()); 					// seconds since 1/1/1970
      Serial.print(", ");
      Serial.print('"');
      Serial.print(now.year(), DEC);
      Serial.print("/");
      Serial.print(now.month(), DEC);
      Serial.print("/");
      Serial.print(now.day(), DEC);
      Serial.print(" ");
      Serial.print(now.hour(), DEC);
      Serial.print(":");
      Serial.print(now.minute(), DEC);
      Serial.print(":");
      Serial.print(now.second(), DEC);
      Serial.print('"');
      Serial.print(", ");
      Serial.print(DHT.humidity, 1);
      Serial.print(", ");
      Serial.print(DHT.temperature, 1);
      Serial.print(", ");
      Serial.print(moisture_humidity); Serial.print("\n");
    #endif
    
  if ( moisture_humidity < SOIL_HUMIDITY_LOW_LIMIT ) {
    #if ECHO_TO_SERIAL
      Serial.println("Valve Open");
    #endif
    
    logfile.print("Valve Open\n");
    openValve();  
  
  uint32_t opentime = 0;
  // Initialize the button
  getButton();
  
  while ( (moisture_humidity < SOIL_HUMIDITY_HIGH_LIMIT) || ((buttonIs==1)&&(buttonWas==0)) )  {
    if ( opentime <= MAX_OPEN_VALVE ) {
      moisture_humidity = read_humidity_sensor();
      // log time
      logfile.print(now.unixtime()); 					// seconds since 1/1/1970
      logfile.print(", ");
      logfile.print('"');
      logfile.print(now.year(), DEC);
      logfile.print("/");
      logfile.print(now.month(), DEC);
      logfile.print("/");
      logfile.print(now.day(), DEC);
      logfile.print(" ");
      logfile.print(now.hour(), DEC);
      logfile.print(":");
      logfile.print(now.minute(), DEC);
      logfile.print(":");
      logfile.print(now.second(), DEC);
      logfile.print('"');
      logfile.print(", ");
      logfile.print(DHT.humidity, 1);
      logfile.print(", ");
      logfile.print(DHT.temperature, 1);
      logfile.print(", ");
      logfile.print(moisture_humidity); logfile.print("\n");
      #if ECHO_TO_SERIAL
        Serial.print(moisture_humidity); Serial.print(" ");
      #endif  
      // To reduce the checks in every interval
      delay(round(MAX_OPEN_VALVE/2));
      opentime = opentime + round(MAX_OPEN_VALVE/2);
      
    } else { 
        #if ECHO_TO_SERIAL
          Serial.println("\nTime limit reached");
          Serial.println("Close Valve"); 
        #endif
        logfile.print("Time limit reached\n");
        logfile.print("Valve Open\n");
        closeValve();
        break; }
    }
  // Never arrive here after the break!.
  Serial.println("Close Valve");
  closeValve();
  logfile.print("Valve Open\n");
  }
  // Delay of HUMIDITY_CHECK_INTERVAL
  delay(HUMIDITY_CHECK_INTERVAL);
  
  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
  
  // blink LED to show we are syncing data to the card & updating FAT!
  digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  Serial.println("LogFile flushed");
  digitalWrite(redLEDpin, LOW);
}
dht11.inoArduino
void temphumi() {
  long chk;
  chk = DHT.read(DHT11_PIN);

  //long sensorValue = analogRead(A1);
  //long tempCelsius = sensorValue*0.5;
  //while (!Serial.available()) {} // wait for data to arrive
  // serial read section
  while (Serial.available())
  {
    delay(10);  //delay to allow buffer to fill
    if (Serial.available() > 0)
    {
      readString = "";
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() > 0)
  {
    Serial.print("Arduino received: ");
    Serial.println(readString); //see what was received
  }

  switch (chk){
    case DHTLIB_OK:  
                Serial.print("OK,\t"); 
                break;
    case DHTLIB_ERROR_CHECKSUM: 
                Serial.print("Checksum error,\t"); 
                break;
    case DHTLIB_ERROR_TIMEOUT: 
                Serial.print("Time out error,\t"); 
                break;
    default: 
                Serial.print("Unknown error,\t"); 
                break;
  }
  
  //delay(500);
  #if ECHO_TO_SERIAL
    Serial.print("DHT11 DEBUG\n");
    Serial.print(DHT.humidity, 1); Serial.print(",");
    Serial.print(DHT.temperature, 1); Serial.print("\n");
    Serial.flush();
  #endif
  //if(Serial.available()){ // only send data back if data has been sent

  //}

  //Serial.println(tempCelsius,DEC);   // temperatura del sensore LM335

  //delay(1000);
}
rtc.inoArduino
void rtcnow () {    
    now = rtc.now();
    #if ECHO_TO_SERIAL    
      Serial.print(now.year(), DEC);
      Serial.print('/');
      Serial.print(now.month(), DEC);
      Serial.print('/');
      Serial.print(now.day(), DEC);
      Serial.print(" ( ");
      Serial.print(now.dayOfTheWeek(), DEC);
      Serial.print("  ");
      Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
      Serial.print(") ");
      Serial.print(now.hour(), DEC);
      Serial.print(':');
      Serial.print(now.minute(), DEC);
      Serial.print(':');
      Serial.print(now.second(), DEC);
      Serial.println();
      
      Serial.print(" since midnight 1/1/1970 = ");
      Serial.print(now.unixtime());
      Serial.print("s = ");
      Serial.print(now.unixtime() / 86400L);
      Serial.println("d");
    #endif
    
    // calculate a date which is 7 days and 30 seconds into the future
    // DateTime future (now + TimeSpan(7,12,30,6));
    
    // #if ECHO_TO_SERIAL
    //   Serial.print(" now + 7d + 30s: ");
    //   Serial.print(future.year(), DEC);
    //   Serial.print('/');
    //   Serial.print(future.month(), DEC);
    //   Serial.print('/');
    //   Serial.print(future.day(), DEC);
    //   Serial.print(' ');
    //   Serial.print(future.hour(), DEC);
    //   Serial.print(':');
    //   Serial.print(future.minute(), DEC);
    //   Serial.print(':');
    //   Serial.print(future.second(), DEC);
    //   Serial.println();
    //   
    //   Serial.println();
    // #endif
    delay(1000);
}
Moisture_sensor.inoArduino
// Read from Moisture senson function
int read_humidity_sensor() {
  digitalWrite(humidity_sensor_vcc, HIGH);
  delay(500);
  int value = analogRead(humidity_sensor_pin);
  digitalWrite(humidity_sensor_vcc, LOW);
  #if ECHO_TO_SERIAL
    Serial.print(value); Serial.print("\n");
  #endif
  return 1023 - value;
  
}
valve.inoArduino
//===========Functions=====================//
void getButton() { 
  buttonWas = buttonIs; // Set the old state of the button to be the current state since we're creating a new current state.
  buttonIs = digitalRead(SwPin); // Read the button state
} 

void openValve(){
    digitalWrite(ValvePin, HIGH);
    digitalWrite(redLEDpin,HIGH);
    Serial.println("Valve Open");
}

void closeValve(){
  digitalWrite(ValvePin, LOW);
  digitalWrite(redLEDpin,LOW);
  Serial.println("Valve closed");
}
error.inoArduino
void error(char *str) {
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second

  //while(1);  
}

Schematics

Main schema
plant_watering_system_9r1Fe6ffv4.fzz
Git repo with all the info
This git repo contains all the info and picture relative to this project.

Comments

Similar projects you might like

Automatic Plant Watering System with Arduino

Project tutorial by Team RobotGeek Projects Team

  • 44,445 views
  • 4 comments
  • 81 respects

Smart Plant Monitoring with SMS Alert: Keep Plants Hydrated!

Project tutorial by Rohan Jadhav

  • 1,831 views
  • 2 comments
  • 4 respects

Windows 10 IoT Plant Monitoring System

Project tutorial by Team BME-AUT

  • 16,713 views
  • 5 comments
  • 66 respects

Plant watering alarm system with arduino

Project tutorial by Giannis Arvanitakis

  • 6,602 views
  • 1 comment
  • 12 respects

Water Quality Monitoring and Notification System

Project showcase by emmanuel ani

  • 74,230 views
  • 50 comments
  • 168 respects

Herb Box Eco System

Project tutorial by Walter Heger

  • 53,808 views
  • 40 comments
  • 300 respects
Add projectSign up / Login