土壤湿度传感器接Arduino:从读数校准到自动浇花提醒

2026-11-09 20:17:08 31阅读
插在花盆土壤里的土壤湿度传感器

家里养花最头疼的就是浇水这件事:浇多了烂根,浇少了叶子发黄,全凭手指头戳土那点感觉。这篇就带你用几块钱一个的土壤湿度传感器配上Arduino,把“该不该浇水”变成串口监视器里明明白白的提示。全程保姆级,只要会点亮LED就能跟上。

先认识这块传感器

常见的土壤湿度传感器有两部分:一块插进土里的叉形探头,和一小块带运算放大器的转接板。探头上是两根镀金属的叉齿,土壤里的水分含量不同,两齿之间的导电率就不同,读数也就跟着变。转接板上一般有四个引脚:VCC、GND、A0、D0。

土壤湿度传感器引脚图

A0输出的是随湿度连续变化的模拟电压,D0则是转接板上电位器比较出来的高低电平。想精细控制就用A0,想简单粗暴地“干了就响”可以直接用D0。转接板上还有一颗电源LED和一颗状态LED,调节板上的蓝色电位器可以改变D0的触发门槛,拧的时候LED会跟着亮灭变化,很好判断。

接线:只占三个脚

这次先玩模拟输出,一共三根线:VCC接Arduino的7号数字脚(后面解释为什么不用5V常供电),GND接地,A0接A0模拟输入。杜邦线直插直用,不存在接错方向的问题。

读取模拟输出的接线图

读出原始数值

有个小坑必须提醒:探头上只要通着电,就会一直发生电解腐蚀,用不了多久叉齿就烂了。所以官方做法是把VCC接到一个数字脚上,读数前才通电,读完立刻断电。下面的代码就是这个思路:

// Sensor pins
#define sensorPower 7
#define sensorPin A0

void setup() {
  pinMode(sensorPower, OUTPUT);

  // Initially keep the sensor OFF
  digitalWrite(sensorPower, LOW);

  Serial.begin(9600);
}

void loop() {
  //get the reading from the function below and print it
  Serial.print("Analog output: ");
  Serial.println(readSensor());

  delay(1000);
}

//  This function returns the analog soil moisture measurement
int readSensor() {
  digitalWrite(sensorPower, HIGH);  // Turn the sensor ON
  delay(300);                       // Allow power to settle
  int val = analogRead(sensorPin);  // Read the analog value form sensor
  digitalWrite(sensorPower, LOW);   // Turn the sensor OFF
  return val;                       // Return analog moisture value
}

烧录进去打开串口监视器(波特率9600),就能看到一秒一个的模拟读数。先把干燥的传感器插进土里记个数,再倒点水进去,观察读数往哪个方向跑。

串口监视器里的原始模拟读数

校准:定出干湿两个门槛

这模块读数是反直觉的:数值越小说明越湿,越大说明越干。空气里读数大概在550到650之间,泡进一杯水里会掉到250到300,插在干燥土里则能飙到800以上。所以校准很简单:把探头插进浇透水的土里记下“湿值”,再等土彻底干透记下“干值”,中间取两个门槛写进代码:

/* Change these values based on your calibration values */
#define soilWet 500  // Define max value we consider soil 'wet'
#define soilDry 750  // Define min value we consider soil 'dry'

// Sensor pins
#define sensorPower 7
#define sensorPin A0

void setup() {
  pinMode(sensorPower, OUTPUT);

  // Initially keep the sensor OFF
  digitalWrite(sensorPower, LOW);

  Serial.begin(9600);
}

void loop() {
  //get the reading from the function below and print it
  int moisture = readSensor();
  Serial.print("Analog Output: ");
  Serial.println(moisture);

  // Determine status of our soil
  if (moisture < soilWet) {
    Serial.println("Status: Soil is too wet");
  } else if (moisture >= soilWet && moisture < soilDry) {
    Serial.println("Status: Soil moisture is perfect");
  } else {
    Serial.println("Status: Soil is too dry - time to water!");
  }

  delay(1000);  // Take a reading every second for testing
                // Normally you should take reading perhaps once or twice a day
  Serial.println();
}

//  This function returns the analog soil moisture measurement
int readSensor() {
  digitalWrite(sensorPower, HIGH);  // Turn the sensor ON
  delay(300);                       // Allow power to settle
  int val = analogRead(sensorPin);  // Read the analog value form sensor
  digitalWrite(sensorPower, LOW);   // Turn the sensor OFF
  return val;                       // Return analog moisture value
}

拿我的实测举例:湿土约480,干土约760,所以soilWet填500、soilDry填750刚好。你的土、你的传感器都不一样,务必以自己量出来的为准。跑起来之后串口会直接告诉你土是太湿、正好还是太干:

干土和湿土两种状态下的读数对比
小提醒:校准的时候别用手捏着叉齿往土里怼,皮肤上的汗会影响读数,也容易把叉齿掰歪。要垂直插到盆栽一半深度左右才准。

校准这步别偷懒直接抄我的数值。同样一块传感器,插在黏土和插在椰糠里读数能差出一大截,浇透水的黏土可能才500出头,而椰糠能掉到300以下。正确的做法是:把探头插进盆里,浇一次透水,等底孔往外渗水了再记湿值;然后放着让它自然干到你平时觉得“该浇了”的干度,记干值。门槛取在这两个数之间稍微偏湿一点的位置,因为植物怕旱不怕短暂偏湿。要是你拿不准,让代码把每次读数都打出来,观察两三天再定门槛,比一次校准靠谱得多。

