How to make an automatic sprinkler with ESP8266 controlled by Arduino Cloud

Introduction

In this article, we will introduce an automatic sprinkler with ESP8266 controlled by Arduino Cloud.

In the age of the Internet of Things (IoT), the ability to collect, monitor and control environmental data in real time has opened new doors towards optimizing resources and creating innovative solutions. In this context, the use of the ESP8266 module as the heart of an automatic irrigation system controlled with Arduino Cloud, associated with various sensors, allows us to create an intelligent circuit capable of measuring, collecting and reacting to changes in temperature, humidity, brightness , atmospheric pressure and soil moisture. Furthermore, the possibility of connection to the cloud via Arduino Cloud opens the door to remote management and automation of these parameters, representing a step forward in efficiency and convenience.

At the heart of this system is the ESP8266, a versatile and powerful IoT platform that acts as an intermediary between the physical world and the cloud. This device is connected to a highly sensitive set of sensors that capture crucial information about the surrounding environment. The DHT22 sensor records air temperature and humidity, providing essential data for monitoring climatic conditions. The BH1750, an advanced light sensor, measures the intensity of ambient light, while the BMP180 offers precise information on atmospheric pressure.

One of the most interesting aspects of this system is its ability to actively control the environment. With the addition of a soil moisture sensor, the system is able to monitor the moisture level in the soil, providing crucial indication for watering your plants. The real innovation comes with the use of a bistable solenoid valve, controlled by a pair of relays, which can open or close the water flow. This element is a step forward in optimizing water resources, allowing for precise and targeted irrigation.

Arduino Cloud: a step forward in automation and remote monitoring

Connecting this system to the cloud via the Arduino Cloud represents a game-changer in data management and control. Thanks to this connection, it is possible to monitor the data collected by the sensors in real time from anywhere in the world. Additionally, the system offers an intuitive user interface in the form of a Dashboard, where environmental data and irrigation status are displayed. But the innovation doesn’t stop there: the user can switch between manual and automatic modes. In manual mode, the user has full control over the opening and closing of the solenoid valve through the interface. In automatic mode, the system responds to user-defined watering patterns via the Arduino Cloud Dashboard scheduler, optimizing water use based on plant needs and environmental conditions.

In this article, we will explore the design, assembly, and configuration of this environmental monitoring and control system in detail. From the selection of components to the programming code, passing through the integration with Arduino Cloud, we will offer a complete guide to create an intelligent system that combines technology and sustainability, opening up new perspectives in optimizing the surrounding environment.

If you are interested in seeing how the Arduino Cloud scheduler works, you can take a look at the article How to use the Arduino Cloud scheduler with an ESP8266 on PlatformIO.

But what is Arduino Cloud?

Arduino Cloud is an online service developed by Arduino, the company known for its open-source prototyping platform. The main purpose of the Arduino Cloud is to provide a simple and effective way to connect and control Arduino-based devices remotely over the Internet. It is part of the Arduino IoT (Internet of Things) ecosystem which aims to allow developers to create IoT projects in an easy and extremely intuitive way using Arduino resources. It is also possible to use other types of devices (not strictly Arduino) such as, for example, the ESP8266 and ESP32 boards.

Here are some of its features:

  • Remote Connection: Arduino Cloud offers a way to connect various devices to the Internet so they can be monitored and controlled from anywhere via an online Dashboard or mobile application;
  • Control and Monitoring: Once the devices are connected, you can use the online interface to monitor various sensors and variables on your device and control its actuators. For example, you might read data from a temperature and humidity sensor and activate a motor or relay connected to your device;
  • Automation: Arduino Cloud allows you to create automation rules and scenarios so that your device can respond to certain conditions or trigger specific actions. This is useful for creating home automation systems or advanced IoT projects;
  • Security: Arduino Cloud generally has security measures in place to ensure that connections between devices and the service are secure. This may include data encryption and secure authentication;
  • Support for different devices: Arduino Cloud is compatible with a variety of devices and boards.

Brief description of the features implemented by the automatic sprinkler with ESP8266

