Introduction: ESP8266 Soil Moisture Sensor for $7

This is a very easy Soil Moisture Sensor. I wanted a waterproof soil moisture sensor so I can setup on my tomato gardens and they were very pricey. Here is one that can be done with very basic parts you probably have at home.

Parts List:

Step 1: Making the Sensor

  1. Cut two pieces of electrical wire, about 6-8 inches in length each and remove about 1-2 inches of the cover.
  2. Cut a couple of small pieces of PCB board so you can use as spacers and solder the wire.
  3. Get a PVC Tube, Cut about 2 inches, you will use this to make your mold.
  4. Mix the Plaster of Paris with a little bit of water until you start to get a nice texture and fill the PVC, once you have a nice fill, insert your electrical wires and let it rest until it is solid.

Step 2: Wiring Schematic

Wiring for the sensor is pretty straight forward.

  • One of the wires to 5V
  • Ground to the other Wire
  • 4.7k Resistor to Ground Line and A0 on your Wemos D1 Mini

Step 3: Fire Up Arduino IDE

For this sketch, you will need Homie 2.0 Firmware which you can download here. You can read the readme how to upload the configuration on the Homie Readme.

Homie is a nice MQTT Framework that basically handles all the hard stuff in handling/reconnecting to WiFi and MQTT connection.

Arduino Sketch

<p>#include <Homie.h><br></p><p>#define FW_NAME "soil-moisture-monitor"
#define FW_VERSION "1.0.0"</p><p>int moistPin = 0;
float knownResistor = 1024;  // Calibrate your high moisture loop</p><p>const int numReadings = 20;
int readings[numReadings];    
int readIndex = 0;              
int total = 0;                 
int average = 0;                
float moisture;</p><p>HomieNode moistureNode("moisture", "moisture");</p><p>int moistVal = 0;
const int SEND_INTERVAL = 300;
unsigned long lastDataSent = 0;</p><p>void loopHandler() {
  if (millis() - lastDataSent >= SEND_INTERVAL * 1000UL || lastDataSent == 0) {
    total = total - readings[readIndex];
    readings[readIndex] = analogRead(moistPin);
    total = total + readings[readIndex];
    readIndex = readIndex + 1;
  
    if (readIndex >= numReadings) {
      readIndex = 0;
    }
  
    average = total / numReadings;
    moisture = float((average / knownResistor) *100);
      
    Serial.println();  
    Serial.print("Resistance: ");
    Serial.print(average);
    Serial.println(" Ω");
  
    Serial.print("Moisture: ");
    Serial.print(moisture);
    Serial.println(" %");
    
    Homie.setNodeProperty(moistureNode, "resistance").send(String(average));
    Homie.setNodeProperty(moistureNode, "moisture").send(String(moisture));</p><p>    lastDataSent = millis();
  }
}</p><p>void setupHandler() {
  
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
  
  Homie.setNodeProperty(moistureNode, "unit").setRetained(true).send("Ω");
  Homie.setNodeProperty(moistureNode, "moisture").setRetained(true).send("%");
  moistureNode.advertise("unit");</p><p>}</p><p>void setup() {
  Serial.begin(115200);</p><p>  Homie_setFirmware(FW_NAME, FW_VERSION);
  Homie.setSetupFunction(setupHandler).setLoopFunction(loopHandler);
  Homie.setup();</p><p>}</p><p>void loop() {
  Homie.loop();
}</p>

Here is my config.json to upload to homie.

  "name": "Tomatoes Soil Moisture",
  <br>   "device_id": "tomatoes-soil-moisture",
  <br>      "wifi": {
    "ssid": "Linksys",
    <br>     "password": "XXXXXXXXXX"
  },
  <br>   "mqtt": {
    "host": "192.168.1.254",
   <br>   "port": 1883,
    <br>   "base_topic": "devices/",
    <br>   "auth": true,
   <br>   "username": "sensor",
    <br>   "password": "sensor1"
  <br>},
  <br>"ota": {  <br> "enabled": true
  }<br>
}

Once you have everything working, the next thing to do is to calibrate the sensor and map the variables to your OpenHab configuration.

Things to do:

  • Solar Powered/Battery

* I maybe compensated for some links.