ESP32 S3 UNO - Soil Moisture Sensor

This ESP32 S3 Uno soil moisture sensor tutorial shows you how to wire a capacitive soil moisture sensor to the ESP32 S3 Uno form board and read the soil moisture level with Arduino code. You will also learn why a capacitive moisture sensor lasts longer than a resistive one, and how to tell if your plant needs water.

In this tutorial, you will:

  1. Compare resistive and capacitive soil moisture sensors
  2. Wire a capacitive soil moisture sensor to the ESP32 S3 Uno
  3. Read the moisture value with analogRead() in the Arduino IDE
  4. Calibrate the sensor to find your own wet/dry threshold
  5. Check if the soil is wet or dry with a simple sketch
ESP32 S3 Uno soil moisture sensor

Hardware Preparation

1×ESP32 S3 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×Capacitive Soil Moisture Sensor
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Buy Note: Many soil moisture sensors available in the market are unreliable, regardless of their version. We strongly recommend buying the sensor with TLC555I Chip from the DIYables brand using the link provided above. We tested it, and it worked reliably.

Overview of Soil Moisture Sensor Sensor

Before you buy a sensor, it is good to know that there are two kinds. They look alike, but one of them wears out quickly in wet soil.

capacitive moisture sensor vs resistive moisture sensor

Resistive moisture sensor

A resistive sensor sends a small current through the soil between its two bare metal probes. This current slowly eats away the metal. This is called electrochemical corrosion, and after some weeks the readings become wrong.

Capacitive moisture sensor

A capacitive sensor has its electrodes covered by a protective layer. No metal touches the soil, so it does not corrode. For this reason, we strongly recommend the capacitive type.

The photo below shows a resistive soil moisture sensor that has corroded after some time in the soil.

resistive soil moisture sensor corroded

The rest of this tutorial uses the capacitive soil moisture sensor.

Capacitive Soil Moisture Sensor Pinout

The sensor has only three pins, so the wiring is very simple.

Pin What It Does
GND Connect to GND (0V)
VCC Power input, 3.3V to 5V. Use 3.3V with the ESP32 S3 Uno
AOUT Analog output. The voltage changes with soil moisture. Connect it to an analog input pin of the ESP32 S3 Uno
capacitive soil moisture sensor pinout

How It Works

The sensor measures how much water is around its probe. More water in the soil gives a lower voltage on the AOUT pin. Dry soil gives a higher voltage. So on the ESP32 S3 Uno, a smaller analogRead() value means wetter soil.

ESP32 S3 Uno Pinout

The image below shows the pinout of the ESP32 S3 Uno form board. Use it to find the A0 pin and its GPIO number when you wire the sensor.

ESP32 S3 Uno pinout diagram

Wiring Diagram

Connect the sensor output to A0 of the ESP32 S3 Uno. Power the sensor from the 3.3V pin.

The wiring diagram between ESP32 S3 Uno soil moisture sensor

This image is created using Fritzing. Click to enlarge image

Soil Moisture Sensor Pin ESP32 S3 Uno Pin
VCC 3.3V
GND GND
AOUT A0 (GPIO2)

WARNING

ESP32 S3 Uno pins are NOT 5V tolerant, and the analog pin can read only up to about 3.3V. Power the sensor from the 3.3V pin, so the AOUT voltage stays inside the safe range. The capacitive sensor works well at 3.3V.

ESP32 S3 Uno Code

This sketch reads the sensor on A0 (GPIO2) every half second and prints the raw moisture value to the Serial Monitor. The ESP32 S3 Uno ADC is 12-bit, so the value goes from 0 to 4095.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-soil-moisture-sensor */ #define AOUT_PIN 2 // ESP32 S3 Uno pin A0 (GPIO2) reads the moisture sensor void setup() { Serial.begin(9600); // Initializes serial communication at 9600 bps // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); } void loop() { int value = analogRead(AOUT_PIN); // Reads the moisture level from the sensor (0-4095) Serial.print("Moisture: "); // Sends the text 'Moisture: ' to the serial monitor Serial.println(value); // Prints the moisture level to the serial monitor delay(500); // Pauses the loop for 500 milliseconds }

The sketch calls analogSetAttenuation(ADC_11db) in setup(). By default, the ESP32 S3 Uno ADC can only measure a small voltage. The 11 dB setting lets the analog pin read the full range, from 0V up to about 3.3V. Without it, the reading hits 4095 too early and the moisture values look wrong.

Detailed Instructions

Do these steps in order:

  1. New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
  2. Wire it up as shown in the diagram.
  3. Connect the board to your computer with a USB Type-C cable.
  4. Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
  5. Copy the code above and paste it into Arduino IDE.
  6. Upload the code by clicking the Upload button.
  7. Test the sensor by pushing it into the soil and then adding water. You can also dip it gently into a cup of salt water.
  8. Open the Serial Monitor at 9600 baud and watch the value go down as the soil gets wet.
  9. Tip: Hold the sensor still while you read the values. Moving it in the soil changes the readings a lot.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
Moisture: 2372 Moisture: 2368 Moisture: 2331 Moisture: 2276 Moisture: 2205 Moisture: 2131 Moisture: 2054 Moisture: 1968 Moisture: 1887 Moisture: 1802 Moisture: 1735 Moisture: 1681 Moisture: 1640 Moisture: 1612 Moisture: 1598 Moisture: 1591 Moisture: 1588
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

