Plant watering system – part 1

In this article I will show how I have set up the electronics and arduino code for a system that monitors moisture in soil and automatically waters a plant when needed. It’s easy to forget to water a plant and this arduino-based system can be your back-up when it happens.

The moisture sensor

I’m using an arduino nano microcontrolller, a moisture sensor and a relay module controlling a small 12V diaphragm pump. I have also set up LED lights to indicate when the sensor reads the moisture values and when the pump waters the plant. LED lights are not strictly necessary to keep the plant alive, but it’s a cool feature that can be implemented in many different ways.

Bill of materials:

  • Arduino Nano
  • Moisture Sensor  (ebay search: “arduino moisture sensor”)
  • Relay Module (ebay search: “1 Channel  Relay Module”)
  • A pump  (ebay search: “Diaphragm Pump”)
  • 2x 220Ohm resistors
  • 2x LEDs
  • A breadboard
This is my prototyping board. I have used three LEDs of each color, but one of each is good enough for testing. Later as I build a complete enclosure for all the parts I will use even more LEDs, but I could have used only one depending on my final design.
A simple illsutration showing how to wire the arduino prototyping breadboard


A 12V diaphragm pump. The inlet and outlet diameter is 6mm on this pump. It comes with rubber feet for anti vibration.

The arduino code is set up to probe the soil of the plant every 10 seconds and if the soil is too dry the pump runs for 3 seconds. These number can and should be changed according to how much water the particlar plant needs and how often it is necessary to probe soil.  It should not be nesesary to probe more than every 15 minutes. Also check how much water the pump can push through a tube per second.

The arduiono code:

// Name: Arduino Plant Water System                             // 
// Author: Anders Holm                                          //
//         Functional Design -     //
// Date: May 2016                                               //
// Version: 1.0                                                 // 
// Notes: Code for checking soil moisture and turning on        // 
// :      a water pump if soil is too dry. LED lights           // 
// :      indicate when probing and when pump is running.       //

int pump = 2; // setting up the pins on the microcontroller
int probelight = 3;
int probe = 7;
int pumplight = 9;
int moistureSensor = 0;

// for the light fading
float probeValue;
float probeTime=0;
float probeDisplace = 500;
float probePeriode = 1000; // set the lenght of led fading
float pumpValue;
float pumpTime=0;
float pumpDisplace = 500;
float pumpPeriode = 1000; // set the lenght of led fading

boolean probeLightState = false; // toggling probe light on/off
int lastprobeLightState = 0; // toggling probe light on/off
int probeLightTime = 1800; // how long LED pulses
unsigned long prevProbelightmillis = 0; // for resetting the probe light time

boolean pumpLightState = false; // toggling pump light on/off
boolean motorStatus = false; // pump on/off
boolean probeStatus = false; // probe on/off

unsigned long probeToggle = millis(); // to store when to turn on off the probe
unsigned long pumpToggle = millis(); // to store when to turn on off the pump
unsigned long pumpRuntime = 3000; // Set the pump run time 
unsigned long probeDelay = 10000; // Set delay between probings

void setup() {

 Serial.begin(9600); // starting the serial monitor for debugging and calibration of sensor data
 // setting up all the pins
 pinMode(pump, OUTPUT);
 pinMode(pumplight, OUTPUT);
 pinMode(probelight, OUTPUT);
 pinMode(probe, OUTPUT);
 digitalWrite(pump, HIGH); // pump is set to off on startup

// the loop routine runs over and over again forever:
void loop() {
 RunProbe(); // probe on, toggle probelight, check value/toggle pump, probe off.
 TogglePump(); // pump on for a set time, toggle pump light on off.
 PumpLight(); // light on when pump on, light of when pump off.
 if (probeLightState) {ProbeLight();} // if the state has changed in RunProbe();, run fader

}// end loop

void RunProbe() {
if (millis() > probeToggle) { // checks if it's time for probing
 probeLightState=true; // turn on probe indicator lights
 prevProbelightmillis = millis(); 
 digitalWrite(probe, HIGH); // turn on the probe
 delay(100); // give the probe some time to wake up
 int sensorValue = analogRead(moistureSensor); //read the value
 Serial.print("Probe reading: ");
 Serial.println(sensorValue); // prints to serial monitor - for debugging/calibration
 if (sensorValue >= 600) { // Check if sensorvalue is too high, calibrate if needed 
 Serial.print(sensorValue); // prints to serial monitor - for debugging/calibration
 Serial.println(" It's too dry! - turning on the pump"); 
 motorStatus = !motorStatus; //changes the pump on/off and updates the timer
 }//end checking sensorvalue
 probeToggle = millis() + probeDelay; //resets the time for probing

 } //end if probeToggle 
 digitalWrite(probe, LOW); //turn of the probe

} //end runprobe

void TogglePump(){ //this function runs the pump if its turned on
if (millis() > pumpToggle)
 if (motorStatus) { //checking if pump is turned on
 digitalWrite(pump, LOW); // pump is now on
 pumpLightState = true; // turn on pump indicator lights
 pumpToggle = millis() + pumpRuntime; // reset pumptoggle time
 motorStatus = !motorStatus; // switching the state
 { //motor is turned off
 pumpLightState = false; // turn off the lights
 digitalWrite(pump, HIGH); // set the pump to OFF 0
 } //end if

} //end runpump
void PumpLight() //the light indicator for running pump
{ if (pumpLightState){
 pumpTime = millis();
 pumpValue = 128+127*cos(2*PI/pumpPeriode*(pumpDisplace-pumpTime)); //using sinus for smooth and pretty fade
 analogWrite(pumplight, pumpValue);
 else {
 analogWrite(pumplight, 0); //set the pump light off if status is off/false

 } //end if
}//end pump toggle

void ProbeLight() //the light indicator for ongoing probe sensing
 if (millis() - prevProbelightmillis <= probeLightTime){ // checking if it's time to fade LEDs
 probeTime = millis();
 probeValue = 128+127.0*cos(2.0*PI/probePeriode*(probeDisplace-probeTime)); //using sinus for smooth and pretty fade
 analogWrite(probelight, probeValue);
 else {
 analogWrite(probelight, 1); // Led stand-by light, value between 1-10
 probeLightState = !probeLightState; // Turn the state off
}//end runprobelight


This is end of part 1 of the watering system. Next step is building it into a practicle enclosure with watertank so that it can be used for watering plant in the living room or in the office.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s