ESP32 Smart Plant Watering | RainMaker

ESP32 Smart Plant Watering | RainMaker + Google & Alexa

Build ESP32 smart plant watering system with ESP RainMaker, automatic irrigation, soil moisture monitoring, and Google & Alexa control.

Smart gardening is one of the most practical real-world applications of IoT. In this project, we build an ESP32 Smart Plant Watering System that automatically waters plants based on soil moisture and lets you control everything from your phone — or even by voice using Google Assistant and Amazon Alexa.

esp32 plant watering system

The system is powered by ESP RainMaker, Espressif’s official cloud platform, so there’s no need to create your own mobile app or server. Device provisioning is done over BLE using a QR code, and all control happens through the RainMaker mobile app.

ESP32 Smart Plant Watering | RainMaker + Google & Alexa

At the heart of the project is an ESP32, a capacitive soil moisture sensor, and a relay-controlled water pump.

Required Components for the ESP32 Project

Required Components for the ESP32 Project
  • ESP32 Development Board
  • Capacitive Soil Moisture Sensor
  • Relay Module (for water pump control)
  • Submersible DC Water Pump
  • Jumper Wires and Breadboard
  • Power Supply (5V/USB)

Circuit of ESP32 Plant Watering System

Circuit of ESP32 Plant Monitoring System

The circuit connections are simple and beginner-friendly:

  • Soil Moisture Sensor → Analog output connected to ESP32 GPIO34 (ADC)
  • Relay IN Pin → Connected to ESP32 GPIO25
  • Relay VCC and GND → Connected to ESP32 5V and GND
  • Water Pump → Connected to relay output as a controlled load
  • ESP32 → Powered via USB cable or external 5V adapter

Note: Always use a relay or MOSFET driver to safely operate pumps or motors.

Tutorial video on the Plant Watering System

Working Principle of IoT Plant Watering System

This ESP32-based irrigation controller continuously monitors soil moisture and automatically turns the water pump ON or OFF depending on user-defined limits.

You can also switch to Manual Mode from the RainMaker app and directly control the pump remotely or with voice commands.

Operating Modes

  • Auto Mode (Default)
    • ESP32 reads soil moisture every 5 seconds
    • If moisture drops below the “Dry Limit,” the pump turns ON
    • If moisture rises above the “Wet Limit,” the pump turns OFF
    • Pump status is instantly synced to RainMaker
    • Moisture percentage is periodically uploaded to the cloud
  • Manual Mode
    • Automatic watering is disabled
    • Pump can be turned ON/OFF from the RainMaker app
    • Voice control works via Google Assistant or Alexa
    • Pump state updates instantly in the app

Program ESP32 with Arduino IDE

For this IoT-based project, I have used the Arduino IDE to program ESP32.

First update the Preferences –> Aditional boards Manager URLs: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json

  • Then install the ESP32 board (2.0.5) from the Board Manager or Click Here to download the ESP32 board.

Source Codes for ESP RainMaker ESP32 IoT Project

Click on the following buttons to download the source code for this ESP32 project.

This code is provided free for project purpose and fair use only.
Please do mail us to [email protected] if you want to use it commercially.
Copyrighted © by Tech StudyCell

Get Sensor reading for the DRY & WET soil

To get the Calibration values for moisture reading from the sensor, first, upload the code “Get Sensor reading” to the ESP32.

Connect the Moisture Sensor AOUT pin with D34 and supply 3.3V across VCC and GND.

Then open the serial monitor with Baud rate 115200.

Get Sensor reading for the DRY & WET soil

Now, note down the following values.

  • Soil is very dry.
  • Soil is very wet.

Later on, the ESP32 will calculate the moisture percentage according to these two values.

Now open the main sketch in Arduino IDE and update the following values.

esp32 plant watering system p8

Enter the deviceName according to your requirements.

Then enter the calibration values of the sensor for the DRY and WET soil types.

If required, modify the moisture threshold values (in %). In AUTO mode, the pump will start/stop according to these values.

Then select the relay type. For the Active-LOW relay make the flag true, for the Active-HIGH relay, make the flag false.

Paragraph-by-paragraph explanation

Below is a paragraph-by-paragraph explanation for every major code block, describing exactly what each section does and how it contributes to the project.

1. Library Includes

#include <Arduino.h>
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"

These libraries provide the core functionality of the project. Arduino.h gives access to standard Arduino functions. RMaker.h is the ESP RainMaker framework used for cloud connectivity, device creation, OTA, and parameters. WiFi.h manages Wi-Fi connections, while WiFiProv.h enables BLE provisioning so Wi-Fi credentials can be configured from the RainMaker mobile app using a QR code.

2. Device Identity and Provisioning Details