※ NOTE THAT:

  • Do not test with pure water. It conducts electricity very poorly, so the readings will not change much.
  • The value usually does not drop to zero. With the sensor at 3.3V, it often stays somewhere between about 1200 and 2400. The exact range depends on how deep the probe is, the type of soil or water, and the supply voltage.
  • Keep the electronic part at the top of the sensor out of the soil and water. Getting it wet can damage the sensor.

Calibration for Capacitive Soil Moisture Sensor

The sensor does not give a fixed "wet" or "dry" number. The value depends on your soil type and how much water it holds. So you need to calibrate it once and find your own cutoff value. We call this value THRESHOLD.

Follow these steps:

  1. Run the code above on the ESP32 S3 Uno.
  2. Put the sensor into dry soil.
  3. Add water slowly to the soil.
  4. Watch the Serial Monitor while the soil gets wetter.
  5. Write down the value at the moment you think the soil changes from dry to wet. This is your THRESHOLD.

Determine if the soil is wet or dry

Now put your THRESHOLD value into the sketch below. The code compares each reading with the threshold. A value above it means dry soil, and a value at or below it means wet soil.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-soil-moisture-sensor */ #define AOUT_PIN 2 // ESP32 S3 Uno pin A0 (GPIO2) for moisture sensor output #define THRESHOLD 1800 // Set threshold value for moisture level (0-4095) void setup() { Serial.begin(9600); // Initialize serial communication at 9600 bps // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); } void loop() { int value = analogRead(AOUT_PIN); // Read value from moisture sensor if (value > THRESHOLD) // Compare sensor reading to threshold Serial.print("The soil is DRY ("); // Print dry status if above threshold else Serial.print("The soil is WET ("); // Print wet status if below threshold Serial.print(value); // Print the sensor reading Serial.println(")"); // Finish the line delay(500); // Wait for half a second before next read }

The value 1800 is only an example. Replace it with the THRESHOLD you found during calibration, then upload the code again. Here is what you will see on the Serial Monitor:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
The soil is DRY (2372) The soil is DRY (2331) The soil is DRY (2205) The soil is DRY (2054) The soil is DRY (1887) The soil is WET (1735) The soil is WET (1681) The soil is WET (1612) The soil is WET (1588)
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

Video Tutorial

Watch the video below to see this ESP32 S3 Uno project step by step.

Function References

FAQ

Can I power the soil moisture sensor from 5V on the ESP32 S3 Uno?

It is better not to. The ESP32 S3 Uno pins are not 5V tolerant, and the analog pin reads only up to about 3.3V. The capacitive sensor works well at 3.3V, so connect VCC to the 3.3V pin.

Why are my ESP32 S3 Uno readings much bigger than the values in Arduino UNO R4 tutorials?

The ESP32 S3 Uno has a 12-bit ADC, so analogRead() gives 0 to 4095. The UNO R4 uses 10-bit by default, which gives 0 to 1023. Also, the sensor runs at 3.3V here. So do not copy a threshold from another board. Calibrate the sensor again.

Why does the code call analogSetAttenuation(ADC_11db)?

This line sets the ESP32 S3 Uno ADC input range to about 0V to 3.3V, so the full sensor signal maps to 0 to 4095. Without it, the range is smaller and the readings reach 4095 too early. The UNO R4 does not need this line, because it is for ESP32 boards only. Keep the sensor output at 3.3V or less.

Which ESP32 S3 Uno pin should I use for the sensor?

Use an analog pin. A0 to A5 all work, and so do some D pins with analog support, like D2, D3, D4, D5 and D7. If you change the pin, write its GPIO number in the code. For example, A1 is GPIO1.

What if my project needs more pins than the Uno headers give?

The ESP32 S3 Uno has two extra rows of holes with more GPIOs. GPIO15 and GPIO16 support I/O, PWM and analog. GPIO45 and GPIO35 to GPIO42 support I/O and PWM. GPIO47 and GPIO48 are output only, with PWM. Solder pin headers to use them, and write the GPIO number in code. For extra soil moisture sensors, use GPIO15 or GPIO16, because they can read analog values. Be careful with two things. First, GPIO47 and GPIO48 may run at 1.8V instead of 3.3V on some modules (mostly ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely. Second, GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.

Can I leave the sensor in the soil all the time?

Yes, the capacitive type is made for this, because its electrodes are covered. Just keep the electronic part at the top dry. You can cover the top edge with tape or hot glue for extra protection.

Troubleshooting

Problem Possible Cause Solution
No COM port in Arduino IDE USB driver missing or board not in download mode Install the CP210x or CH340 driver, use a data USB cable, or hold BOOT while you press RESET
Value is always 0 AOUT wire loose or connected to the wrong pin Check that AOUT goes to A0 (GPIO2) and that the code uses pin 2
Value is always 4095 Missing analogSetAttenuation(ADC_11db) or sensor output too high Add the attenuation line in setup() and power the sensor from 3.3V
Value does not change in water Testing with pure water Use soil or salt water instead
Readings jump a lot Loose wires or the sensor moves in the soil Use short, firm wires and keep the sensor still
Sensor stopped working after watering Water reached the electronic part at the top Dry it fully and keep only the probe part in the soil
Always DRY or always WET THRESHOLD value does not fit your soil Run the calibration again and update THRESHOLD
Serial Monitor shows strange characters Wrong baud rate Set the Serial Monitor to 9600 baud

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!