Soil Moisture Sensor
The soil moisture module is a simple water sensor that can be used to detect the moisture of soil. The surface is nickel-plated so it is not easy to rust, which extends its service life. The wide sensing area improves conductivity. The module has a dual output mode: digital quantity output is simple, and analog quantity output is more accurate. The sensitivity is adjustable (the blue potentiometer in the figure adjusts the threshold). The comparator uses the LM393 chip, which works stably and produces a clean signal. It has fixed bolt holes for easy installation. Use this sensor to make an automatic watering device so that the plants in your garden do not need manual management.
Module Source
Purchase link: https://detail.tmall.com/item.htm?abbucket=15&id=691640308824&ns=1&spm=a21n57.1.0.0.76ea523cQF7VPZ Materials download link: https://pan.baidu.com/s/1HJ3WhTG6dpNf-BdgW3zLlg?pwd=8889 Materials extraction code: 8889
Specifications
Operating voltage: 3.3V-5V Operating current: 150MA Output method: DO interface for digital output, AO interface for analog output Read method: ADC Number of pins: 4 Pin (2.54mm pitch pin header)
View Materials
- The sensor is suitable for soil moisture detection;
- The blue potentiometer on the module is used to adjust the soil moisture threshold. Turning it clockwise increases the controlled humidity, while turning it counterclockwise decreases it;
- The digital output DO can be directly connected to the microcontroller. The microcontroller detects the high and low levels to thereby detect soil moisture;
- The small board analog output A0 can be connected to the AD module. Through AD conversion, more accurate values of soil moisture can be obtained;
The principle is to insert the fork that comes with the module into the soil. When there is sufficient moisture, it conducts electricity, and the water in the soil connects the two ends of the fork. You can do a small experiment: take a metal object and place it against the fork to short the two ends of the fork, and you will find that the DO_LED on the module lights up.
Porting Process
Pin Selection
Port to Project
Our goal is to port the example to the ESP32-S3 dev board. Complete driver code has been provided for you. Follow the steps below to complete the porting. For detailed instructions on creating folders and new .c and .h files, refer to section 1.4.2 in the [DHT11 Temperature and Humidity Sensor] chapter; we will not repeat it here. However, here we change the file names bsp_dht11.c and bsp_dht11.h to bsp_soilHumidity.c and bsp_soilHumidity.h, and rename the folder to SoilHumidity.
Write Code
In the file bsp_soilHumidity.c, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2023-11-02 LCKFB-yzh first version
*/
#include "bsp_soilHumidity.h"
esp_adc_cal_characteristics_t *adc_chars;
static void delay_ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
static void delay_us(unsigned int us)
{
ets_delay_us(us);
}
static void delay_1ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
static void delay_1us(unsigned int us)
{
ets_delay_us(us);
}
/******************************************************************
* Function Name: ADC_Init
* Function Description: Initialize ADC function
* Function Parameters: none
* Function Return: none
* Author: LC
* Notes: none
******************************************************************/
void ADC_Init(void)
{
gpio_config_t IN_config = {
.pin_bit_mask = (1ULL<<GPIO_SH_DO), //Configure pin
.mode =GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_DISABLE, //Disable pull-up
.pull_down_en = GPIO_PULLDOWN_DISABLE, //Disable pull-down
.intr_type = GPIO_INTR_DISABLE //Disable pin interrupt
};
gpio_config(&IN_config);
adc1_config_width(width);// 12-bit resolution
//ADC_ATTEN_DB_0: indicates reference voltage is 1.1V
//ADC_ATTEN_DB_2_5: indicates reference voltage is 1.5V
//ADC_ATTEN_DB_6: indicates reference voltage is 2.2V
//ADC_ATTEN_DB_11: indicates reference voltage is 3.3V
//adc1_config_channel_atten( channel,atten);// Set channel 0 and 3.3V reference voltage
// Allocate memory
adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
// Initialize ADC characteristics so that conversion results and compensation factors can be calculated correctly
esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
}
/******************************************************************
* Function Name: Get_Adc_Value
* Function Description: Calculate the average of data and output
* Function Parameters: CHx = which scanned data
* Function Return: corresponding scanned ADC value
* Author: LC
* Notes: none
******************************************************************/
unsigned int Get_Adc_Value(char CHx)
{
unsigned char i = 0;
unsigned int AdcValue = 0;
/* Since it samples SAMPLES times, loop SAMPLES times */
for(i = 0; i < SAMPLES; i++)
{
/* Accumulate */
AdcValue += adc1_get_raw(CHx);
}
/* Calculate the average */
AdcValue = AdcValue / SAMPLES;
return AdcValue;
}
/******************************************************************
* Function Name: Get_SH_Percentage_value
* Function Description: Read value and return percentage
* Function Parameters: none
* Function Return: returns percentage
* Author: LC
* Notes: none
******************************************************************/
unsigned int Get_SH_Percentage_value(void)
{
int adc_max = 4095;
int adc_new = 0;
int Percentage_value = 0;
adc_new = Get_Adc_Value(channel);
Percentage_value = ((float)adc_new/adc_max) * 100;
return Percentage_value;
}
/******************************************************************
* Function Name: Get_SH_DO_value
* Function Description: Get the pin level state
* Function Parameters: none
* Function Return:
* Author: LC
* Notes: Adjust the sliding resistor on the module to adjust sensitivity
******************************************************************/
char Get_SH_DO_value(void)
{
if( gpio_get_level(GPIO_SH_DO) == 0 )
{
return 0;
}
else
{
return 1;
}
return 3;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
In the file bsp_soilHumidity.h, write the following code.
#ifndef _BSP_SOILHUMIDITY_H_
#define _BSP_SOILHUMIDITY_H_
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_rom_sys.h"
#include "esp_timer.h"
#include "driver/uart.h"
#include "rom/ets_sys.h"
#include "esp_system.h"
#include "driver/gptimer.h"
#include "esp_log.h"
#include "freertos/queue.h"
#include "driver/spi_master.h"
#include "nvs_flash.h"
#include "esp_adc/adc_cali_scheme.h"
#include "esp_adc/adc_cali.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#define GPIO_SH_AO 1
#define GPIO_SH_DO 2
#define DEFAULT_VREF 1100 //Default reference voltage, unit mV
#define channel ADC_CHANNEL_0 // ADC measurement channel
#define width ADC_WIDTH_BIT_12 // ADC resolution
#define atten ADC_ATTEN_DB_11 // ADC attenuation
#define unit ADC_UNIT_1 // ADC1
//Number of samples
#define SAMPLES 30
void ADC_Init(void);
unsigned int Get_Adc_Value(char CHx);
unsigned int Get_SH_Percentage_value(void);
char Get_SH_DO_value(void);
#endif2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Porting Verification
In the main function of your own project, write the following code.
/*
* LCSC-Openkits (LCKFB) software and hardware materials and related expansion board software and hardware materials are all open source on the official website.
* Dev board official website: www.lckfb.com
* Technical support resides on the forum; any technical questions are welcome for exchange and learning at any time.
* LCKFB Forum: club.szlcsc.com
* Follow our Bilibili account: [LCSC-Openkits (LCKFB)] to keep up with our latest updates!
* We do not make money by selling boards; we take cultivating engineers as our mission.
* Change Logs:
* Date Author Notes
* 2024-01-16 LCKFB-lp first version
*/
#include <stdio.h>
#include "bsp_soilHumidity.h"
#include "string.h"
#include "esp_private/esp_task_wdt.h"
#include "esp_private/esp_task_wdt_impl.h"
int app_main(void)
{
esp_task_wdt_deinit();
ADC_Init();
printf("Start.......\r\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
while(1)
{
printf("Soil Humidity = %d\r\n", Get_SH_Percentage_value() );
if( Get_SH_DO_value() == 0 )
{
printf("DO = 0 \r\n");
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Power-on effect:
Driver code:
File Download
📌 Materials Download Center (click to jump)
📌 In the Materials Download Center -> Module Porting Materials Download, inside the compressed package of this chapter.