SMART WATERING

QUICK PROJECT DESCRIPTION
  • PROJECT OBJECTIVE: Build an automated watering system for your garden that decides, based on soil humidity, temperature and time, when to water your plants.
  • HARDWARE REQUIREMENTS: Provided in the Mango Labs Mechatronics Maker Kit: Arduino-compatible board, USB cable, RTC module, SSR module, temperature sensor, RGB LED module, 2 x 10K resistors, 16 male to male jumper cables, 2 male to female jumper cables, mini breadboard, 12v power supply.
    Additional hardware: computer, electrovalve (I used a washing machine valve that is easy to find), 2 male plugs, 1 female plug, glue gun, 2 galvanized nails, thin solid core wire (stripped telephone or network cable), 16 AWG cable (length will depend on your installation. Vulcanized/outdoor cable or terminals would work fine), CR2032 coin battery, small star screwdriver, pliers/crimper.
  • SOFTWARE REQUIREMENTS: Arduino environment (or online editor). Download the RTC library here. Unzip and paste the folder in the Arduino libraries folder. It’s in the same location as your default sketches. You can look it up under File/Preferences Sketchbook location.
  • KNOW-HOW REQUIREMENTS: Basic Arduino environment knowledge (learn more here). Basic electrical skills.
QUICK OVERVIEW
  1. Connect everything as shown in the diagram.
  2. Install the RTC library (if you tested the board with the Hello World example you have the library already installed).
  3. Compile and upload the sketch to your board.
  4. Attention: As you are using high voltage, please be very careful and check that you don’t have any exposed leads or any shorts before plugging to mains. Don’t power the Arduino-compatible board from the USB port of your computer.
  5. To be safe, screw the solid state relay board to a non-conductive board together with the outlet. (You can also stick or screw the breadboard and screw the Arduino Uno-compatible board to the same board.)
  6. Connect one pole of the outlet to the SSR board and from the SSR board to your plug, and the other pole of your outlet directly to the other pole of the plug.
    Don’t strip more insulation than needed for the SSR board. You only need to strip 5 mm. Insert the entire exposed end into the screw terminal. Tighten the screws. Check that there aren’t any conductors exposed. For the outlet, you will probably need to strip a little more insulation. This will depend on the outlet you are using, but around 10 mm should be fine. Check that your cables are properly inserted and tightly screwed into the outlet before closing it.
  7. Wire the nails and stick them into the ground approximately 2.5cm apart.
  8. Wire the electrovalve and connect the male plug.
  9. Connect the electrovalve to your water supply/spout. If you are using a washing machine electrovalve you can use a regular washing machine hose (mine is 3/4″). Connect a hose to the output (I heated my hose a little to make it fit).
  10. Power your Arduino Uno-compatible board with an external power supply.
  11. Plug the electrovalve into your SSR-controlled outlet.
  12. The LED should blink white three times and repeat every six minutes. If the soil is moist, the LED will stay green. It will change to yellow if it is somewhat dry, and to red if it’s very dry.
PIN OUT DIAGRAM
1
2
3
4
5
6
7
8
9
10
1

Plug to mains. Be very careful! Plug last!

2

Elctrovalve plug to solid state relay female plug.

3

Electrovalve / Solenoid

4

Solid state relay.
White control cable (CH1) goes to digital in 3
on the Arduino compatible board.

5

Galvanized nails measure soil resistance/moisture.
One is connected to 5 volts the other to analog 0 (A0)
and trough a 10k resistor to ground.

6

RGB LED.
Ground (-) is connected to ground.
Red to digital 9, green to digital 10
and blue to digital 11.

7

Real time clock module.
SDA is connected to analog 4 (A4) and
and SCL to analog 5 (A5).

8

Temperature sensor, thermistor.
One end is connected to ground the other end
to analog 1 (A1) and through a 10k resistor to
5 volts.

9

10k resistor for soil moisture sensor.

10

10k resistor for thermistor.

SETUP

The crucial part for this project is the solenoid valve / electrovalve. I have found out that washing machine valves are that the easiest to source and to set up.

It doesn’t matter what model you get. What is important is to check if it will be easy for you to connect it to your water supply. Washing machine electrovalves come with a threaded inlet side where you connect it to your supply with a standard washing machine hose, which has the same threading and size as most garden spouts. So that should make things easier.