Let’s start describing the various features that will be implemented in this project.
The device is able to command a solenoid valve in order to close or open it to interrupt or not the water flow of a garden hose. It is able to detect air temperature and humidity through a special sensor (DHT22), atmospheric pressure and light intensity through the BMP180 and BH1750 sensors. It can also measure the amount of moisture in the soil where the plant is. It is also able to connect to the internet via a WiFi connection on our home modem. The internet connection is used to monitor and control the device via a specially created Arduino Cloud Dashboard. Through this interface we can graphically display the air temperature and humidity, atmospheric pressure, lighting intensity, soil humidity, the status of the solenoid valve (if it is open or closed) remotely. We can also send commands: we can make it work manually (by turning the solenoid valve ON or OFF by giving a command on a switch on the Dashboard) or automatically (by setting the solenoid valve ON and OFF times, again from the Dashboard).

Obviously, there are many possibilities. The user can develop new features or modify existing ones. For example, it could decide to activate irrigation automatically if the humidity of the soil is below a certain value and so on.

PLEASE NOTE: although this project is quite simple, it requires a number of variables that exceeds the maximum number of variables that can be managed with an Arduino Cloud free plan. Therefore, unless the number of variables (and therefore of sensors) is reduced, it is necessary to subscribe to a paid plan (which, moreover, is quite cheap and worth the expense).

We have already described on this same blog a project concerning an automatic sprinkler controlled by Telegram. If you are interested take a look at the article How to make an automatic sprinkler controlled by Telegram with the ESP8266 NodeMCU.

As in the articles already published on this blog, we will use the optimal as the IDE PlatformIO.

What components do we need?

The list of components is not particularly long:

An example of a twin optoisolated relay module used in this project
An example of a twin optoisolated relay module used in this project

An example of a 9V bistable solenoid valve used in this project
An example of a 9V bistable solenoid valve used in this project

9V battery clip
9V battery clip

We need the 9V battery to power the solenoid valve.

Let’s briefly see how a solenoid valve works

There are mainly two types of solenoid valves, one monostable and one bistable.
The monostable solenoid valve is powered with alternating voltage while the bistable with direct voltage.
We will be using a bistable solenoid valve in this project. The double solenoid valve has two stable states, one for closed valve and one for open valve. By powering the solenoid, the valve opens and remains open even when power is removed.
To close it we must power the solenoid by inverting the polarity, also in this case by cutting OFF power the valve remains closed. The main advantage is minimal power consumption, given that to open and close the valve it is only necessary to power it for a few milliseconds, this allows it to be powered using a battery.
The solenoid valve requires a double opto-isolated relay module. The two relays are conveniently driven by two digital outputs of the ESP8266 NodeMCU to apply a forward or reverse voltage to the solenoid valve, depending on whether you want to open or close it.

Project realization

The wiring scheme

Before realizing the real circuit let’s look at the pinout of the board and the sensors:

The NodeMCU ESP8266 pinout
The NodeMCU ESP8266 pinout

Various GPIOs are used in this project, some to read sensors, some to drive relays.

We will use GPIO 14 to read the DHT22 sensor (ambient temperature and humidity), GPIO 4 and 5 to read the BH1750 and BMP180 sensors (ambient brightness and atmospheric pressure), ADC0 to read the soil moisture value, and GPIO 12 and 13 to control the relays.

So let’s see the pinout of the DHT22, BH1750 and BMP180 sensors:

DHT22 pinout
DHT22 pinout

BH1750 pinout
BH1750 pinout

BMP180 pinout
BMP180 pinout

While the DHT22 has a dedicated GPIO for its reading (not used by other sensors), the BMP180 and BH1750 sensors are both connected to GPIO 4 (SDA) and 5 (SCL) of the ESP8266. These pins are part of a two-wire communication bus called I2C. This bus requires the presence of a master device (in our case the ESP8266) which manages the communication and one or more slave devices (which in our case are the two sensors). The slave devices all have their own hexadecimal address in order to let the master understand which device a certain message is coming from or to make the master send a message to the right slave. In this way, conflicts between messages are avoided, since they travel on the same bus.

The BMP180 sensor has an address of 0xEF for reading and 0xEE for writing while the address of the BH1750 sensor can be set via the ADDR pin. In particular, we will have that:

  • the address is 0x23 if the voltage at the ADDR pin is less than 0.7 Vdc
  • the address is 0x5C if the voltage at the ADDR pin is greater than 0.7V

Fortunately the addresses of the two devices do not coincide so we will not have message collisions.

In general, if two or more devices have the same address (not modifiable) it will not be possible to connect them to the same I2C bus.

At this point we can see the complete wiring diagram created, as usual, using Fritzing:

Complete wiring diagram of the automatic sprinkler with ESP8266
Complete wiring diagram of the automatic sprinkler with ESP8266