升级成自动浇花提醒

校准完,这个提醒系统其实已经成型了:把loop里的delay(1000)改成delay(21600000)(六小时测一次,实际项目里建议一天一到两次),把“too dry”那行换成蜂鸣器响一声或者点亮一颗红色LED,一个不用你操心的浇花提醒器就完成了。

提醒的方式看你想多吵。最简单的是一颗LED:土干了就亮,塞在花盆边上,路过瞄一眼就知道。想更醒目就上个无源蜂鸣器,串口提示too dry的同时响三短声。再讲究点,可以直接接一块ESP8266之类的WiFi板,干透了往手机推一条消息,人不在家也不怕。代码层面都只是在判断分支里加几行digitalWrite的事,先把基础版本跑稳再往上叠功能。

想更进一步,可以加个继电器直接带小水泵,土一干自动补水,连提醒都省了——不过继电器接水泵是另一个话题,改天单独写。

如果你嫌模拟输出麻烦,还有更偷懒的玩法:用D0数字输出,接线换成D0接8号脚,电位器拧到“湿土时板载状态LED刚好灭”这个临界点,然后digitalRead一下就能判断干湿。代码更短:

读取数字输出的接线图
// Sensor pins
#define sensorPower 7
#define sensorPin 8

void setup() {
  pinMode(sensorPower, OUTPUT);

  // Initially keep the sensor OFF
  digitalWrite(sensorPower, LOW);

  Serial.begin(9600);
}

void loop() {
  //get the reading from the function below and print it
  int val = readSensor();
  Serial.print("Digital Output: ");
  Serial.println(val);

  // Determine status of our soil moisture situation
  if (val) {
    Serial.println("Status: Soil is too dry - time to water!");
  } else {
    Serial.println("Status: Soil moisture is perfect");
  }

  delay(1000);  // Take a reading every second for testing
                // Normally you shoul take reading perhaps every 12 hours
  Serial.println();
}

//  This function returns the analog soil moisture measurement
int readSensor() {
  digitalWrite(sensorPower, HIGH);   // Turn the sensor ON
  delay(300);                        // Allow power to settle
  int val = digitalRead(sensorPin);  // Read the analog value form sensor
  digitalWrite(sensorPower, LOW);    // Turn the sensor OFF
  return val;                        // Return analog moisture value
}

代价是门槛只能靠拧电位器来定,没有模拟读数直观,适合做“低于某个湿度就报警”这种单一场景。两条路线按需选,模拟版信息量大,数字版接线简单。

顺带答几个新手常问的问题。读数一直不动或者一直是满值,八成是VCC没接对,或者探头没插到位,叉齿有一半露在空气里。读数飘忽不定,可能是刚浇完水土还没渗匀,等几分钟再看;也可能是杜邦线接触不良,换根线试试。叉齿发黑是电镀层被腐蚀的正常现象,只要叉齿还没断就不影响读数,黑得厉害了记得换个新的。还有人说插进土里读数和空气里一样,检查一下探头上那两个圆孔是不是被塑料袋之类的隔住了,探头必须和土壤紧密贴合才有读数。

最后说下摆放位置。别把探头怼在盆正中间贴着根须最密的地方,那里浇水后永远湿着,测出来的数偏乐观;也别贴盆边,土干得快,读数偏悲观。插在盆沿往里三分之一、深度到叉齿一半最合适。多肉这类耐旱植物可以适当把门槛调高,绿萝蕨类这类爱水的就调低,同一套代码换个门槛就能伺候不同脾气。

总结一下三步走:接线时VCC走数字脚做软开关,先烧原始读数代码记下自家湿土干土两个数,再把门槛填进判断代码。剩下的就是把它塞进花盆,接个小蜂鸣器,从此告别“想起来才浇水”的日子。装好之后欢迎在评论区汇报你家的读数区间,看看各家的土壤差别有多大。


作者:隔壁老王的教程
链接:https://www.aiddithome.com/p/591346385c85f.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
6条评论
阿强焊点总飞
1楼 · 3小时前

教程写得挺细,那个delay(21600000)我一开始没反应过来是六小时,数了数零才明白哈哈。不过一天测两次会不会太频繁,电池供电的话是不是改成一天一次更好

触底反弹的Tony
2楼 · 3小时前

已照做,我的问题是插进盆中间读数一直偏高,看到文末才知道不能怼在根须最密的地方,明天挪个位置重新校准

只看不说话
3楼 · 3小时前

正好想给我家阳台上那盆绿萝搞个自动提醒,先收藏了。问下校准的时候湿值和干值差太少怎么办?我上次测一个才差50多

线比代码多
4楼 · 3小时前

分享个翻车经历:我把探头一直接着5V挂在花盆里两个月,拔出来一看叉齿锈得不成样子,读数也没法用了。博主说的通电才读数这条真的是血的教训,大家千万别省这个步骤

拆机党
5楼 · 3小时前

请教一下,多肉用这个方案的话门槛一般设多少合适?我上次调完总觉得它明明干了还在喊perfect

1 2