char nodeName[]   = "ESP32_Plant";
char deviceName[] = "Garden Pump";

const char *service_name = "PROV_Plant";
const char *pop = "PLANT123";

Here you define how your device appears in RainMaker. nodeName is the overall IoT node name, while deviceName is the actual controllable device (your pump).
service_name and pop (Proof of Possession) are used during BLE provisioning. When onboarding the ESP32, these values are embedded in the QR code so the RainMaker app can securely pair with the device.

3. GPIO Pin Assignment

#define MOISTURE_PIN 34
#define RELAY_PIN    25

These lines assign ESP32 GPIO pins. GPIO34 reads the analog value from the capacitive soil moisture sensor. GPIO25 controls the relay module connected to the water pump.

4. Soil Sensor Calibration

int DRY_ADC = 2910;
int WET_ADC = 925;

These values represent your sensor’s calibration points. DRY_ADC is the ADC reading when soil is completely dry, and WET_ADC is the reading when soil is fully wet. These values are later mapped to a 0–100% moisture scale. Every sensor is different, so these numbers should be measured and adjusted for your own hardware.

5. Moisture Thresholds

int MOISTURE_MIN = 30;
int MOISTURE_MAX = 70;

These define the automatic watering limits. When moisture drops below 30%, the pump turns ON. When moisture rises above 70%, the pump turns OFF. This creates a hysteresis band so the relay does not rapidly toggle.

6. Relay Type and Status Pins

#define RELAY_ACTIVE_LOW true

static uint8_t wifiLed = 2;
static uint8_t gpio_reset = 0;

RELAY_ACTIVE_LOW tells the firmware whether your relay turns ON with LOW or HIGH logic. Most modules are active-LOW.
wifiLed is a status LED that indicates Wi-Fi connection.
gpio_reset uses the ESP32 BOOT button to reset Wi-Fi credentials or perform a factory reset depending on how long it’s pressed.

7. Runtime State Variables

bool autoMode = true;
bool cloudRelayState = false;
bool actualRelayState = false;

These variables hold the system state:

  • autoMode decides whether watering is automatic or manual (controlled from RainMaker).
  • cloudRelayState stores manual ON/OFF commands coming from the app.
  • actualRelayState reflects the real physical state of the relay. This prevents unnecessary cloud updates.

8. RainMaker Device and Parameters

static Switch pump(deviceName);
static Param autoParam("AutoMode", "esp.param.bool",
                       value(true),
                       PROP_FLAG_READ | PROP_FLAG_WRITE);

static Param moistureParam("Moisture", "esp.param.int",
                           value(0),
                           PROP_FLAG_READ);

Node node;

Here the RainMaker objects are created:

  • pump is a standard RainMaker Switch device.
  • autoParam allows enabling or disabling Auto Mode from the app.
  • moistureParam publishes soil moisture percentage to the cloud (read-only).
  • node represents the overall ESP32 device in RainMaker.

9. Relay Control Function

void applyRelay(bool on) {

  if (actualRelayState == on) return;

  actualRelayState = on;

  if (RELAY_ACTIVE_LOW)
    digitalWrite(RELAY_PIN, on ? LOW : HIGH);
  else
    digitalWrite(RELAY_PIN, on ? HIGH : LOW);

  pump.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, actualRelayState);
}

This function controls the physical relay and immediately updates RainMaker with the new pump status. If the requested state is already active, it exits early to avoid unnecessary cloud traffic. This design ensures pump feedback appears instantly in the RainMaker app while minimizing server requests.

10. Moisture Reading Function

int readMoisture() {
  int adc = analogRead(MOISTURE_PIN);
  int pct = map(adc, DRY_ADC, WET_ADC, 0, 100);
  return constrain(pct, 0, 100);
}

The ESP32 reads the raw ADC value from the sensor, maps it between dry and wet calibration values, converts it into a percentage, and constrains the result between 0 and 100. This gives a user-friendly soil moisture reading.

11. Provisioning Event Handler

