4. 土壤湿度传感器选型与校准

在ESP32无线灌溉控制器中,土壤湿度传感器是整个闭环的“感知入口”。它决定了控制器何时开阀、何时停水,也直接决定了系统是否会出现“旱死”或“涝死”两类极端错误。本节围绕三个问题展开:选什么传感器、模拟量怎么接进ESP32、以及如何把一串ADC读数变成可信的“干/湿”判断。

一、电容式与电阻式:先选对原理,再谈精度

常见的低成本土壤湿度传感器分为两大类。电阻式(如常见的两针叉形探头)本质是测量土壤中两个电极之间的导电率:土壤含水越多,离子导电越强,电阻越小。它的优点是电路极简、成本低;缺点是电极长期通直流电会发生电解腐蚀,且读数受土壤盐分、肥料浓度影响极大,同一块地在施肥前后读数可能明显漂移,寿命通常只有几个月到一年。

电容式传感器把探头当作电容的一极,土壤作为介质,通过测量电容值(通常由RC振荡或高频激励转换为电压/频率)反映介电常数,而水的介电常数远高于干土和空气。它的关键优势是电极不直接暴露于直流电解过程,腐蚀慢、寿命长,且对盐分不敏感。缺点是价格略高,且对供电稳定性、探头与土壤的贴合程度更敏感。

对于需要长期埋地、无人值守的灌溉控制器,应优先选择电容式传感器。若使用电阻式,必须采用“间歇供电”方式——只在测量瞬间给探头通电,其余时间断电,以减缓电解腐蚀。

两类土壤湿度传感器的原理与信号链对比 电阻式(导电率型) 两根金属电极插入土壤 含水↑ → 离子导电↑ → 电阻↓ 分压电路 → 模拟电压 受盐分/肥料影响大,电极易腐蚀 使用要点 间歇供电测量,避免长期直流 适合短期/低成本场景 电容式(介电常数型) 探头为电容极板,土壤为介质 含水↑ → 介电常数↑ → 电容↑ 振荡/激励电路 → 电压或频率 对盐分不敏感,电极腐蚀慢 使用要点 保证探头与土壤紧密贴合 推荐用于长期埋地灌溉控制

二、模拟量采集电路:从探头到ADC引脚

多数电容式模块输出0~3.0V左右的模拟电压,可直接接入ESP32的ADC引脚(如GPIO34、GPIO35、GPIO32、GPIO33,这些引脚仅输入、适合做ADC)。接线时注意三点:

  • 供电取3.3V而非5V:ESP32的ADC满量程约3.3V(实际受衰减配置影响),若模块输出5V会超量程甚至损伤引脚。若模块必须5V供电,输出端需用电阻分压到3.3V以内。
  • 共地:传感器GND必须与ESP32 GND相连,否则读数漂浮。
  • ADC衰减配置:ESP32默认衰减下有效量程约0~1.1V,需在代码中设置ADC_ATTEN_DB_11(约0~3.1V),否则高压段会饱和。

ESP32的ADC存在非线性,尤其在量程两端误差较大。工程上不必追求绝对精度,而应关注重复性:同一湿度下多次读数是否稳定。因此采集时通常连续采样多次取中值或均值,并避开0和4095这两个饱和区。

// 示例:ADC初始化与单次读取(参数为教学示例)
#include <driver/adc.h>

void soil_adc_init() {
  adc1_config_width(ADC_WIDTH_BIT_12);          // 12位,0~4095
  adc1_config_channel_atten(ADC1_CHANNEL_6,     // GPIO34
                            ADC_ATTEN_DB_11);   // 量程约0~3.1V
}

int soil_read_raw() {
  return adc1_get_raw(ADC1_CHANNEL_6);          // 返回0~4095
}

三、干湿标定:把ADC值映射为“含水量”

传感器读数本身没有物理意义,必须通过标定建立“ADC值—湿度状态”的对应关系。最实用的两点标定法如下:

  1. 干点标定:取风干土壤装入与现场相同的花盆/土槽,探头插入相同深度,读取稳定后的ADC值,记为raw_dry。示例中假设为3200(电容式模块常见“越干读数越大”)。
  2. 湿点标定:向同一土壤缓慢加水至饱和但不积水,静置10分钟让水分均匀,读取ADC值,记为raw_wet。示例中假设为1400。

随后用线性映射把原始值转换为0~100%的相对湿度:

// 示例标定参数(需按实际土壤重新测定)
const int RAW_DRY = 3200;   // 风干土读数
const int RAW_WET = 1400;   // 饱和土读数

float to_percent(int raw) {
  float p = (float)(RAW_DRY - raw) * 100.0f
          / (float)(RAW_DRY - RAW_WET);
  if (p < 0)   p = 0;
  if (p > 100) p = 100;
  return p;
}

注意:不同土壤(沙土、壤土、黏土)的干湿点差异很大,换土必须重新标定。标定值应写入配置区或NVS,而不是散落在代码里。灌溉阈值一般设在相对湿度的30%~40%启动、60%~70%停止,具体依作物而定。

四、数据滤波:让判断不被噪声带偏

土壤湿度变化缓慢,但ADC读数会因电源波动、探头接触、无线发射瞬间的电流冲击而出现尖峰。直接拿单次读数做判断,容易误开阀。推荐两级处理:

  • 中值滤波:连续采5次,去掉最大最小后取中间3个的平均,可有效剔除偶发尖峰。
  • 一阶低通/滑动平均:对中值结果再做平滑,例如filtered = 0.8 * filtered + 0.2 * new,让输出跟随真实趋势而不被单次扰动拉动。

此外,测量应避开Wi-Fi发射窗口:可在发送数据前后各延时数十毫秒再采样,或把采样安排在两次上报之间。滤波后的百分比再与阈值比较,并加入“连续N次低于阈值才开阀”的去抖条件,可显著降低误动作。

标定与滤波的验收方法:把探头插在稳定湿度的土中静置,观察串口输出的百分比在1分钟内波动是否小于±3%;再人为拔插探头制造扰动,滤波后的曲线应平缓恢复,而不是跟着尖峰跳变。满足这两点,才说明采集链路可用于灌溉决策。

把以上环节串起来,一条可靠的感知链就是:选电容式探头 → 3.3V供电与正确衰减配置 → 干湿两点标定得到映射参数 → 中值加低通滤波 → 去抖后输出湿度百分比。后续的阀门控制逻辑,都建立在这条链路输出的可信数值之上。