If you ever tried to measured soil humidity. You come across the ESP32 Soil Sensor PCB. It’s quite pricy for $20. I could not find a lot of documentation for this particular sensor. So, I decided to by one and test them. The first part is all about getting the data.

Pinout

ESP 32 PinFunction
22DHT Out
32 (A4)Soil Sensor Voltage
ESP32 Soil Sensor Pinout

Libraries

I’m using the Adafruit DHT Sensor library. For, need both libs in the dependencies.

  • adafruit unified sensor (Arduino | PlatformIO)
  • adafruit DHT Sensor
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = 
	adafruit/DHT sensor library@^1.4.4
	adafruit/Adafruit Unified Sensor@^1.1.6

Serial Test Code

The test Code is elementary. Get the data and print the data out. Thanks to the library, we don’t have to care about the DHT11 Protocol.

#include <Arduino.h>
#include <DHT.h>

#define DHT11_PIN 22
#define SOIL_PIN A4

DHT dht(DHT11_PIN, DHT11);

void setup() {
  dht.begin();
  Serial.begin(9600);
  delay(1000);
}

void loop() {
  Serial.print("Soil Humidity raw value: ");
  Serial.print(analogRead(SOIL_PIN));
  Serial.print("\t");
  //use the functions which are supplied by library.
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
  Serial.println("Failed to read from DHT sensor!");
  return;
  }
  // print the result to Terminal
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println(" *C ");

  delay(5000);
}

Soil Sensor Calibration

This code outputs only the raw value from the soil sensor. But why?

The ADC has 4096 values, I measure a value from 2500. The soil humidity is 2500/4096 ยท 100% = 61% right?

Wrong! The Sensor covers not the full range of 0.0 to 3.3 volts. Dry does not mean 3.3V, and wet does not mean 0V. Fortunately, we can measure wet pretty easy. We just have to stick the sensor in water. The resulting value is the 100% Water value and our lower bound.

In my case, the lowest values was 1003 (in Water) and the highest was 3120 (Air only). With the map function, we can map the ratio from 1003…3120 to 0..100%.

#define SOIL_WATER_VALUE 1003
#define SOIL_AIR_VALUE 3120

...
void loop() {
  ...
   Serial.print(map(analogRead(SOIL_PIN), SOIL_AIR_VALUE, SOIL_WATER_VALUE, 0, 100));
  ...
}

Full Code

#include <Arduino.h>
#include <DHT.h>

#define DHT11_PIN 22
#define SOIL_PIN A4

#define SOIL_WATER_VALUE 1200
#define SOIL_AIR_VALUE 3500

DHT dht(DHT11_PIN, DHT11);

void setup() {
  dht.begin();
  Serial.begin(9600);
  delay(1000);
}

void loop() {
  Serial.print("Soil Humidity: ");
  Serial.print(map(analogRead(SOIL_PIN), SOIL_AIR_VALUE, SOIL_WATER_VALUE, 0, 100));
  Serial.print(" %\t");
  //use the functions which are supplied by library.
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
  Serial.println("Failed to read from DHT sensor!");
  return;
  }
  // print the result to Terminal
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println(" *C ");

  delay(5000);
}