最近在折腾阳台自动浇花的小项目,手里正好用到了MH-Sensor-Series这块土壤湿度传感器。说实话,这块模块在Arduino圈子里算是老熟人了,便宜、皮实、资料多,新手和老手都绕不开它。很多朋友拿到手之后第一反应是往土里一插、接上A0引脚、打开串口,结果发现读数要么一直是1023,要么跳得跟心电图似的,完全不知道该怎么分析。这篇文章我就从拿到一块全新的MH-Sensor-Series开始,把从接线、原理、调试到实际应用的完整流程捋一遍,顺便把我踩过的坑和总结下来的经验一并写出来。
这套调试方法不仅适用于MH-Sensor-Series这一款,市面上绝大多数电阻式土壤湿度传感器模块(不管是蓝板还是黑板,只要板载了LM393比较器的)基本都通用。无论你是想做自动浇花、宿舍绿植守护、还是毕设里的土壤监测节点,看完这篇文章都能直接上手复现。我会把每个操作背后的原理也讲清楚,这样遇到异常情况时你知道该查哪里,而不是靠瞎试。
1. 整体设计与思路拆解
1.1 为什么选择MH-Sensor-Series这块传感器
先说结论:MH-Sensor-Series系列的土壤湿度传感器板,本质上是一个“电阻式湿度检测探头 + LM393电压比较器”的组合模块。它在淘宝上零售价大概几块钱到十几块钱,和Arduino UNO、Nano、ESP32等主控都能无缝对接。选择它做入门级土壤湿度检测,主要有三个原因。
第一是输出信号友好。模块同时引出AO(模拟量输出)和DO(数字量输出)两个引脚,AO可以直接接主控的ADC引脚读取连续的湿度值,DO可以配合板载电位器设定阈值,输出干净的高低电平。这个设计对调试非常友好,你既可以用模拟量做精细化监测,也可以用数字量做简单的阈值触发。
第二是供电要求低。标准工作电压在3.3V到5V之间,Arduino UNO的5V引脚直接就能喂饱它,不需要额外的电平转换电路。第三是替换成本低。探头部分是裸露的PCB铜箔走线,长期埋在土里迟早会被电解腐蚀,坏了直接换一块新的就行,不心疼。我在实际项目中通常会把传感器归类为“耗材”,备上两三块轮着用。
1.2 常见误区:它到底测的是什么
很多新手拿到这块传感器会误以为它能直接测出“土壤绝对含水量百分比”,其实不然。MH-Sensor-Series测的是土壤的导电特性,也就是两个电极之间电阻的变化。土壤越湿,水分越多,离子导电性越强,两极板之间的等效电阻越小;土壤越干,电阻越大。模块上的AO引脚输出的是分压后的电压值,这个电压随着电阻变化而改变,主控通过ADC采样得到0到1023之间的数字量。
所以它本质上是一个“相对湿度指示器”,而不是精密的科学仪器。你需要先在自己的使用场景里标定几个参考点(比如“干土”、“湿润土”、“刚浇透水”对应的ADC值),再根据这几个点的数据去判断当前土壤处于什么状态。这一点我在第3章的校准环节会详细说明,但请你从一开始就建立这个认知:不要迷信绝对数值,要建立属于自己的参考坐标系。
1.3 系统整体架构与硬件清单
我在这个项目里最终搭出来的系统是这样一条链路:
土壤湿度传感器(感知层) -> Arduino UNO(采集与逻辑处理) -> 串口输出/OLED显示/继电器控制(表现层)
如果你想做一个最简单的“湿度探测仪”,只要传感器加Arduino再加一根USB线就够了。但既然目标是“从调试到应用”,我建议你按下面的完整清单备料,这样一套下来既能练手调试,也能直接扩展成一个小型自动浇花装置。
| 硬件 | 数量 | 用途说明 |
|---|---|---|
| Arduino UNO(或Nano) | 1块 | 主控,读取传感器数据并处理 |
| MH-Sensor-Series土壤湿度传感器 | 1-2块 | 采集土壤湿度,建议备一块备用 |
| 面包板 | 1块 | 方便接线和测试 |
| 杜邦线(公对公/公对母) | 若干 | 连接模块与主控 |
| 0.96寸OLED显示屏(I2C) | 1块(可选) | 本地显示湿度数据 |
| 继电器模块 | 1个(可选) | 控制小水泵实现自动浇水 |
| 小水泵(3-6V直流) | 1个(可选) | 执行浇水动作 |
| 蜂鸣器模块或LED | 1个(可选) | 阈值提醒 |
2. 核心细节解析与实操要点
2.1 引脚定义与接线详解
MH-Sensor-Series模块通常引出4个引脚,不同卖家丝印可能略有差异,但功能和位置基本一致。引脚含义如下表所示:
| 引脚名称 | 功能说明 | 接线目标 |
|---|---|---|
| VCC | 模块供电正极 | 接Arduino 5V或3.3V |
| GND | 模块供电负极 | 接Arduino GND |
| DO | 数字量输出(TTL电平) | 接Arduino数字引脚(如D2) |
| AO | 模拟量输出(0-VCC) | 接Arduino模拟引脚(如A0) |
接线这一步,我的建议是“分步走”。第一次通电测试,先不要急着把DO和AO全部接上,只接VCC、GND和AO三根线,用模拟量做基础读数。为什么?因为DO那边牵扯到电位器阈值的调节,如果一开始两个输出都接上,一旦读数异常你很难定位是哪一路出了问题。先把模拟量这条最简单的链路打通,拿到正常读数之后,再接DO做数字量验证,排查范围小,心态也稳。
实际接线就三根杜邦线的事,AO插入A0,VCC接5V,GND接GND。模块上的电源指示灯会亮起,把探头插到土里,打开Arduino IDE的串口监视器,就能看到数据在动了。
2.2 模拟量与数字量的本质区别
这里必须花点篇幅把AO和DO的区别讲透,因为这是后面所有调试的基础。
AO是连续变化的模拟信号,电压范围在0到VCC之间。当土壤湿度变化时,AO引脚电压会连续变化,Arduino通过analogRead()读取该引脚,返回0到1023的整数值。注意一个关键点:土壤越湿,AO读数越小。这是由模块上的分压电路决定的——探头电阻变小,导致AO点被拉得更接近GND。很多新手第一次测试,看到干燥土壤的读数是800多,一浇水反而降到200多,就以为传感器坏了,其实这恰恰是正常现象。
DO是数字量输出,内部通过LM393比较器把AO电压和一个由电位器设定的参考电压做比较。当AO电压高于参考电压时(对应土壤较干),DO输出一个电平;当AO电压低于参考电压时(对应土壤较湿),DO翻转成另一个电平。电位的旋转方向决定了阈值位置。关于DO和AO哪个“越湿越低”还是“越干越低”,不同板上比较器接法可能相反,我一般是直接用实测数据来确认当前这块板子的逻辑,不做假设。
2.3 板载电位器到底在调什么
模块上那个蓝色的十字可调电位器,看起来像个神秘旋钮,实际就是给LM393比较器提供一个可调的参考电压。旋转电位器,实际上是改变DO翻转时对应的土壤湿度阈值。
调节方法很简单:把探头插入一块湿度适中的土壤,然后用一字螺丝刀慢慢旋转电位器,找到DO刚好翻转的位置。如果你手里没有土壤,也可以用一杯水代替,把探头放进水里观察DO的变化。需要注意,调节电位器时动作一定要轻,这种小型电位器本身不精密,转多了容易损坏,万一转坏了整个板子的DO功能就废了,AO功能倒不受影响。
我的习惯是用万用表配合调节:将万用表打到直流电压档,黑表笔接GND,红表笔接AO,然后旋电位器,观察电压值,这样能精确地定位翻转点。
2.4 接线与供电的硬性注意事项
这块传感器虽然便宜,但有几个硬性坑必须提前避开。
第一,探头是裸露金属,不能在通电状态下长时间泡在水里,否则电解反应会加速腐蚀电极。这点在“应用”阶段特别重要,我后面会给出一个解决思路:通过主控引脚间歇性给传感器供电,用几分钟一次的频率采样,而不是让它7x24小时通电。
第二,VCC接5V还是3.3V需要想清楚。接5V时AO输出范围更大,分辨率略高;接3.3V时AO最高电压不会超过3.3V,如果你的主控是5V容忍引脚的Arduino UNO,怎么接都安全。但如果你用的是ESP32、STM32这类3.3V主控,千万不要把传感器VCC接5V后直接让AO引脚对接3.3V的ADC引脚,可能损坏引脚。稳妥做法是模块和主控同用3.3V供电,或者另做分压。
第三,传感器底部的走线没有完全封胶,如果故意泡水或者插土过深导致底部短路,读数会变得极不稳定甚至烧毁。我一般会在探头底部涂一层透明的热熔胶或绝缘漆做保护。
3. 实操过程与核心环节实现
3.1 Arduino IDE环境的准备与常见坑
调试Arduino项目之前,先把开发环境弄利索。去arduino官网下载Arduino IDE,我推荐安装1.8.x系列的稳定版本,稳定、插件兼容性好;如果你喜欢新界面,2.x版本也可以,功能更强一些,但对老电脑稍有卡顿。安装包下载下来正常安装即可,Windows下如果板子插上去没有识别到串口,十有八九是CH340/CH341驱动没装好,去驱动网站上搜CH340驱动装上,重启IDE再选端口。
还有个高频问题:点了上传按钮后提示“avrdude: stk500_getsync() attempt 1 of 10: not in sync”之类的报错。这个报错90%是端口没选对或者板子型号没选对,先到“工具-开发板”里确认当前选的是Arduino Uno,到“工具-端口”里确认选的是实际识别的COM口。如果都对了还报错,拔掉板子重新插一次,或者重启IDE再来。这里提一句,如果你手头暂时没有实体板子,也可以用Wokwi在线仿真平台练手,选好Arduino Uno和土壤传感器模块,代码逻辑完全一样,非常适合验证思路。
3.2 第一步测试:读取AO并输出到串口
先把最简单的代码烧进去,目标是让Arduino读取AO引脚数值并通过串口打出来。新建一个Arduino工程,复制粘贴下面这段代码:
#define SOIL_AO A0 void setup() { Serial.begin(9600); pinMode(SOIL_AO, INPUT); Serial.println("MH-Sensor-Series Soil Sensor Demo"); } void loop() { int sensorValue = analogRead(SOIL_AO); Serial.print("Raw ADC value: "); Serial.println(sensorValue); delay(500); }代码很简单,我解释一下每部分的作用。pinMode(SOIL_AO, INPUT)这句其实可写可不写,模拟引脚默认就是输入模式,写上是为了语义清晰。analogRead(SOIL_AO)负责把AO引脚的电压转换成0到1023的整数,0对应0V,1023对应5V(如果你的板载ADC是10位分辨率的AVR芯片,比如UNO上的ATmega328P)。delay(500)控制采样频率是每0.5秒读一次,太快的采样没必要,土壤湿度本身是慢变量。
上传成功后打开“工具-串口监视器”,右下角波特率选9600,你就能看到一行一行的数值刷出来。把探头分别插进干燥土壤、湿润土壤和一杯水里,观察数值变化。正常情况下干燥土壤读数偏高,湿润土壤读数降低,泡水读数会掉到很低。如果你的读数完全不变,立刻检查接线和供电,而不是怀疑代码。
这里有个进阶技巧:串口监视器看数值变化不够直观,可以用“工具-串口绘图器”(Serial Plotter),它会以波形的形式把数据实时画出来。把探头从干土插到湿土,你能直接看到一条下降的曲线,这种感觉比看数字痛快得多,也更容易判断信号是否平稳。
3.3 第二步校准:建立自己的湿度参考坐标系
拿到原始ADC数值之后,接下来要做的不是急着接继电器,而是先校准。这一步决定你后续所有判断的准确度。
我用的是“三点校准法”。准备三个样品:一杯干燥的干土(可以放在太阳下晒过或用吹风机吹干)、一杯正常湿润的园艺土(手捏成团但不出水)、一杯清水。把探头分别插入三个样品中,等串口数值稳定30秒,各记录10个读数,取平均值,得到下面这样一张表:
| 样品状态 | 实测ADC均值 | 相对湿度体会 |
|---|---|---|
| 干燥土 | 780 | 很干,需要浇水 |
| 湿润土 | 420 | 正常偏好区间 |
| 清水 | 180 | 过湿/泡水 |
记录完之后,你手上就有了自己设备的“标定曲线”。注意不同模块、不同土壤类型、不同供电电压都会影响这组数据,所以不要直接照抄网上的阈值,一定要自己测一遍。校准还有一个作用:如果同一块板子隔了很久再使用,读数基线可能会漂移,重新校准一次就能校正。
有了校准数据之后,可以将原始ADC值映射成“相对湿度百分比”。我的做法是用一次线性映射,把干燥时的读数当作0%,把清水时的读数当作100%:
int dryValue = 780; int wetValue = 180; int percent = map(sensorValue, dryValue, wetValue, 0, 100); percent = constrain(percent, 0, 100);代码里map()函数把干燥时的780映射为0%,把湿润时的180映射为100%。constrain()是限幅函数,防止个别异常值把百分比拉到负数或超过100%。我在串口输出里把原始值和百分比一起打印出来,调试阶段这样最直观。
3.4 第三步数据平滑:为什么读数会跳变
原始ADC值在实际使用中不会特别平稳,土壤本身是不均匀介质,探头周围的水分分布、颗粒接触状态都在变,加上电磁干扰等因素,读数会出现几到几十的随机波动。如果拿这个跳变的数据去控制水泵,就会出现“水泵启动-停止-又启动”的抖动现象,非常烦人。
解决办法是软件滤波。这里我推荐两种比较适合新手的方案。
第一种是简单滑动平均。维护一个长度为10的数组,每来一个新采样值就把它塞进数组末尾,同时丢掉最早的一个,最后对整个数组求平均值:
const int numReadings = 10; int readings[numReadings]; int readIndex = 0; long total = 0; int average = 0; void setup() { Serial.begin(9600); for (int i = 0; i < numReadings; i++) { readings[i] = 0; } } void loop() { int sensorValue = analogRead(A0); total = total - readings[readIndex]; readings[readIndex] = sensorValue; total = total + readings[readIndex]; readIndex = (readIndex + 1) % numReadings; average = total / numReadings; Serial.println(average); delay(200); }第二种是“中值滤波”,连续读5次,取中间值。这种方式对消除毛刺特别有效,因为中值不会像平均值那样被极端值拉偏。我个人在土壤湿度这种慢变化场景中更喜欢滑动平均,代码简单且平滑效果足够。
滤波之后,数据会表现出非常自然的趋势,这时候再去做阈值判断,控制逻辑才会稳定。
3.5 应用一:灯光与蜂鸣器阈值提醒
调试和校准都通过之后,就可以开始做实际应用了。最简单的应用是把湿度信息转成直观的提醒信号。规划逻辑如下:实时读取校准后的湿度百分比,如果低于25%(对应干土),点亮红色LED并让蜂鸣器间隔鸣叫,提示“该浇水了”;如果介于25%到70%之间,点亮绿色LED,表示状态良好;如果高于90%,代表水分接近饱和,点亮蓝色LED,提示停止浇水。
接线方面,把LED和蜂鸣器通过220欧限流电阻接到数字引脚D8、D9、D10和D11上。参考代码结构如下:
#define LED_DRY 8 #define LED_OK 9 #define LED_WET 10 #define BUZZER 11 void setup() { pinMode(LED_DRY, OUTPUT); pinMode(LED_OK, OUTPUT); pinMode(LED_WET, OUTPUT); pinMode(BUZZER, OUTPUT); } void loop() { int percent = getSoilPercent(); if (percent < 25) { digitalWrite(LED_DRY, HIGH); digitalWrite(BUZZER, HIGH); delay(200); digitalWrite(BUZZER, LOW); } else if (percent < 70) { digitalWrite(LED_OK, HIGH); } else { digitalWrite(LED_WET, HIGH); } delay(500); }getSoilPercent()这个函数就是把前面滤波、映射、限幅的代码封装起来,返回一个0到100的整数。提醒功能的价值在于,你不需要一直盯着手机或电脑看数据,传感器自己就能告诉你目前的水分状态。
3.6 应用二:自动浇花装置完整实现
阈值提醒只是“告诉人”,自动浇花则是让系统代替人做决策。这部分的执行器我用了一个3-6V直流小水泵,中间串联一个继电器模块。需要特别注意,水泵的电流远超Arduino引脚能承受的电流,绝对不能直接接数字引脚,必须通过继电器或MOS驱动模块来开关。
接线逻辑如下:Arduino的D7引脚接继电器的IN端,继电器VCC接5V、GND接GND,水泵正极接继电器公共端COM,水泵负极接电源负极。水泵电源建议独立供给(比如3节5号电池或单独的USB电源),不要和Arduino共用一路电源,否则水泵启动时的浪涌电流会把单片机拉复位。
控制逻辑也是简单的阈值加迟滞。这个“迟滞”非常关键,举个例子:如果只设置“低于25%启动水泵,高于25%停止水泵”,当湿度在25%附近时,水泵会在10秒内反复启停,很快就烧了。正确做法是设置两个阈值:低于20%启动水泵,一直浇到湿度达到45%才停,中间这段空档就是迟滞区间:
#define PUMP_PIN 7 int lowerThreshold = 20; int upperThreshold = 45; bool pumpRunning = false; void loop() { int percent = getSoilPercent(); if (!pumpRunning && percent < lowerThreshold) { digitalWrite(PUMP_PIN, HIGH); pumpRunning = true; } else if (pumpRunning && percent >= upperThreshold) { digitalWrite(PUMP_PIN, LOW); pumpRunning = false; } delay(1000); }这个简单的状态机保证了水泵不会频繁切换。根据我的测试,一个20cm花盆从“干透”浇到“湿度45%”大概需要10到20秒,所以下一次loop里即使读到湿度略低于45%,也不会立刻再启动,稳压得很。
3.7 应用三:把数据搬到OLED屏幕上
报警和自动控制都搞定之后,我加了一块0.96寸OLED显示屏,把实时湿度百分比直观地显示出来。SSD1306驱动的OLED接法很统一:SCL接A5,SDA接A4,VCC接5V或3.3V,GND接GND(如果是I2C版本的话)。
需要安装两个库,在Arduino IDE的“库管理器”中搜索安装Adafruit SSD1306和Adafruit GFX。然后参考下面的代码:
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); } void loop() { int percent = getSoilPercent(); display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(20, 25); display.print("Soil:"); display.print(percent); display.print("%"); display.display(); delay(1000); }如果屏幕初始化失败,第一件事查I2C地址是不是0x3C。用I2C Scanner例程扫描一下,有些模块的地址是0x3D,把代码里的地址改掉就能点亮。OLED在这里起到“本地可视化”的作用,调试现场不用每次接USB线看串口了。
4. 常见问题与排查技巧实录
4.1 读数异常的排查思路
这章我把自己实际遇到过的故障和排查过程整理成一个速查表,遇到问题可以直接照方抓药。
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 读数一直稳定在1023 | AO接线没接对、探头悬空 | 检查AO是否插在A0,探头触碰到湿土 |
| 读数一直稳定在0 | 探头两根电极短接、VCC没供电 | 确认VCC/GND电压,检查探头是否泡水短路 |
| 读数忽高忽低 | 探头接触不良、供电不稳、土壤颗粒缝隙大 | 重新插拔探头,改用滤波算法,检查USB供电质量 |
| DO输出始终不变 | 阈值电位器没调好、DO引脚接触不良 | 旋转电位器,确认DO接的是数字引脚并定义好pinMode |
| 浇水后读数反而升高 | 探头附近积水形成短路、或读数映射方向反了 | 把探头换到另一处,检查校准表方向 |
| 继电器吸合瞬间单片机重启 | 水泵/继电器反电动势干扰、供电不足 | 继电器线圈并联续流二极管,水泵独立供电并共地 |
4.2 关于“Arduino上传项目出错”的高频问题
这个话题在社区里被问烂了,但确实是新手最常卡住的地方。我总结为“三个检查”:查驱动、查端口、查板卡。驱动和端口前面提过,这里补充一个细节:Arduino IDE 2.x版本如果你同时在界面上打开了串口监视器,上传的时候会提示“Serial port busy”,这是因为串口被监视器占用了。关掉串口监视器窗口再上传即可。另外有些克隆版需要先按住板上的复位键再点上传,等IDE开始烧写时再松开,这个技巧在部分“卡在上传时”的场景下非常管用。
4.3 传感器电极腐蚀与间歇供电方案
这是电阻式土壤湿度传感器最绕不开的宿命。探头铜箔在直流电作用下会发生电解反应,长时间通电会加速腐蚀,导致读数漂移甚至失效。我一开始做自动浇花时让传感器7x24小时通电,大概一个多月后,同一盆土的读数就比新传感器低了快100,就是电极被腐蚀了。
解决思路是不要把传感器一直挂在VCC上,而是通过一个数字引脚给传感器供电。Arduino的引脚可以输出5V,驱动传感器绰绰有余。代码里这样写:
#define SENSOR_POWER 12 void setup() { pinMode(SENSOR_POWER, OUTPUT); digitalWrite(SENSOR_POWER, LOW); } int readSoilOnce() { digitalWrite(SENSOR_POWER, HIGH); delay(300); // 等待电压稳定 int value = analogRead(A0); digitalWrite(SENSOR_POWER, LOW); return value; } void loop() { int value = readSoilOnce(); // 处理读数 delay(60000); // 每分钟采样一次 }每次采样前通电300毫秒,稳定后读数,读完立刻断电。这样传感器每天实际带电时间只有几十秒,电极寿命可以延长非常多。这个办法适合自动浇花这种低频采样场景,如果想做实时监控,可以把采样间隔缩短到10秒一次,也能明显减少腐蚀。
4.4 串口调试助手的正确打开方式
调试Arduino时,用官方的串口监视器就够了,但如果你需要更丰富的调试能力,比如保存数据到CSV文件、定时发送指令、显示波形曲线,那就可以用第三方串口调试助手。这类工具在调试阶段能帮你做两件事:一是把传感器数据流记录成文件,方便事后分析一天之内的湿度变化趋势;二是可以用脱机模拟的方式,把预先录好的数据文件当串口输入回放给上位机,用来测试后续的代码逻辑。
我自己的习惯是:日常看数据用IDE自带监视器,需要长时间记录或导出图表时,就用串口调试助手把数据导成CSV,再导入Excel或者在线表格中做可视化。这套流程不依赖任何复杂的软件,上手极快。
5. 再往前走一步:应用场景扩展
5.1 从Arduino到其他平台的移植思路
很多朋友在玩完Arduino UNO之后,会想把手上的传感器接到STM32或者ESP32上。MH-Sensor-Series的AO输出是电压信号,在STM32上用ADC采集本质和Arduino一样,只是库函数不同。比如在STM32的HAL库里,用HAL_ADC_Start()加HAL_ADC_GetValue()就能读到同样的0到4095(12位ADC)数值,然后按照同样的“先标定再映射”思路处理就行。
如果换到ESP32,需要注意它的ADC是非线性的,尤其是低压端的转换曲线没那么准。我建议在ESP32上做两件事:一是开启ADC衰减设置analogSetPinAttenuation(A0, ADC_11db),扩展可测量电压范围;二是不要直接使用ADC原始值做精细判断,尽量落在自己标定过的区间里。
5.2 给系统加上低功耗和远程监控
如果你想把这套土壤湿度监测装置做成真正的“无人值守小站”,有两个方向值得投入。第一个是低功耗方向,把主控换成ESP32或ATtiny系列,用睡眠模式把系统功耗压到微安级,搭配一块太阳能电池板和锂电,就能在没有USB供电的阳台上长期运行。第二个是联网方向,ESP32带WiFi,可以直接把湿度数据通过MQTT协议发到本地Home Assistant或云端平台,实现手机远程查看土壤状态。这块内容展开讲又是一篇长文,但基础就是本文这套调试和校准流程,数据采集端做扎实了,后面接什么平台都是水到渠成。
5.3 我踩过的坑与最终心得
最后再分享几个只有动手做才会体会到的经验。
第一,做任何土壤湿度项目,先把串口打印这关过了再接执行器。我看到太多人一上来就把传感器、水泵、继电器全部接好,然后一通电就烧了引脚或者把板子搞复位,最后排查一圈发现是模块某个脚接错了。一步一步来,每加一个硬件就验证一次,虽然慢了点,但排查成本最低。
第二,校准数据一定要记录,不要凭感觉记在脑子里。我后来翻看之前的调试记录,发现同一个传感器在不同季节、不同土质下的基线变化很大,如果没有纸上数据,根本没法判断当前读数是否正常。
第三,传感器是易耗品,备几块很有必要。我把一块新传感器和旧传感器同时插在同一盆土里对比过,新板的读数能差出好几十。所以如果你发现某个传感器的数据越来越离谱,别花太多时间怀疑代码,直接换一块新传感器试试,往往立刻恢复正常。
MH-Sensor-Series这块小小的板子,承载了从模拟电路、单片机ADC采样、数据滤波到执行器控制的一整套完整链路,麻雀虽小五脏俱全。把这套流程走通一遍,你对Arduino项目开发和传感器调试的理解绝对会上一个台阶。