void sysProvEvent(arduino_event_t *sys_event) {

This callback listens for system events. When provisioning starts, it prints a QR code payload to the Serial Monitor for BLE onboarding. When Wi-Fi connects, it turns ON the status LED. This gives visual feedback that the device is online.

12. RainMaker Write Callback

void write_callback(Device *device, Param *param,
                    const param_val_t val,
                    void *priv_data,
                    write_ctx_t *ctx) {

This function is called whenever the RainMaker app changes a parameter.

  • If the Power parameter changes, the relay is updated only when Auto Mode is OFF (manual control).
  • If AutoMode changes, the local autoMode variable is updated.

This allows seamless switching between automatic and manual operation.

13. setup()

void setup() {

The setup() function initializes everything:

  • Starts Serial communication.
  • Configures GPIO pins.
  • Turns the pump OFF initially.
  • Creates the RainMaker node and adds device parameters.
  • Enables OTA updates, scheduling, and timezone services.
  • Starts RainMaker cloud.
  • Registers provisioning events.
  • Begins BLE provisioning so the device can be added to the RainMaker app.

This is where the ESP32 becomes a fully cloud-connected IoT device.

14. Main Loop Timer

unsigned long moistureTimer = 0;

This variable tracks when moisture was last sent to the cloud, allowing updates every 5 seconds without blocking the program.

15. loop()

void loop() {

The loop continuously performs five tasks:

Reset Handling

Long-pressing the BOOT button resets Wi-Fi or performs a factory reset.

Wi-Fi Status

The LED reflects whether the ESP32 is connected.

Moisture Reading

Soil moisture is read every loop iteration.

Automatic Watering Logic
if (autoMode) {
  if (moisture <= MOISTURE_MIN) applyRelay(true);
  if (moisture >= MOISTURE_MAX) applyRelay(false);
}

In Auto Mode, the pump is controlled purely by soil moisture using the defined thresholds.

Cloud Updates Every 5 Seconds
if (millis() - moistureTimer > 5000) {
  moistureTimer = millis();
  moistureParam.updateAndReport(value(moisture));
}

Moisture percentage is uploaded every 5 seconds, providing live monitoring while keeping cloud traffic low.

This code creates a fully automated ESP32-based smart irrigation controller:

  • Soil moisture controls the pump in Auto Mode
  • Manual pump control is available from RainMaker
  • Pump status is reported instantly
  • Moisture data is sent every 5 seconds
  • BLE provisioning simplifies Wi-Fi setup
  • OTA updates allow remote firmware upgrades

The result is a clean, cloud-connected plant watering system with minimal server usage and real-time feedback — perfect for modern smart gardening.

PCBWay – Professional PCB Assembly Services

PCBWay not only produces FR-4 and Aluminum boards but also advanced PCBs like Rogers, HDI, andFlexible and Rigid-Flex boards, at very affordable prices.

PCBWay

PCBWay provides fast, high-quality PCB assembly with lead times from just 24 hours, offering Turn-key, Partial Turn-key, and Consigned options to suit your project needs.

You can also participate in the PCBWay Mascot 3D Printing Design Contest

  • Open to all 3D printing enthusiasts
  • PCBWay’s first-ever 3D Printing Design Contest
  • Design either PCBWay mascot “Eon” or your own original character

PCBWay Contest
  • Upload the project on PCBWay Open Source Community
  • Select CNC & 3D Printing category
  • Mention Eon Theme or Open Creative
  • Add title, description & required files
  • Click Submit

Setting Up ESP RainMaker

ESP RainMaker is Espressif’s free IoT platform for ESP32 that allows you to connect your project to the cloud and control it using the ESP RainMaker mobile app.
It also supports integration with Alexa and Google Home.

esp32 plant watering system p9

🧩 Steps:

  1. Install the ESP RainMaker app (available on Android & iOS).
  2. Log in using your Espressif ID or Google account.
  3. Power up the ESP32 — it will start BLE provisioning mode.
  4. Press and hold the BOOT button for 10 seconds.
  5. Turn on the mobile Bluetooth and GPS (Location).
  6. Scan the QR code from the Serial Monitor.
  7. Connect to your Wi-Fi through the app.
esp32 plant watering system p10

Once the setup is done, the device will appear on your dashboard, allowing you to control the LED’s brightness directly.

Please refer to the following article to add the devices to the ESP RainMaker app.

Now, please refer to the following articles to connect the ESP RainMaker with Amazon Alexa and Google Home App.

After doing all these steps, you can control the appliances with Google Assistant and Amazon Alexa.

esp32 plant watering system p4

By default, the system will be in AUTO mode. To go to Manual mode, tap on the device, then tap on “Edit” beside “Auto Mode” and make it false.

  • AutoMode = true → Automatic watering (sensor controls pump)
  • AutoMode = false → Manual control (you control the pump)
esp32 plant watering system p3

Conclusion

This ESP32 Smart Plant Watering System demonstrates how powerful and accessible IoT can be when combined with ESP RainMaker. With automatic irrigation, cloud monitoring, and voice control through Google Assistant and Alexa, your plants get exactly the water they need — even when you’re away from home.

It’s a low-cost, scalable, and professional-grade smart irrigation solution that’s perfect for learning ESP32 IoT while solving a real-world problem.

If you’re looking to build a modern, cloud-connected plant watering system, this project is a fantastic place to start.