top of page

Automated Arduino Garden!

IMG_1924_edited.jpg

Check out and follow along my first Arduino based project!

Background

I started this project after a year since I graduated from college and winter coming to New Hampshire. After work activities can be somewhat limited if you're not into outdoor winter activities in the dark.

 

As a stereotypical engineer who can make simple things difficult, I decided to overcomplicate a small indoor hobby garden. For vegetables!! The high-level goal was/is to water the plants when the moisture content gets below a certain threshold and control when a grow light turns on and off. Other than that other cool features will be implemented as the project develops. Hope you enjoy! 

Stage 1: First Lines and Connections

After defining some basic functions and knowing what I wanted the first thing to do was wire up a temperature and humidity sensor. This was intended to be a refresher for wiring up things correctly. From there some quick research and the temperature and humidity were being logged and I was in business. Overall the code was quite simple. All you have to do is Google "DHT 11 sensor" and you too will be on your way.

IMG_2080_edited.jpg
IMG_2087_edited.jpg

Stage 2: Soil Moisture Monitoring

Along with monitoring the ambient temperature and humidity it really isn't (to my knowledge) all that important to growing plants. After a bit of research, I found that controlling soil moisture content is more important. With the integration of soil moisture monitoring, I was able to use the output from the sensor to control a peristaltic pump that turns on once the moisture content goes below a certain threshold.

** One thing to note that the type of sensor I'm using kills plants due to the coating on it or something like that..

Stage 3: LCD Display

LCD display... Nothing serious, but who doesn't want to see what the outputs of their system are. A couple I2C connections or something. All I can really remember is LCD.Set("Something Here") and there is on the screen. I rotate through the time/ Date and soil moisture content. Once again nothing serious.

Stage 4: Relay and Grow Light

As someone who cannot sleep with any lights on the grow lights for sure could not be on during the night. I purchased a UV grow light, cut some wires and screwed it into a relay. The relay is closed circuit during the hours of 6am and 7pm allowing the light to be on and the plants to grow with a little extra sunlight. Also a nice alarm clock enhancement

IMG_2089_edited_edited.jpg

Stage 5: Relay and Pump

I'm sure you've all been wondering monitoring the moisture interfaces with the pump. Simply put the sensor reads a value that is below the moisture content threshold and the pump turns on through the same type of relay as the light, but only a max of twice a day to avoid flooding the apartment. The Cholula Hot Sauce bottle has worked perfectly. Another aspect of the design to note is the silicone tubing is perforated in the grow bed to diffuse the water evenly.

IMG_2085.jpg

Not a fan of the number 6...

Stage 7: And in Business..

Overall a pretty neat project for a beginner if I do say so myself. Up until this point the system has been functioning fine, but it turns out I don't have a green thumb. (Check out the image at the bottom of the page..) Let me know your thoughts below and I appreciate your time reading through this blog. After all, it is the first one! 

IMG_2090.jpg

Results well kinda..

IMG_2088.jpg

Schematic and Code

Circuit_Schematic.JPG

Click on components in the schematic to make purchasing easy!

*Pinouts in the schematic are not consistent with code

// 2020-08-04 Arduino Home Garden Code
// Enjoy

#include <Wire.h>
#include <LiquidCrystal_I2C.h> //Version 1.0.6
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#include <DHT.h>
#include "RTClib.h"
#define DHTPIN 9

float h = 0;
float f = 0;

const int waterpump =  11;
const int ledWater =  11;
const int ledError =  10;
const int lighting = 12;
const int growing = 13;

int water = 0;
int reset = 0;

DateTime now;
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
char dateBuffer[12];
void showTime(void);
void showMeasurments(void);
void waterPlants(void);
void takeMeasurments(void);

RTC_DS3231 rtc;

#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