As you can see the scheme is not particularly complex. Rather you have to pay attention to the power supplies since they are separated between the sensors power supply section and the relay module power supply section. As you can see, the power for the three sensors is taken from the 3.3V output of the NodeMCU (pin 3V3). It is necessary to power the sensors with 3.3V so that their output is also 3.3V as the digital pins of the NodeMCU do not accept voltages higher than 3.3V.

Instead, the power supply of the relay module is taken from the Vin pin of the NodeMCU which supplies the 5V necessary to drive the relay coils.

PAY ATTENTION: in the ESP8266 NodeMCU the maximum voltage tolerated by the digital inputs is equal to 3.3V. Any higher voltage would damage it irreparably!!

Currently the double relay module is not present in Fritzing but, if you want to use it in your projects, you can download it from here.

Let’s analyze in more detail the connection of the relay module.

The two pins Vin and GND of the ESP8266 NodeMCU are used to power the dual relay module, connecting the Vin pin (NodeMCU side) to the VCC pin (dual relay module side) and the two pins GND (ground).

Two other connections are used to control the relay module and they are the orange wire and the brown wire which connect the two digital outputs GPIO 12 and GPIO 13 of the NodeMCU to the IN1 and IN2 inputs of the relay module.

You will notice that on the relay module there is a jumper (drawn in blue on the left connector) that connects the JD-VCC and VCC terminals. This jumper is used to power the relay module through the VCC and GND terminals on the right connector. Without this jumper, we are forced to power the module from an external power supply.

Finally, connected to the relay contacts, we have the 9V battery and the solenoid valve so that we can power it with opposite polarity depending on whether we want to open or close it.

Let’s now analyze the soil moisture meter

We have already mentioned the presence of a feature that allows us to check if the soil in which our plant is located is wet or dry enough and needs to be watered.

But how do you measure the value of this humidity? What physical parameter can we use? The parameter we use is the electrical conductivity of the soil. In reality what we really measure is its electrical resistivity, which is the inverse of conductivity.

Soil, when wet, is a good conductor of electricity. This means that its electrical resistance is low. When it dries, however, it becomes a poor conductor of electricity, so its electrical resistance increases.

To measure its resistance, we plug it into a very simple circuit called a voltage divider.

A voltage divider circuit
A voltage divider circuit

As you can see, the voltage divider consists of two resistors: R1 and R2. In our case, R1 represents the electrical resistance of the ground, R2 is a normal 10kΩ resistor. A voltage, which we call Vin, is applied to the divider. At the output of the divider we have a voltage which we call Vout. The voltage Vout will be a fraction of the Vin (hence the name voltage divider) given by the formula:

The voltage divider formula
The voltage divider formula

The voltage Vin is our reference voltage and must be constant. We take it from the 3V3 pin of the NodeMCU which supplies a constant voltage at 3.3V and which we have already used to power the other sensors.

PAY ATTENTION: in the ESP8266 NodeMCU the maximum voltage tolerated by the analog input is equal to 3.3V. Any higher voltage would damage it irreparably!!

The R2 resistance is fixed (we set it at 10kΩ) while the R1 resistance (that of the soil) varies according to the humidity. Therefore the voltage Vout will vary as a function of the resistance R1 (and therefore of the humidity of the soil).

We just have to measure this voltage Vout with the analog input of the NodeMCU.

The two red and blue wires are connected to two metal sticks which are then stuck into the soil near the plant, spacing them a few centimeters apart.

As you can see, the Vout voltage is measured by connecting the blue wire between the center point of the voltage divider and the NodeMCU pin A0.

Let’s create the objects and the dashboard on the cloud

First, if you haven’t already done so, you need to create an account on Arduino Cloud.

PLEASE NOTE: although this project is quite simple, it requires a number of variables that exceeds the maximum number of variables that can be managed with an Arduino Cloud free plan. Therefore, unless the number of variables (and therefore of sensors) is reduced, it is necessary to subscribe to a paid plan (which, moreover, is quite cheap and worth the expense).

Once you have logged in you will find this page:

Arduino Cloud home page
Arduino Cloud home page

Click on the GET STARTED button and you will be sent to the page:

Second page of Arduino Cloud
Second page of Arduino Cloud

Click on the IoT Cloud button. The Things page will open.

At this point you will proceed to:

  • create the device that will map the board
  • create the object (thing) with the variables associated with the device created in the previous step
  • create the dashboard to be associated with the variables

