4. 传感器数据校准:干土与湿土实验
好了,到了这一步,你的土壤湿度传感器应该已经能读出数据了。但有个问题——你读到的数值到底代表什么?是湿还是干?
说实话,不同品牌、不同批次的传感器,甚至同一块传感器插在不同土里,读数都可能不一样。我刚开始做智能浇花项目时,就吃过这个亏。买了一批传感器,以为所有阈值都一样,结果有的花淹死了,有的旱死了。嗯,从那以后,我养成了一个习惯:每换一次传感器,必须重新校准。
4.1 为什么需要校准?
土壤湿度传感器本质上是一个可变电阻。土壤含水量越高,导电性越好,输出的模拟值就越低(或越高,取决于你的接法)。但问题是:
- 传感器个体差异:同一型号的传感器,输出值可能偏差10%~20%
- 土壤类型不同:沙土、黏土、腐殖土的导电性完全不同
- 温度影响:温度变化会影响土壤的导电率
说白了,你不能拿别人的阈值直接套用。我见过有人直接复制网上的代码,结果传感器一直报"土壤干燥",其实花盆里都快积水了。这就是没校准的后果。
4.2 校准实验:干土与湿土
校准的原理其实很简单:测出传感器在完全干燥和完全湿润时的读数,然后取中间值作为浇水临界点。
我个人习惯做三次实验取平均值,这样更靠谱。下面是具体步骤:
实验一:干土测量
- 取一些干燥的土壤(可以放烤箱里100℃烘30分钟,或者阳光下晒一天)
- 将传感器完全插入干土中,深度约2~3厘米
- 等待10秒,让读数稳定
- 记录下此时的模拟值,记为
dryValue - 重复三次,取平均值
实验二:湿土测量
- 将干土慢慢加水,直到土壤完全湿润(表面有水渗出但不要积水)
- 同样插入传感器,等待10秒
- 记录此时的模拟值,记为
wetValue - 重复三次,取平均值
4.3 计算浇水临界值
有了干土值和湿土值,临界值怎么算?很简单:
// 假设你的传感器是:越湿数值越低
// 干土值:2800,湿土值:1200
// 临界值取中间偏干一点的位置
int threshold = dryValue - (dryValue - wetValue) * 0.6;
// 或者更保守一点:
int threshold = dryValue - (dryValue - wetValue) * 0.7;
为什么取60%~70%的位置?你想想看,如果取50%,那土壤稍微干一点就触发浇水,容易浇过头。我一般取60%,也就是土壤含水量降到40%以下时开始浇水。这样既不会让植物旱着,也不会涝着。
| 土壤状态 | 典型数值范围 |
|---|---|
| 完全干燥 | 3000~3500 |
| 正常偏干 | 2500~3000 |
| 正常湿润 | 1500~2500 |
| 完全湿润 | 800~1500 |
| 水中 | 300~800 |
注意:这只是参考值,你的传感器可能完全不同!
4.4 编写校准程序
接下来,我们写一个简单的校准程序。这个程序会读取传感器值,并打印到串口监视器上。你只需要观察数值变化,手动记录干湿阈值。
// 校准程序:土壤湿度传感器阈值测定
// 适用于ESP32 + 土壤湿度传感器(模拟输出)
#define SOIL_SENSOR_PIN 34 // ADC引脚
void setup() {
Serial.begin(115200);
Serial.println("=== 土壤湿度传感器校准程序 ===");
Serial.println("请将传感器插入干土中,等待读数稳定...");
Serial.println("10秒后开始读取数据");
delay(10000);
}
void loop() {
int sensorValue = analogRead(SOIL_SENSOR_PIN);
// 将原始值转换为百分比(假设干土=0%,湿土=100%)
// 注意:这里需要你手动填入干湿阈值
// 先打印原始值,后面再计算百分比
Serial.print("原始ADC值: ");
Serial.print(sensorValue);
// 简单的湿度百分比估算(临时用)
// 等你知道干湿阈值后,替换下面的数值
int dryThreshold = 3000; // 临时值,需要你实际测量后修改
int wetThreshold = 1200; // 临时值,需要你实际测量后修改
int moisturePercent = map(sensorValue, dryThreshold, wetThreshold, 0, 100);
moisturePercent = constrain(moisturePercent, 0, 100);
Serial.print(" | 湿度百分比: ");
Serial.print(moisturePercent);
Serial.println("%");
delay(1000); // 每秒读取一次
}
dryThreshold和wetThreshold是临时值。你必须先运行程序,观察干土和湿土时的实际ADC值,然后替换掉这两个数值。我曾经见过有人直接复制代码没改,结果阈值完全不对,浇花系统直接罢工了。
4.5 避坑指南
做校准实验时,有几个坑我踩过,分享给你:
- 传感器不要插太深:插到底容易碰到花盆底部的积水,读数会偏低。我一般插2~3厘米深。
- 等待读数稳定:刚插入传感器时,数值会跳动。等5~10秒,数值稳定了再记录。
- 不要用手捏传感器:手上的汗液会影响导电性。拿传感器时捏塑料部分,别碰金属探针。
- 多次测量取平均:一次测量可能有误差。我习惯测三次,取平均值作为最终阈值。
4.6 最终确定临界值
假设你测出来的数据是这样的:
- 干土平均值:
dryAvg = 2850 - 湿土平均值:
wetAvg = 1150
那么浇水临界值可以这样算:
// 方法一:按比例取60%位置
int threshold = dryAvg - (dryAvg - wetAvg) * 0.6;
// = 2850 - (2850 - 1150) * 0.6
// = 2850 - 1700 * 0.6
// = 2850 - 1020
// = 1830
// 方法二:直接取中间值(更保守)
int threshold = (dryAvg + wetAvg) / 2;
// = (2850 + 1150) / 2
// = 2000
我个人推荐方法一,也就是取60%的位置。这样当土壤湿度降到40%以下时,系统就会启动浇水。既不会让植物干死,也不会因为频繁浇水导致烂根。
好了,校准这一步做完,你的传感器就有了"灵魂"。它知道什么是干、什么是湿,什么时候该浇水。下一章,我们会把这些阈值写进自动灌溉的逻辑里,让ESP32真正开始"思考"什么时候该浇水。