float dryValue = 677;
float wetValue = 200;
float friendlyDryValue = 0;
float friendlyWetValue = 100;
float friendlyValue;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.init();
  lcd.backlight();
  lcd.clear();
  dht.begin();
  Serial.begin(9600);

  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC Module");
    while (1);
  }

  if (rtc.lostPower())
  {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

  pinMode(waterpump, OUTPUT);
  pinMode(ledWater, OUTPUT);
  pinMode(ledError, OUTPUT);
  pinMode(lighting, OUTPUT);
  pinMode(growing, OUTPUT);
  digitalWrite(growing, HIGH);

  //Print a message to the LCD.
  lcd.print("Starting up");
  delay(500);
  lcd.clear();
  lcd.print("Starting up.");
  delay(500);
  lcd.clear();
  lcd.print("Starting up..");
  delay(500);
  lcd.clear();
  lcd.print("Starting up...");
  delay(2000);
  lcd.clear();

}

void loop() {
  showTime();
  delay (1000);
  showTime();
  delay (1000);
  showTime();
  delay (1000);
  showTime();
  lcd.clear();
  takeMeasurments();
  showMeasurments();

  //Lighting
  if ((now.hour() > 21))
  {
    water = 0;
    digitalWrite(ledWater, LOW);
    digitalWrite(ledError, LOW);
    digitalWrite(growing, LOW);
  }

  if ((now.hour() < 21) && (now.hour() >= 07))
  {
    digitalWrite(lighting, HIGH);
  }
  else
  {
    digitalWrite(lighting, LOW);
  }

  if ((now.hour() < 21) && (now.hour() >= 07) && (water < 2))
  {
    digitalWrite(growing, HIGH);
    digitalWrite(ledError, LOW);
  }
  else
  {
    digitalWrite(growing, LOW);
    digitalWrite(ledError, HIGH);
  }

  //Watering

  if ((friendlyValue < 50))
  {

    if ((now.hour() < 21) && (now.hour() >= 06))
    {

      if ((water >= 2))
      {
        digitalWrite(ledWater, LOW);
      }

      else if ((water < 1))
      {
        lcd.clear();
        lcd.print("Watering...");
        digitalWrite(waterpump, HIGH);
        digitalWrite(ledWater, HIGH);
        delay(6000);
        water = water + 1;
        digitalWrite(waterpump, LOW);
        Serial.print(water);
      }

      else if ((water < 2))
      {
        lcd.clear();
        lcd.print("Watering...");
        lcd.setCursor(0, 1);
        lcd.print("Again...");
        digitalWrite(waterpump, HIGH);
        delay(6000);
        digitalWrite(waterpump, LOW);
        water = water + 1;
        lcd.clear();
      }
    }
  }
}

void showTime()
{
  now = rtc.now();

  lcd.setCursor(1, 0);
  lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);

  lcd.setCursor(5, 0);
  sprintf(dateBuffer, "%02u-%02u-%04u ", now.month(), now.day(), now.year());
  lcd.print(dateBuffer);

  sprintf(dateBuffer, "%02u:%02u:%02u ", now.hour(), now.minute(), now.second());
  lcd.setCursor(4, 1);
  lcd.print(dateBuffer);
}

void showMeasurments()
{
  takeMeasurments();
  lcd.print("Temperature");
  lcd.setCursor(0, 1);
  lcd.print(f, 1);
  delay(2000);
  lcd.clear();

  lcd.print("Humidity");
  lcd.setCursor(0, 1);
  lcd.print(h, 1);
  delay(2000);
  lcd.clear();

  lcd.print("Moisture Content");
  lcd.setCursor(0, 1);
  lcd.print(friendlyValue, 1);
  delay(2000);
  lcd.clear();
}

void takeMeasurments()
{
  int rawValue = analogRead(A0);
  friendlyValue = map(rawValue, dryValue, wetValue, friendlyDryValue, friendlyWetValue);
  h = dht.readHumidity();
  f = dht.readTemperature(true);
}

 

Do you want to stay up to date with projects and posts?

Sign up below!

Thanks for submitting!

bottom of page