Maker 101
Published © GPL3+

Build a Self Watering System

Soil Moisture Sensor - Water Pump - Water Level Sensor - MOSFET - Circuit - Code

IntermediateFull instructions provided585
Build a Self Watering System

Things used in this project

Hardware components

Wemos D1 Mini (ESP8266) x1
×1
16V 100uF Capacitors
×2
SparkFun Soil Moisture Sensor (with Screw Terminals)
SparkFun Soil Moisture Sensor (with Screw Terminals)
×1
Water Level Sensor
×1
Water Pump Motor DC 3.3V - 5V
×1
Resistor 330 ohm
Resistor 330 ohm
×1
Resistor 10k ohm
Resistor 10k ohm
×1
IRFZ44N Mosfet
×1
5V 1A Power Supply
×1
Development Kit Accessory, Jumper Wire Kit
Development Kit Accessory, Jumper Wire Kit
×1
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE
Blynk
Blynk
Circuit Maker
CircuitMaker by Altium Circuit Maker

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Custom parts and enclosures

arbre1_qgpOgYdyWm.stl

arbre2_5w8DbQszI7.stl

eau_Key64y5vBC.stl

terre_iZ8jovFowL.stl

top-case-cover_zvBaaZA5no.stl

top-case-for-circuit_NqOnYxHmMn.stl

Schematics

Breadboard-Circuit-Diagram

Schematic

Code

Blynk_Moisture_WaterLevel_ESP8266.ino

Arduino
#include <ESP8266WiFi.h>
#include <FastLED.h>
#include <BlynkSimpleEsp8266.h>

#define BLYNK_PRINT Serial
#define BLYNK_AUTH_TOKEN "YOUR_TOKEN"

char ssid[] = "YOUR_SSID";
char pass[] = "PASSWORD";

#define LED_PIN     15  // D8 pin - Wemos D1 Mini
#define LED_COUNT   12  // Number of LEDs in your NeoPixel ring
#define BRIGHTNESS  60  // LED brightness (0-255 range)

CRGB leds[LED_COUNT];

// Sensor pins
#define WATER_PWR 14    // D5 pin - Wemos D1 Mini
#define WATER_PIN A0    // A0 pin
#define MOISTURE_PWR 4  // D2 pin
#define MOISTURE_PIN 5  // D1 pin
#define WATER_PUMP 12   // D6 pin

/* Define how long the pump will run (3 seconds) */
#define PUMP_TIME 3000

/* Change these values based on your calibration values */
#define LVL_HIGH 520  // Define max value water level
#define LVL_LOW 470   // Define min value of water level

/* Define the time range for sensor measurements */
const int measurementInterval = 10000;
/* Time variable to keep track of the time range */
unsigned long previousMillis = 0; 

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Wi-Fi connected: ");
  Serial.println(WiFi.localIP());

  Blynk.config(BLYNK_AUTH_TOKEN);

  pinMode(WATER_PWR, OUTPUT);
  pinMode(WATER_PIN, INPUT);
  pinMode(MOISTURE_PWR, OUTPUT);
  pinMode(MOISTURE_PIN, INPUT);
  pinMode(WATER_PUMP, OUTPUT);
  
  /* Initially keep the sensors and motor OFF */
  digitalWrite(WATER_PWR, LOW);
  digitalWrite(MOISTURE_PWR, LOW);
  digitalWrite(WATER_PUMP, LOW);

  FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, LED_COUNT);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.show();
  FastLED.clear();
}

void loop() {
  // Run the Blynk app.
  Blynk.run();
  // Run the LED function
  ultravioletEffect();

  /* Get current time. If the defined time range 
  has not passed, terminate the loop */
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis < measurementInterval) {
    return;
  }
  /* If the defined time range is complete, update the time */
  previousMillis = currentMillis;

  /* Get the value from the soil moisture sensor function 
  when the defined time range is complete */
  int MOISTURE_LEVEL = readMoisture();

  /* If the soil moisture is HIGH, report everything as perfect! */
  /* The sensor value works inversely! */
  if (MOISTURE_LEVEL == LOW) {
		Serial.println("Moisture is perfect");
    Blynk.virtualWrite(V1, "Moisture is perfect");
    Blynk.virtualWrite(V3, "The water pump is on standby!");

  /* If the soil moisture value is LOW, report it and 
  run the water pump motor for the defined pump time, 
  then stop the pump */
	} else {
		Serial.println("Low moisture! Time to water!");
    Blynk.virtualWrite(V1, "Low moisture! Time to water!");
    Blynk.virtualWrite(V3, "Water pump started!");
    digitalWrite(WATER_PUMP, HIGH);
    Serial.print("Water pump started!");
    delay(PUMP_TIME);
    digitalWrite(WATER_PUMP, LOW);
    Serial.print("The water pump is on standby!");
	}

  /* Get the value from the water level sensor function 
  when the defined time range is complete */
  int WATER_LEVEL = readWaterLevel();
  /* Convert the received water level value to the percent value */
  float percentLevel = map(WATER_LEVEL, 300, 600, 0, 100);
  Serial.print("Water Level: ");
  Serial.print(percentLevel);
  Serial.println(" %");
  /* Report and print the received water level status */
  if (WATER_LEVEL > LVL_HIGH) {
		Serial.println("Water level is too");
	} else if (WATER_LEVEL >= LVL_LOW && WATER_LEVEL < LVL_HIGH) {
		Serial.println("Water level is perfect");
	} else {
		Serial.println("Water level is low! Time to add water!");
	}
  Blynk.virtualWrite(V2, percentLevel);
  
  /* It is the last line of the Loop Function, 
  the Loop Function is executed from the beginning... */
	Serial.println();
}

/* This function returns the analog water level measurement */
int readWaterLevel(){
  digitalWrite(WATER_PWR, HIGH);            // Turn the sensor ON
  delay(10);                                // Allow power to settle
  int sensorValue = analogRead(WATER_PIN);	// Read the analog value from sensor
  digitalWrite(WATER_PWR, LOW);             // Turn the sensor OFF
  return sensorValue;                       // Return analog water value
}

/* This function returns the digital soil moisture measurement */
int readMoisture(){
  digitalWrite(MOISTURE_PWR, HIGH);             // Turn the sensor ON
  delay(10);                                    // Allow power to settle
  int sensorValue = digitalRead(MOISTURE_PIN);	// Read the digital value from sensor
  digitalWrite(MOISTURE_PWR, LOW);              // Turn the sensor OFF
  return sensorValue;                           // Return digital moisture value
}

/* Ultraviolet color function (You can adjust the values here to get the desired color) */
void ultravioletEffect() {
  CRGB uvColor(138, 43, 226);
  // Turn on all LEDs with the ultraviolet color
  fill_solid(leds, LED_COUNT, uvColor);
  FastLED.show();
}

Credits

Maker 101

Maker 101

42 projects • 172 followers
Maker 101; Beginner and intermediate level Maker projects!

Comments