We will see the procedure just listed with this video:

PLEASE NOTE: it is important to note that in the video, at 4:20, I downloaded a pdf containing the device connection parameters. They are called Device ID and Secret Key and we will need them later. So download this pdf yourself and keep it somewhere.

Obviously the Device ID and Secret Key parameters are specific to each device, therefore they change when the device changes.

Once the procedure is complete, go to the test_thing object and click on the Sketch tab:

Object properties screenshot
Object properties screenshot

Then press the Open full editor button:

Sketch screenshot
Sketch screenshot

A window like this will open:

Screenshot of the complete code
Screenshot of the complete code

What interests us (and which we will use later) are the main .ino file (the one called test_thing_aug15b.ino in the photo and which will have a different name from you) and the thingProperties.h file. We will use these two files later in our PlatformIO project.

The sketch

Let’s create the PlatformIO project

We have already seen the procedure for creating a PlatformIO project in the article How to create a project for NodeMCU ESP8266 with PlatformIO.

Of the libraries indicated, install, following the procedure, the DHT sensor library for ESPx by Bernd Giesecke (which is used to read the data transmitted by the DHT22 temperature and humidity sensor) and leave the other two alone (WiFiManager and UniversalTelegramBot).

Then install the Adafruit BMP085 Library by Adafruit library:

Install the BMP085 library on the PlatformIO project
Install the BMP085 library on the PlatformIO project

Install now the BH1750 by claws library:

Install the BH1750 library on the PlatformIO project
Install the BH1750 library on the PlatformIO project

Then, following the usual procedure, install the Arduino_ConnectionHandler library:

Installing the Arduino_ConnectionHandler library
Installing the Arduino_ConnectionHandler library

and the ArduinoIoTCloud library:

Installing the ArduinoIoTCloud library
Installing the ArduinoIoTCloud library

Now edit the platformio.ini file to add these two lines:

monitor_speed = 115200
upload_speed = 921600

so that it looks like this:

[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps = 
	arduino-libraries/Arduino_ConnectionHandler@^0.7.6
	arduino-libraries/ArduinoIoTCloud@^1.12.0
	beegee-tokyo/DHT sensor library for ESPx@^1.19
	adafruit/Adafruit BMP085 Library@^1.2.2
	claws/BH1750@^1.3.0

At this point go back to the cloud platform, copy the contents of the .ino file:

The .ino file of the project
The .ino file of the project

and paste it into the main.cpp file of the PlatformIO project, in order to completely replace its contents.

Now create in the include folder a file that you will call thingProperties.h, go to the cloud platform, copy the content of the tab thingProperties.h:

The thingProperties.h file
The thingProperties.h file

and paste it into the thingProperties.h file you just created inside the PlatformIO project.

At this point you will have to edit this file in order to connect it to the cloud:

const char DEVICE_LOGIN_NAME[]  = "XXXXXXXXXXXXXXXXXXXXXXXXXX";

const char SSID[]               = SECRET_SSID;    // Network SSID (name)
const char PASS[]               = SECRET_OPTIONAL_PASS;    // Network password (use for WPA, or use as key for WEP)
const char DEVICE_KEY[]  = SECRET_DEVICE_KEY;    // Secret device password

As you can see, in this section there are some parameters to set.

The first parameter (DEVICE_LOGIN_NAME) was automatically added and you can find it in the pdf you downloaded when you created the object (you can find the reference in the previous video). In the pdf the parameter is called Device ID.

The SECRET_SSID and SECRET_OPTIONAL_PASS parameters are, respectively, the name and password of your WiFi network. Therefore, instead of SECRET_SSID you will put the name of your network between double quotes (“) and instead of SECRET_OPTIONAL_PASS you will put your network password (between double quotes).

The last parameter, SECRET_DEVICE_KEY, can be found in the pdf you downloaded from the platform with the name Secret Key.

So the section in question should look like this:

const char DEVICE_LOGIN_NAME[]  = "5b20cc94-d4fe-4d09-a4fa-7bb75e353aa7";
const char SSID[]               = "my_wifi_network_ssid";    // Network SSID (name)
const char PASS[]               = "my_wifi_network_password";    // Network password (use for WPA, or use as key for WEP)
const char DEVICE_KEY[]  = "P7WPMDDR2G9SZW2LKBAY";    // Secret device password

As you can see, I put in the DEVICE_LOGIN_NAME field the value taken from the pdf under Device ID (in this case 5b20cc94-d4fe-4d09-a4fa-7bb75e353aa7), in the SSID field the SSID of my WiFi network (in this case my_wifi_network_ssid), in the PASS field the password of my WiFi network (in this case my_wifi_network_password) and in the DEVICE_KEY field the value taken from the pdf under the Secret Key (in this case P7WPMDDR2G9SZW2LKBAY).

It’s time to edit the main.cpp file.

You will initially include the Arduino library and the thingProperties.h file like this:

#include <Arduino.h>
#include <thingProperties.h>

Then you will need to include the necessary libraries:

#include <Wire.h>
#include "DHTesp.h"
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <BH1750.h>

Define the variables necessary for the acquisition of the soil moisture value:

#define ANALOGPIN0 A0  // ESP8266 Analog Pin ADC0 = A0
#define MAXADCRESOLUTION 1024
int soilMoistureAcquired = 0;  // value read 
float soilMoistureVoltage = 0.0;
float soilMoistureThreshold = 1.0;
float powerSupply = 3.3;

Define the objects that will interface to the other sensors:

Adafruit_BMP085 bmp;  
BH1750 brightnessMeasure;
DHTesp dht;

Then define the GPIOs dedicated to the DHT22 and to driving the relay module:

#define  DHT22_PIN 14   
#define  RELAY_1  13
#define  RELAY_2  12

Finally, define the variables that establish the timing of the measurements (in this case the quantities will be measured every 10 minutes):

unsigned long measureDelay = 600000;                //    NOT LESS THAN 2000!!!!!    BETTER 600000  (10 MINUTES)
unsigned long lastTimeRan;

Continue with the implementation of the functions that open/close the solenoid valve (open_valve and close_valve) and those that cut OFF its power (reset_valve_high and reset_valve_low) by putting the two pins at the same potential:

void reset_valve_high() {
  // Sends 0V to the valve setting HIGH both control pins.
  digitalWrite(RELAY_1, HIGH);
  digitalWrite(RELAY_2, HIGH);  
  Serial.println("Reset HIGH\n");
}

void reset_valve_low() {
  // Sends 0V to the valve setting LOW both control pins.
  digitalWrite(RELAY_1, LOW);
  digitalWrite(RELAY_2, LOW);  
  Serial.println("Reset LOW\n");
}


void open_valve() {
  // Sends a 10ms impulse to open the valve.
  digitalWrite(RELAY_1, LOW);
  digitalWrite(RELAY_2, HIGH);
  delay(200); 
  Serial.println("\nValve opened. Water Flowing\n");
}


void close_valve() {
  // Sends a 10ms impulse to open the valve.
  digitalWrite(RELAY_1, HIGH);
  digitalWrite(RELAY_2, LOW);
  delay(200);
  Serial.println("\nValve closed. Water not Flowing\n");
}

The solenoid valve opens by setting the RELAY_2 pin to HIGH (ie 1) and the RELAY_1 pin to LOW (ie 0) for 200 ms (line delay(200); ) and closes by inverting the status of the two pins.

Depending on the solenoid valve model, it may be necessary to change this time interval by trial and error.

Now let’s see what happens in the setup function.

Initially you need to change the serial port speed from 9600 to 115200:

Serial.begin(115200);

instead of:

Serial.begin(9600);

and, if it’s not already present, impose a delay to give the port time to initialize, like this:

delay(1500); 

Then proceed to initialize the I2C bus, the brightness and pressure sensors, the temperature and humidity sensor, the mode and lastStatus variables and the initProperties(), ArduinoCloud.begin(ArduinoIoTPreferredConnection), setDebugMessageLevel(2) and ArduinoCloud.printDebugInfo() which initialize the part managed by Arduino Cloud:

  Wire.begin();           

  brightnessMeasure.begin();

  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP085/BMP180 sensor, check wiring!");      
    while (1) {}
  }

  dht.setup(DHT22_PIN, DHTesp::DHT22); // Connect DHT sensor to GPIO 14 

  mode = true;
  lastStatus = false;  

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

At the end of the setup function you will proceed to define the two pins that manage the relay module as OUTPUT:

  pinMode(RELAY_1, OUTPUT);
  pinMode(RELAY_2, OUTPUT);

and to give the command to close the solenoid valve (to avoid accidental flooding):

close_valve();
reset_valve_high();

Now let’s see how the loop function looks like:

Initially there is the ArduinoCloud.update() function which takes care of updating the status of the Cloud followed by a block which takes care of acquiring the measurements of the physical quantities every measureDelay milliseconds (in our case they are 600000 corresponding to 10 minutes):

ArduinoCloud.update();
// Your code here 

if (millis() > lastTimeRan + measureDelay)  {
atmosphericHumidity = dht.getHumidity();
atmosphericTemperature = dht.getTemperature();
ambientLight = brightnessMeasure.readLightLevel();
atmosphericPressure = bmp.readPressure() / 100.0;   
soilMoistureAcquired = analogRead(ANALOGPIN0); 
soilMoisture = (powerSupply / MAXADCRESOLUTION) * soilMoistureAcquired / 0.033;  

Serial.println("Sending data...");      

lastTimeRan = millis();
}

These variables are defined within the test_thing that we have created within the Arduino Cloud so they are updated in real time on the Cloud.

An if block follows that determines whether the sprinkler is set to automatic mode (when the mode variable is true) or manual mode (when the mode variable is false). In the first case the main block is executed, in the second case the code inside the else is executed:

if(mode) {                    // if mode == true   automatic mode

switch(schedule.isActive())
{
    case 0:             // if valve state is CLOSED, closes the valve
    if(lastStatus != schedule.isActive()) {
        close_valve();
        reset_valve_high();
    }      
    lastStatus = false;
    break;

    case 1:             // if valve state is OPEN, opens the valve
    if(lastStatus != schedule.isActive()) {
        open_valve();
        reset_valve_low();
    }
    lastStatus = true;
    break;
}

} else {                    // if mode == false    manual mode

    switch(activate)
    {
    case 0:             // if valve state is CLOSED, closes the valve
        if(lastStatus != activate) {
        close_valve();
        reset_valve_high();
        }      
        lastStatus = false;
        break;
    
    case 1:             // if valve state is OPEN, opens the valve
        if(lastStatus != activate) {
        open_valve();
        reset_valve_low();
        }
        lastStatus = true;
        break;
    }

}

Let’s see it now in more detail.

In automatic mode (main block) the opening or closing of the solenoid valve is decided by the Dashboard scheduler. Inside we have a switch…case structure like this:

switch(schedule.isActive())
{
    case 0:             // if valve state is CLOSED, closes the valve
    if(lastStatus != schedule.isActive()) {
        close_valve();
        reset_valve_high();
    }      
    lastStatus = false;
    break;

    case 1:             // if valve state is OPEN, opens the valve
    if(lastStatus != schedule.isActive()) {
        open_valve();
        reset_valve_low();
    }
    lastStatus = true;
    break;
}

This structure checks the state of the schedule variable (particularly whether schedule.isActive() is true or false). If it is false (case 0) it means that from the Dashboard the scheduler has given the command to close the solenoid valve. If true (case 1) it means that from the Dashboard the scheduler has given the command to open the solenoid valve.

In manual mode (else block) the opening or closing of the solenoid valve is decided by the user by acting on the appropriate switch on the Dashboard. Inside we have a switch…case structure like this:

switch(activate)
{
case 0:             // if valve state is CLOSED, closes the valve
    if(lastStatus != activate) {
    close_valve();
    reset_valve_high();
    }      
    lastStatus = false;
    break;

case 1:             // if valve state is OPEN, opens the valve
    if(lastStatus != activate) {
    open_valve();
    reset_valve_low();
    }
    lastStatus = true;
    break;
}

The activate variable is the one associated with the aforementioned switch. Therefore, if the user decides to close the solenoid valve by using the switch on the Dashboard, the activate variable will assume the value 0 (false) activating in the switch…case the first section that calls the functions:

close_valve();
reset_valve_high();

If, on the other hand, the user decides to open the solenoid valve by acting on the switch, the activate variable will assume the value 1 (true) activating in the switch…case the second section that calls the functions:

open_valve();
reset_valve_low();

Of course you can download the complete project from the following link:

Video of the operation of our sprinkler

Once the circuit has been created, the project compiled and loaded on the ESP8266 we should already be able to act on the sprinkler. You should be able to see the first acquired data on the Dashboard after about 10 minutes (if you’ve left the setting I gave). Anyway, here’s a video showing how the project works:

Let’s power our system via solar energy