Once you have your electrovalve you have to attach some cables to it. Choose cable that is long enough to enable you to place your electronics at safe distance from the water. If you have a soldering gun, you can solder the cable to the terminals. For insulating the terminals I recommend shrink-wrap tubing.

If you don’t want to solder you can also crimp a terminal and connect it to the electrovalve. I suggest shrink-wrapping the whole terminal.

At the other end of the cable you have two choices. You can connect one lead to the solid state relay and go from there to your plug and connect the other lead of the electrovalve to the plug. Take care to strip only a small amount of insulation from the cables you are connecting to the relay board.

Otherwise, I would recommend connecting a male plug to the electrovalve and a female one to the SSR module and screw them both to a board (as on the Bluetooth-controlled slow cooker Lab Idea).

For your soil humidity sensor you need two galvanized nails 4 inches or more. At the top you have to wrap some copper cable to connect it to your Arduino-compatible board. Solid core cable works better; if you are placing your electronics some distance away from your garden and water (which would make sense) you could use solid core telephone cable. Strip a good length of insulation away from your wire.

Coil it a couple of times around your nails and twist it to secure it.

You should insert them in the soil 2.5 cm apart.

Follow the diagram to wire the circuit and take special care in checking that all the wiring that goes to mains is OK. Upload the sketch from here or copy the code below to your Arduino-compatible board. Time will automatically be set on the RTC board so be sure to have the coin battery already installed; this way, it won’t reset when you unplug it. Unplug the USB and plug the power supply to your Arduino-compatible board to perform a last check.
It’s a good idea to protect your electronics from water. A fast and cheap way to do it is to put everything in a plastic container.

Connect your electrovalve to your water supply. Using a washing machine hose worked for me.

You could also use a hose clamp and a regular hose.

I connected the other end of the washing machine hose to the bronze coupling of my garden hose (in order to extend the range) and added a packing to get a tight fit.

Pin your nails in the garden, plug the12v power supply to your Arduino-compatible board, plug your electrovalve to the SSR controlled female plug, plug your SSR to mains and you should be done.

The system checks for normal conditions for every sensor at startup and will light the LED red if something is wrong (it will also send a message through the serial port indicating if there’s a problem in a specific sensor). Every six minutes it will check the input variables (and blink white) to decide if watering is needed.

Have fun!

CODE
</pre>
/*
by Dr Mangus for Mango Labs

inspired by
Grady Hillhouse (March 2015) project
*/

#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

#define LOG_INTERVAL 360000 //milliseconds between entries (6 minutes = 360000)
// I/O declarations
#define THERMISTORPIN A1
#define soilMoisturePin A0
#define LEDPinRed 9
#define LEDPinGreen 10
#define LEDPinBlue 11
#define ssrPin 3

int wateringTime = 600000; //Set the watering time (10 min for a start)

const float wateringThreshold = 65; //Value in humidity % below which the garden gets watered
// (estimated, based on soil resistivity)

//Thermistor declarations
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 10
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10050

int samples[NUMSAMPLES];

float Temp = 0; //Scaled value of soil temp (degrees C)
float soilMoistureRaw = 0; //Raw analog input of soil moisture sensor (Ain)
float soilMoisture = 0; //Scaled value of volumetric water content in soil (percent)
float humidity = 0; //Relative humidity (%)
int state = 0;
bool watering = false;
bool wateredToday = false;
DateTime now;

void error(char *str)
{
Serial.print("error: ");
Serial.println(str);

// red LED indicates error
digitalWrite(LEDPinRed, HIGH);

while(1);
}

void setup() {

//Initialize serial connection
Serial.begin(9600); //Just for testing


pinMode(LEDPinRed, OUTPUT); //LED red pin
pinMode(LEDPinGreen, OUTPUT); //LED green pin
pinMode(LEDPinBlue, OUTPUT); //LED blue pin
pinMode(ssrPin, OUTPUT); //solenoid pin
digitalWrite(ssrPin, HIGH); //Make sure the valve is off (inverted logic)


//Establish connection with real time clock
Wire.begin();
if (!rtc.begin()) {
error("RTC failed com");
}

//Set the time and date on the real time clock if necessary
if (! rtc.isrunning()) {
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

// Check if thermistor is inside normal range
Temp = readTemp();
delay(20);
if ((Temp > 45) || (Temp < -25)){
error("temp sensor out of range");
}

//Check if humidity sensor is inside normal range
soilMoistureRaw = analogRead(soilMoisturePin);
delay(20);
if ((soilMoistureRaw > 900) || (soilMoistureRaw < 0)){
error("humidity sensor out of range");
}

now = rtc.now();

}

void loop() {

//delay software
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));

