Arduino Capacitive Soil Moisture Sensor (DIY) with ESP32
Many publications exist about moisture sensors for applications, e.g. plant watering systems. Making a DIY Sensor is fun and cost-saving.
Components and supplies
1
Moisture Level Indicator
1
Capacitor 100 nF
1
Geekworm NodeMCU-32S ESP32S Lua
1
capacitive Soil Moisture Sensor
1
Resistor 1M ohm
1
1N4007 – High Voltage, High Current Rated Diode
1
Resistor 10k ohm
1
Resistor 221 ohm
1
Arduino Mega 2560
Tools and machines
1
Soldering iron (generic)
1
common workshop tools
Apps and platforms
1
Arduino IDE
Project description
Code
Soil_Moisture_Sensor.ino
arduino
1/* 2 This code for a Soil Moisture sensor and a Moist Level Indicator has been developed and produced by Pierre Pennings (December 2018) 3 This application can be used e.g. in automatic plant watering systems 4 The DIY Moisture Sensor uses 2 pieces of fondue forks 5 The DIY Moist Level Indicator is made with 5 (Neopixel) SMD5050 LEDs with WS2812B controller chips powered with 5 V 6 The Moist Level is measured once every second (during 5 seconds) and determines the average of 5 consecutive measurements in 5 different levels 7 The Moist Level Indicator is set to the measured soil moisture level 8 This sketch is written for using 1 Moisture sensor, but in the final Plantwatering project 3 different sensors will be used 9 10 For this Project, an ESP 32 (NodeMCU) is used with 12 Bits ADCs 11 The ESP 32 device works at 3.3 Volt levels, while the Moist Level Indicator runs on 5 V 12 The 5 Level LEDs have been built in a separate indicator Display (indicating 1%, 25%, 50%, 75% and 100% levels) 13 The ESP 32 is fed with 5 V power (from a 5V adaptor or 5v powerbank), it has an on-board 3.3V voltage regulator 14 The 5 indicator LEDs get the 5V supply directly from the 5 volt pin of the ESP 32 15 16 This code is licensed under GPL3+ license. 17*/ 18 19#include <Adafruit_NeoPixel.h> 20#define NUM_LEDS 5 21 22 23///////////////////////////////////////////////// initialise the GPIO pins 24const int IndicatorPin = 16; // pin 16 sends the control data to the LED Moist Level Indicator 25const int ToneOutput1 = 25; // pin 25 is used for sending a 600 kHz PWM tone to the MoistSensor1 measurement circuit 26const int freq = 600000; 27const int Channel1 = 1; 28const int resolution = 8; 29const int MoistSensor1Pin = 4; // 12 bits ADC pin 4 senses the voltage level of the MoistSensor1 (values 0 - 4095) 30 31int level = 0; // Variable of the Moist Level: 1%, 25%, 50%, 75%, 100% 32int Moistlevel1 = 0; // Variable to store the Moist level for sensor 1 33 34byte color_scheme[] = { 35 0, 0, 0, // no color/ off 36 0, 200, 0, // green 37 100, 200, 0, // yellow 38 250, 150, 0, // orange 39 0, 0, 200, // blue 40 200, 0, 0 // red 41}; 42 43Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, IndicatorPin, NEO_RGB + NEO_KHZ800); 44 45/////////////////////////////////////////////////// the setup code that follows, will run once after "Power On" or after a RESET 46void setup() { 47 Serial.begin(115200); 48 ledcSetup(Channel1, freq, resolution); // configure the PWM functionalitites 49 ledcAttachPin(ToneOutput1, Channel1); // attach the channel 1 to the GPIO pin 25 for generating a PWM signal of 600kHz 50 51 pinMode(IndicatorPin, OUTPUT); // Initializes the output pin for the Moist Level Indicator 52 pinMode(MoistSensor1Pin, INPUT); // Initializes the sensor pin (4) for measuring the MoistureLevelValue1 53 54 strip.begin(); // Initialize all LEDs to "off" 55 56 for (int t = 0; t < 5 ; t++) 57 { 58 strip.setPixelColor(t, 100, 100, 100); // After Power On the Moist Level Indicator LEDs are tested once 59 strip.show(); // note that the order of colors of the WS2812 LED strip is R,G,B 60 delay (200); 61 strip.setPixelColor(t, 0, 0, 0); // and back to off 62 } 63 for (int k = 4; k > -1 ; k--) 64 { 65 strip.setPixelColor(k, 100, 100, 100); // blink for 0,2 seconds going top down and then off 66 strip.show(); 67 delay (200); 68 strip.setPixelColor(k, 0, 0, 0); // and back to off 69 } 70} 71 72 73/////////////////////////////////////////////////// the loop code that follows, will run repeatedly until "Power Off" or a RESET 74void loop(){ 75 76 MEASUREMOISTURE1 (); // measure moisture level1 77 INDICATELEVEL (); 78 delay(1000); // wait 1 sec to Check for new values; 79 //this value is just for demonstration purposes and will in a practical application be far less frequent 80} 81//////////////////END of LOOP//////////////////////////////////////////////////////////// 82 83/////////////////////////////////////////////////// Hereafter follows the Function for measuring the Moisture level with MoistSensor1 (capacitive measurement) 84 85void MEASUREMOISTURE1 () { 86 Moistlevel1 = 0; 87 ledcWrite(Channel1, 128); // send a PWM signal of 600 kHz to pin 25 with a dutycycle of 50% 88 delay(200); // allow the circuit to stabilize 89 for (int m = 1; m < 6 ; m++) // take 5 consecutive measurements in 5 seconds 90 { 91 Moistlevel1 = Moistlevel1 + analogRead(MoistSensor1Pin) ; // Read data from analog pin 4 and add it to MoistLevel1 variable 92 delay (1000); 93 } 94 Moistlevel1 = Moistlevel1 / 5; // Determine the average of 5 measurements 95 96 if (Moistlevel1 > 150 && Moistlevel1 < 375){ 97 level = 5; // means moistlevel is 100% 98 Serial.print(" Moistlevel is 100% "); Serial.print(" Moistlevel1 = "); Serial.println (Moistlevel1); 99 } 100 if (Moistlevel1 > 375 && Moistlevel1 < 725){ 101 level = 4; // means moistlevel is 75% 102 Serial.print(" Moistlevel is 75% "); Serial.print(" Moistlevel1 = "); Serial.println (Moistlevel1); 103 } 104 if (Moistlevel1 > 725 && Moistlevel1 < 1075){ 105 level = 3; // means moistlevel is 50% 106 Serial.print(" Moistlevel is 50% "); Serial.print(" Moistlevel1 = "); Serial.println (Moistlevel1); 107 } 108 if (Moistlevel1 > 1075 && Moistlevel1 < 1425){ 109 level = 2; // means moistlevel is 25% 110 Serial.print(" Moistlevel is 25% "); Serial.print(" Moistlevel1 = "); Serial.println (Moistlevel1); 111 } 112 if (Moistlevel1 > 1425 && Moistlevel1 < 1775){ 113 level = 1; // means moistlevel is 1% 114 Serial.print(" Moistlevel is 1% "); Serial.print(" Moistlevel1 = "); Serial.println (Moistlevel1); 115 } 116 ledcWrite(Channel1, 0); // stop generating PWM tones at pin 25 117 } 118 119 120/////////////////////////////////////////////////// Hereafter follows the Function for Indicating the MoistureLevel (called from within the loop) 121 122void INDICATELEVEL () { 123 124for (int t = 0; t < 6 ; t++) 125 { 126 strip.setPixelColor(t, 0, 0, 0); // turn off all LEDs on the Moist Level Indicator 127 strip.show(); 128 } 129 130int redVal, greenVal, blueVal; // Set the Moist Level Indicator LED with a color defined in the Array color_scheme 131 redVal = color_scheme[level*3]; 132 greenVal = color_scheme[level*3 + 1]; 133 blueVal = color_scheme[level*3 + 2]; 134 135 strip.setPixelColor(level-1, strip.Color(redVal, greenVal, blueVal) ); 136 strip.show(); 137 } 138 139
Downloadable files
Fritzing diagram Soil Moisture Sensor
Breadboard set up for measuring soil moisture with a DIY capacitive sensor
Fritzing diagram Soil Moisture Sensor
Fritzing diagram Soil Moisture Sensor
Breadboard set up for measuring soil moisture with a DIY capacitive sensor
Fritzing diagram Soil Moisture Sensor
Comments
Only logged in users can leave comments