A problem that is immediately noticeable is that this system is not independent of an energy source derived from a power supply. You could also use a power bank but this needs to be periodically unplugged to recharge it. A more efficient solution is to power the sprinkler with a system equipped with a photovoltaic panel and battery. If you are interested in this improvement, I refer you to the article Solar Power for Arduino, ESP8266 and IoT: Complete Guide to Energy Independence.

The system powered by solar energy (in this photo only the datalogger part is working while the solenoid valve is disabled)
The system powered by solar energy (in this photo only the datalogger part is working while the solenoid valve is disabled)

The dashboard shows the values ​​detected in real time by the device powered by the photovoltaic system
The dashboard shows the values ​​detected in real time by the device powered by the photovoltaic system

Let’s make the PCB for our automatic sprinkler

One of the most interesting and useful aspects of our automatic sprinkler and data logger project is the creation of a custom PCB (Printed Circuit Board). This PCB plays a vital role in optimizing our system, offering numerous benefits. First of all, it allows for greater reliability, since it replaces complex wiring on breadboards (and eliminates many tangled wires) and minimizes the risk of connection errors. Furthermore, the PCB makes our system more compact and well-organized, saving valuable space. But what really makes our custom PCB special is its ability to seamlessly integrate the different components of our system, including irrigation control and data logging. This means that our system is now more efficient and ready to provide a reliable service for watering plants, as well as recording important data for monitoring environmental conditions.

What is a PCB?

A PCB, or Printed Circuit Board, is one of the fundamental components of modern electronics. It is a thin insulating board generally made of composite material or fiberglass, on which conductive electrical circuits that connect electronic components are printed. The PCB serves as a physical platform on which to mount components such as resistors, capacitors, transistors, and microchips. The precise arrangement of printed circuit boards on a PCB is important for the stable operation of any electronic device. Thanks to its ability to simplify and organize electrical connections, PCBs have become a key element in a wide range of applications, from mobile telephony to industrial automation. To design a PCB efficiently and accurately, engineers and electronics enthusiasts use advanced PCB design software tools. Among the many on the market there is KiCad (open source and free) which has reached an excellent level of professionalism and which I used for this project. This software allows you to create detailed electrical schematics, design component and circuit layouts, optimally route electrical traces, and generate production files for PCB fabrication. With the help of this powerful design suite, you can build custom PCBs that meet the specific needs of your project, ensuring reliable connectivity and efficient operation.

Once the project has been completed, it is sent to one of the companies specialized in its implementation.

The PCB in this article was physically created by the PCBWay company given that KiCad has a plug-in that allows you to create project files in a format compatible with that required by this company.

Obviously you can download the KiCad project from this link:

Here is the electrical diagram created with KiCad 6
Here is the electrical diagram created with KiCad 6

And here are the images of the 3D rendering performed by KiCad 6:

The TOP side of the PCB
The TOP side of the PCB
The BOTTOM side of the PCB
The BOTTOM side of the PCB

Let’s see in practice how PCBs are made

The PCB will accommodate the components that we have already used and that are currently present on the breadboard. First of all, it is advisable to solder female header connectors with a 2.54mm pitch onto the PCB so that the various components can be easily inserted. This is to avoid having to solder them to the PCB permanently and to allow them to be detached when needed. If you are not familiar with soldering you can take a look at the article Yet another tutorial on how to solder on this blog.

This is what the 2.54 mm pitch female header connectors look like
This is what the 2.54 mm pitch female header connectors look like

Below we can see the PCB with the soldered connectors and the components that will have to be inserted on the connectors:

PCB with connectors
PCB with connectors

Typically these connectors are sold in 40 pin strips so you need to shorten them with small cutters.

This photo instead shows the various components, which were previously on the breadboard, mounted on the PCB connectors:

PCB with components inserted
PCB with components inserted

Finally, let’s see how the relay module was mounted: 4 nylon spacers and relative screws/nuts are sufficient to fix it in the holes provided on the PCB. Finally, it will be necessary to connect the wires coming from the relay module (VCC, IN1, IN2, GND) to the appropriate connector.

Relay module mounted on PCB
Relay module mounted on PCB

Relay module mounted on PCB (viewed from behind)
Relay module mounted on PCB (viewed from behind)

Newsletter

If you want to be informed about the release of new articles, subscribe to the newsletter. Before subscribing to the newsletter read the page Privacy Policy (UE)

If you want to unsubscribe from the newsletter, click on the link that you will find in the newsletter email.

Enter your name
Enter your email
Scroll to Top