//Three white blinks means start of new cycle
setColourRgb(75, 90, 100);
delay(500);
setColourRgb(0, 0, 0);
delay(150);
setColourRgb(75, 90, 100);
delay(150);
setColourRgb(0, 0, 0);
delay(150);
setColourRgb(75, 90, 100);
delay(150);
setColourRgb(0, 0, 0);

//Reset wateredToday variable if it's a new day
if (!(now.day()==rtc.now().day())) {
wateredToday = false;
}

now = rtc.now();

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(", ");

//Collect Variables
Temp = readTemp();
delay(20);

soilMoistureRaw = analogRead(soilMoisturePin);
delay(20);

//Soil Water Content
soilMoisture = map(soilMoistureRaw, 190, 825, 0, 1000);
soilMoisture = soilMoisture/10.0;

Serial.print(Temp);
Serial.print("*C, ");
Serial.print(soilMoisture);
Serial.print("h%, ");

// LED display based on soil humidity
if (soilMoisture > 24 && soilMoisture < 50)
setColourRgb(200, 200, 0); //yellow
else if (soilMoisture < 25)
setColourRgb(255, 0, 0); //red
else
setColourRgb(0, 100, 0);

// watering RULES

//normal conditions
if ((soilMoisture < wateringThreshold) && (now.hour() > 8) && (now.hour() < 11) && (Temp > 4) && (wateredToday = false)) {
//water the garden
digitalWrite(ssrPin, LOW);
Serial.print("Normal watering");
setColourRgb(0, 0, 255); //blue
delay(wateringTime);

digitalWrite(ssrPin, HIGH);
wateredToday = true; //record that we're watering
}
else {
state = 0;
}

//extreme heat
if ((soilMoisture < wateringThreshold) && (now.hour() > 10) && (now.hour() < 19) && (Temp > 27)) {
//water the garden
digitalWrite(ssrPin, LOW);
Serial.print("Extreme heat watering");
setColourRgb(0, 0, 255); //blue
wateringTime = wateringTime / 2; //half the watering time
delay(wateringTime);

digitalWrite(ssrPin, HIGH);
}
else {
state = 0;
}

//extreme dryness
if ((soilMoisture < 15) && (Temp > 10)) {
//water the garden
digitalWrite(ssrPin, LOW);
Serial.print("Extreme dryness watering");
setColourRgb(0, 0, 255); //blue
wateringTime = wateringTime * 1.5; //extend the watering time
delay(wateringTime);

digitalWrite(ssrPin, HIGH);
}
else {
state = 0;
}

//protecting plants against freezing
if ((soilMoisture < wateringThreshold) && (now.hour() > 18) && (now.hour() < 22) && (Temp > 4) && (Temp < 9)) {
//water the garden
digitalWrite(ssrPin, LOW);
Serial.print("Cold protection watering");
setColourRgb(0, 0, 255); //blue
wateringTime = wateringTime / 2; //half the watering time
delay(wateringTime);

digitalWrite(ssrPin, HIGH);
}
else {
state = 0;
}

switch (state) {
case 0:
Serial.print("Not watering");
break;
}

Serial.println();
delay(50);
}

float readTemp(){
uint8_t i;
float average;
// take N samples in a row, with a slight delay
for (i=0; i< NUMSAMPLES; i++) {
samples&#91;i&#93; = analogRead(THERMISTORPIN);
delay(3);
}
// average all the samples out
average = 0;
for (i=0; i< NUMSAMPLES; i++) {
average += samples&#91;i&#93;;
}
average /= NUMSAMPLES;

// convert the value to resistance
average = 1023 / average - 1;
average = SERIESRESISTOR / average;

float steinhart;
steinhart = average / THERMISTORNOMINAL; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro)
steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
steinhart -= 273.15; // convert to C

return steinhart;
}

void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) {
analogWrite(LEDPinRed, red);
analogWrite(LEDPinGreen, green);
analogWrite(LEDPinBlue, blue);
}
<pre>