Automated plant watering with Arduino

Hardware Design

These two control concepts of time and temperature, under new communication protocols, will be the basis of the examples I'll describe in this article. The first example is based on watering, controlled in real time, for which the RTC is used as well. For this, you'll need an irrigation system that you can activate at a determined hour.

Here I use a small, submersible pump [5] (Figure 3), controllable by a digital pin. However, you could use a different pump, such as one you already have installed in your house. You'll just need to know its operating voltage and perhaps review the concepts of controlling a relay.

Figure 3: The submersible pump used in the watering system.

To begin, connect the system as shown in Figure 4. That is, connect the pump to digital pin 13 and to ground, and connect the RTC to 5V, GND, and analog pins 4 (SDL) and 5 (SDA).

Figure 4: Example assemblage for watering at a specific time.

For the second example (Listing 2), I'll use the soil humidity sensor [6] shown in Figure 5, as well as the temperature sensor. This sensor works as a resistive analog sensor. Depending on the humidity, it gives values of 0 to 1023, with 500 being humid soil, 100 dry soil, and 1000 saturated soil.

Figure 5: Soil humidity sensor used in the second assembly.

Listing 2

Real-Time Control of Watering

001 // Include the Wire library to work with I2C
002 #include "Wire.h"
003 // I2C bus address
004 #define DS1307_I2C_ADDRESS 0x68
005
006 // Static variables
007 // Declare time variables
008 byte second, minute, hour, weekDay, monthDay, month, year;
009
010 // Declare the ledPin as a variable
011 int wateringSystem = 13;
012
013 // Function to convert normal decimal number to numbers 0-9 (BCD)
014 byte decBcd(byte val) {
015   return ( (val/10*16) + (val%10) );
016 }
017
018 // Function to convert numbers 0-9 (BCD) to normal decimal number
019 byte bcdDec(byte val) {
020   return ( (val/16*10) + (val%16) );
021 }
022
023 // Function to set the system clock
024 void configureTime() {
025    // 1) Set the date and time values
026    second       = 00;
027    minute       = 25;
028    hour         = 13;
029    weekDay      = 1;
030    monthDay     = 29;
031    month        = 10;
032    year         = 12;
033
034    // 2) Commands to start up the clock
035    Wire.beginTransmission(DS1307_I2C_ADDRESS);
036    Wire.write(0x00);
037    Wire.write(decBcd(second));
038    Wire.write(decBcd(minute));
039    Wire.write(decBcd(hour));
040    Wire.write(decBcd(weekDay));
041    Wire.write(decBcd(monthDay));
042    Wire.write(decBcd(month));
043    Wire.write(decBcd(year));
044    Wire.endTransmission();
045 }
046
047 // Function to call up the system time
048 void requestTime()
049 {
050   // Reset the pointer to the register
051   Wire.beginTransmission(DS1307_I2C_ADDRESS);
052   Wire.write(0x00);
053   Wire.endTransmission();
054
055   // Call up the time and date
056   Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
057   second        = bcdDec(Wire.read() & 0x7f);
058   minute        = bcdDec(Wire.read());
059   hour          = bcdDec(Wire.read() & 0x3f);
060   weekDay       = bcdDec(Wire.read());
061   monthDay      = bcdDec(Wire.read());
062   month         = bcdDec(Wire.read());
063   year          = bcdDec(Wire.read());
064
065   // Print the date and time via serial monitor
066   Serial.print(hour, DEC);
067   Serial.print(":");
068   Serial.print(minute, DEC);
069   Serial.print(":");
070   Serial.print(second, DEC);
071   Serial.print("  ");
072   Serial.print(monthDay, DEC);
073   Serial.print("/");
074   Serial.print(month, DEC);
075   Serial.print("/");
076   Serial.print(year, DEC);
077   Serial.print("  ");
078 }
079 void setup() {
080   // Initialize the I2C
081   Wire.begin();
082   // Initialize the serial port
083   Serial.begin(57600);
084   // Initialize the LED pin as an output
085   pinMode(wateringSystem, OUTPUT);
086   digitalWrite(wateringSystem, LOW);
087
088   // Set the time: ONLY THE FIRST TIME YOU RUN THE CODE!!
089   configureTime();
090 }
091
092 void loop() {
093   // Small time delay:
094   delay(2000);
095   // Read the time and date every 2 seconds
096   requestTime();
097   Serial.println(" ");
098
099   // Based on the exact time
100   if (hour == 13) {
101     if (minute == 40) {
102       // Turn on the watering system for the plants
103       Serial.println("13:40 --> Time to water the plants");
104       digitalWrite(wateringSystem, HIGH);
105     }
106   }
107
108 }

Placing these sensors in your garden won't be much of a problem because the temperature sensor comes in probe form, so you only have to do is bury it in the soil. The humidity sensor is a U-shaped device that you can stick in the soil near the plant (Figure  6).

Figure 6: Soil humidity sensor taking a reading.

For notification of when these values become dangerous, I'll use the GPRS (general packet radio service) module [7] (Figure 7). The assembly with everything connected looks similar to that shown in Figure 8.

Figure 7: Schematic of the monitoring system of a plant's status.
Figure 8: Example assembly for monitoring a plant's status.

Programming

The programming for these examples is going to be rather brief because of the use of pre-defined libraries and because the codes encountered are verbosely commented. However, I will highlight and clarify several coding functions and concepts.

In the first example, I defined two functions with which to communicate with the RTC. The first is used to set the clock of the device and the second to call up the time. As might be expected, the clock time needs to be set only once; otherwise, each time the code is executed, it would reset the time. Therefore, after the first time you run the program, you need to comment out the time reset function:

// configureTime():

The rest of the code only serves to call up the time and compare it with the time established in the program; when these values coincide, the watering system is activated. The result of this first assembly can be seen in Figure 9.

Figure 9: Series of monitor views of the date and time until the watering system is activated.

The second example doesn't really need further clarification, because I'm only measuring the values of the two sensors, and the system will make a call when the values get to a specified range.

The result shows something rather peculiar: Your plants are calling you on the phone to let you know that they need to be watered.

Buy this article as PDF

Express-Checkout as PDF

Pages: 6

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content