Arduino Automated Plant Water Project
A simple but practical Arduino project to automatically water your plants, showing the usage of a 7-Segment Display, a Soild Moisture Sensor, a Temperature Sensor and a Relay.
Guide
Arduino Automated Plant Watering Project
This is a simple project aimed at those new to the world of Arduino. The aim is to build a complete project using multiple modules. This will hopefully serve as a guide & tutorial for the usage of various modules available at Leobot Electronics (https://leobot.net).
First let us define the goal of the project:
Objective
I want to automate the watering of a plant in a container, gain information on how moist the soil is and what the temperature is where the plant is located.
Next we need to break this objective down into the actual components that will be required.
Automated Plant Watering Components
- A 12V battery (can be any power supply). I am using a 12V lead-acid battery for this project because I intend to add solar panels in the future to recharge the battery and stick to green energy.
- Ardunio Uno R3 -The Arduino will be used to control the logic of the system and act as the computer essentially.
- 7-Segment Display Module - The 7segment display is a convenient way to display various information to the user of the device. It will be used to flash the soil moisture level, temperature and other information while the device is turned on.
- Soil Moisture Sensor. The soil moisture sensor module is the core component to read the “moisture level” of the material surrounding it. Essentially, the sensor simply senses the dielectric strength of the material (much like a capacitor). The sensor provides an analogue output to determine the moisture level. If the probe is dry then a reading tends toward 1024 while, the more wet the probe is (and stronger dielectric field) the more the reading will tend toward 0. The value read from this sensor will be displayed on the 7-segment.
- Analogue Temperature Sensor Module. The temperature will be detected and returned as an analogue signal, which can be converted to Degrees Celsius easily. The Degrees Celsius will be displayed on the 7-segment.
- Mini-Breadboard. The meanie breadboard is useful because we need multiple connections to the 5V and ground pins of the Arduino. Therefore, we are using the breadboard as a middleman to easily connect everything together.
- Dupont Jumper Wires. Dupoint wires are used to connect everything together. For a few tips on using Dupont wires, have a look at video at the end.
Now a quick overview on how to connect everything up.
Connections
The connections are fairly straight forward but I did notice one or two things worth pointing out.
- Connect the 5V and Ground from the Arduino to the breadboard (into separate rails!)
- Connect all the VCC pins from all the sensors to the 5V rail and all the GND pins to the Ground rail on the breadboard.
- I noticed that the temperature sensor I had have a common problem, it is marked incorrectly! The VCC is actually GND and, the GND is actually VCC. If you see that the sensor gives you a lower reading instead of a higher reading when you heat it up then you simply need to switch the pins around. This seems to be a common problem with this module.
- Connect the power supply, the battery in this case, to its own + and the joined GND rail (all GND pins have to be connected to each other!) on the breadboard. The reason for this is because the power supply is running at 12C in this case while the modules use 5V. We don’t want to mix the voltages, the 12V is intended to power the Arduino itself and also provide power to the pump/valve.
- Connect the “Vin” pin from the Arduino to the 12V power rail. This will supply the 12V to power the Arduino without harming the other components.
- Connect the Relay Module through the Normally-Closed (NC) pins and the 12V & ground rail.
At this point you will be left with only the data pins that needs to be connected to the Arduino’s IO pins. You can choose any pins but I chose to wire up the modules to the Arduino. For this project I arbitrarily chose the following pins:
- 7-Segment Display Module –
- The “CLK” pin is connected to Arduino’s Digital IO pin 2.
- The “DIO” pin is connected to Arduino’s Digital IO pin 3.
- Thermistor Module (Heat Sensor)
- The analogue output pin is connected to the Arduino’s Analogue IO pin A0
- Moisture Sensor Module
- The analogue output pin is connected to the Arduino’s Analogue IO pin A1
- Relay Module
- The digital input pin is connected to the Arduino’s Digital IO Pin 4.
This concludes the essentials of wiring up the project. Next, let us take a look at the source code.
Coding
First, we need to consider what code libraries are available from the Internet for us to use. Not only does it save development time, valuable examples to learn from often accompany the code libraries. In other cases, the usage is straightforward & simple enough to not need a library. It all depends on what module you are using.
In our project, the most ‘complicated’ module is the 7-segment display. Therefore, after scouring the internet, using the keywords from the Leobot Electronics site, I came across a library named “TM1637Display”. It does all the I2C communication implementation for you (more information on Arduino I2C is available at Arduino.cc).
The TM1637Display library can be downloaded at https://github.com/avishorp/TM1637
The next code consideration is to convert the reading from the Thermistor to something relatable. The Thermistor module will provide a reading between 0 and 1024 (integer) on the Arduino, but we want to know the Degrees Celcuis. Luckily this is only a simple math conversion to be done. This can be best explained with the actual code:
double Temp;
Temp = log(10000.0 * ((1024.0 / RawADC - 1)));
Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp )) * Temp );
Temp = Temp - 273.15;
return Temp;
To keep this discussion simple, I will not explain the four constants involved in this function. We are simply converting the relative 0-1024 value to Kelvin, then converting the Kelvin value to Degrees Celsius.
Reading the soil moisture value is just as easy except I am not that interested in converting the reading into an absolute value. The reason for this has to do with how the soil moisture sensor operates. The sensor reads the dielectric constant of the material. The dielectric constant is the ratio (a relative value) of permittivity (the ability of a material to store an electric field) relative to the permittivity of a vacuum. Because this value does not have an easy-to-relate-to unit such as Degrees Celsius, and because the permittivity of water can vastly differ depending on what has been diluted in the water (such as salt), it makes more sense to use the direct relative value between 0-1024 for me at least.
The Relay module is also very simple to use as it only requires a digital signal to turn the relay on or off. Because the relay is wired up so that the pump/valve is connected to the Normal Open (NO) pins on the relay it means that we would need to send a 1 (or HIGH) to turn our pump on and a 0 (or LOW) to turn it off.
Source Code
#include <Arduino.h>
#include <TM1637Display.h>
// Module connection pins (Digital Pins)
#define CLK 2 //CLK Input Pin from 7Segment
#define DIO 3 //DIO Input Pin from 7Segment
#define TI A0 //Thermistor Analogue Input Pin
#define MI A1 //Moisture Analogue Input Pin
#define RO 4 //Relay Output Pin
#define RelayThreshold 500 //Moisture Level to reach before turning on the pump or valve.
#define TEST_DELAY 500 // The amount of time (in milliseconds) between tests
TM1637Display display(CLK, DIO);
void setup()
{
pinMode(RO, OUTPUT);
display.setBrightness(0x0f);
}
void loop()
{
int readVal = analogRead(TI); // Get the Temperature
double temp = Thermistor(readVal); // Convert to Celsius
display.showNumberDec(temp, false); //Display on 7-Segment
delay(TEST_DELAY); //Wait for some time
readVal = analogRead(MI); //Read the moisture level
int soil= readVal; //Save it in its own variable
display.showNumberDec(soil, false); //Display on 7-segment
delay(TEST_DELAY); //Wait for some time
if(readVal>RelayThreshold) //Take action depending on the level of moisture
{
display.showNumberDec(999, false); //Display state
digitalWrite(RO,1); //Turn on the Relay
}else
{
display.showNumberDec(111, false); //Display state
digitalWrite(RO,0); //Turn off the Relay
}
delay(TEST_DELAY);
}
double Thermistor(int RawADC)
{
double Temp;
Temp = log(10000.0 * ((1024.0 / RawADC - 1)));
Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp )) * Temp );
Temp = Temp - 273.15; // convert from Kelvin to Celsius
return Temp;
}