可以——用一块 Arduino Uno,大约一小时就能搭好一套自动浇花系统,全程免焊接。Uno 通过 A0 读取电容式土壤湿度传感器(capacitive soil moisture sensor)的数值,当土壤湿度低于你校准好的阈值时,就驱动继电器(relay)启动一个 5V 小型潜水泵。程序里还有安全超时,不会把花盆浇到淹水。
自动浇花系统是怎么工作的?
Arduino Uno 跑的是一个简单的“感知—判断—执行”循环:电容式土壤湿度传感器输出一个随含水量变化的电压,Uno 拿它和两个校准好的阈值比较,再由继电器模块开关水泵。这跟我们的自动晾衣架雨滴传感器教程是同一个套路——换掉传感器和执行器,逻辑照搬就行。
水装在什么容器里都行——旧冰淇淋桶就够用——水泵放进去,再接一条硅胶管通到花盆。土壤读数偏干时,水泵就抽水,直到传感器重新读到湿润为止。
需要哪些零件?
Arduino Uno、电容式土壤湿度传感器、继电器模块和 5V 水泵——整套系统就这四个模块,用杜邦线加上水泵自带的短水管连起来。Arduino Uno 兼容板(CH340G)是大脑;传感器、继电器和水泵分别负责输入和输出这两头。
零件清单
你还需要一个 USB 移动电源(power bank)或闲置的 5V 手机充电器——水泵要用独立供电,接线章节会解释原因。
为什么选电容式土壤湿度传感器,而不是两叉式探针?
电容式土壤湿度传感器 v1.2(CAPSOIL)隔着阻焊层感应湿度,没有任何裸露金属接触土壤。便宜的电阻式两叉探针让电流直接流过湿土,电解会一点点吃掉表面镀层;对一套要长期无人值守运行的系统来说,电容式探头就是比它们耐用。
它的供电范围是 3.3–5.5V,但输出电压永远摆不满量程:5V 供电时,大致是在干燥空气中约 3V,泡进水里降到约 1.5V。电压越低表示土壤越湿,而且每一块的实际范围都不一样——所以校准是必做步骤,不是可选项。
提醒一句山寨批次的坑:有些批次用的是 555 定时器变体,或者稳压电路的接法只在 5V 下才正常,或者输出接近供电电压。在 5V 的 Uno 上这无伤大雅;但接 3.3V 板子之前,务必先量一下输出再决定信不信它。
传感器、继电器和水泵怎么接线?
5V 继电器模块(1WRELAY)是 Uno 的“大脑”和水泵的“肌肉”之间的桥梁——千万不要用 Arduino 引脚直接驱动水泵。Uno 单个引脚的额定电流大约是持续 20mA(绝对上限 40mA),而光是继电器线圈就要吃掉约 70mA,小水泵的工作电流在 100–220mA 左右,启动瞬间还有更大的冲击电流。引脚只负责给继电器模块发信号,大电流走的是另一条路。
| 模块引脚 | Arduino Uno 引脚 | 用途 |
|---|---|---|
| CAPSOIL VCC(红线) | 5V | 传感器供电 |
| CAPSOIL GND(黑线) | GND | 接地 |
| CAPSOIL AOUT(黄线) | A0 | 模拟湿度信号 |
| 1WRELAY VCC | 5V | 继电器线圈与光耦供电 |
| 1WRELAY GND | GND | 接地 |
| 1WRELAY IN | D7 | 触发信号(低电平有效) |
大多数光耦隔离的继电器板,IN 引脚都是低电平触发(active LOW)——把 IN 拉到 GND 继电器才吸合——而且板上已经带了驱动三极管和续流二极管,线圈这一侧不需要任何额外元件。程序默认低电平触发;如果你的板子行为相反,把代码顶部那两个常量对调即可。

| 从 | 到 | 说明 |
|---|---|---|
| 移动电源 5V(+) | 继电器 COM 端子 | 水泵供电从开关这一侧进入 |
| 继电器 NO 端子 | 水泵红线 | NO = 常开(normally open),水泵默认断电 |
| 水泵黑线 | 移动电源 GND(−) | 完成水泵回路 |
小型潜水泵要用那个独立的 5V 电源供电,不要接 Uno 的 5V 引脚。电机的电流冲击一旦经过 Uno 的稳压器,就会出现经典的“水泵一转 Arduino 就重启”问题。由于继电器触点是电气隔离的,水泵回路甚至不需要和 Uno 共地。
两条摆放原则:传感器的线要避开水泵的电线,因为电机噪声会让模拟读数抖动;水泵必须完全泡在水里——它靠水散热,绝对不能干转。

土壤湿度传感器怎么校准?
电容式土壤湿度传感器永远读不满 0–1023 的 ADC 量程,而且没有两块读数完全一样,所以校准就是做两次快速测量。打开串口监视器,先记下探头在空气中干燥时的原始读数(5V Uno 上通常接近 590),再记下泡进一杯水里的读数(通常在 270 左右)。这两个数字就是程序里的 RAW_AIR 和 RAW_WATER。
探头只插到 PCB 上印的那条限位线为止,SMD 元件要留在土面以上,也不要被水溅到。把电子元件埋进土里,等于放弃了你选这款传感器换来的防腐蚀优势。

安全的浇水代码长什么样?
下面这份 Arduino 程序用的是一个湿度区间,而不是单一阈值:湿度跌破 35% 才开泵,回升超过 55% 才停。单一阈值会让继电器在临界点上反复跳动;一个区间能让每次浇水都干脆地开始、干脆地结束。
程序内置了三道安全网。水泵每个周期最多运转约八秒;两次浇水至少间隔 30 分钟;任何超出校准范围的读数都会把水泵锁定关闭——传感器一旦脱落,A0 悬空后的读数通常会飘出这个区间。水在土壤里渗透得很慢,所以“短脉冲加休息”比一次浇个透更有效。
// 自动浇花系统 — Arduino Uno + 电容式土壤传感器 v1.2 + 继电器 + 5V 水泵
// 传感器 AOUT 接 A0,继电器 IN 接 D7。大多数光耦继电器板为低电平触发(ACTIVE LOW)。
const int SENSOR_PIN = A0;
const int RELAY_PIN = 7;
const int RELAY_ON = LOW; // 如果你的继电器板是高电平触发,把这两个值对调
const int RELAY_OFF = HIGH;
// ---- 校准:换成你自己的读数(见校准章节) ----
const int RAW_AIR = 590; // 原始读数:探头在空气中干燥状态
const int RAW_WATER = 270; // 原始读数:探头泡在一杯水里
// ---- 浇水区间(滞回) ----
const int START_PUMP_BELOW_PCT = 35; // 比这个更干 -> 开始浇水
const int STOP_PUMP_ABOVE_PCT = 55; // 比这个更湿 -> 停止浇水
// ---- 安全限制 ----
const unsigned long MAX_PUMP_MS = 8000UL; // 每个周期最多抽水 8 秒
const unsigned long MIN_GAP_MS = 30UL * 60UL * 1000UL; // 两次浇水至少间隔 30 分钟
const int FAULT_MARGIN = 60; // 读数超出校准范围 +/- 余量 = 传感器故障
bool pumping = false;
unsigned long pumpStartedAt = 0;
unsigned long lastWateringAt = 0;
void setup() {
digitalWrite(RELAY_PIN, RELAY_OFF); // 先写入 OFF 状态,再启用引脚
pinMode(RELAY_PIN, OUTPUT);
Serial.begin(9600);
}
int readMoisturePct() {
long sum = 0;
for (int i = 0; i < 10; i++) { // 取 10 次读数平均,抹平电机噪声
sum += analogRead(SENSOR_PIN);
delay(20);
}
int raw = sum / 10;
// 引脚悬空时读数不定 -> 当作故障处理。
if (raw > RAW_AIR + FAULT_MARGIN || raw < RAW_WATER - FAULT_MARGIN) {
return -1;
}
// 原始值越低越湿。映射到 0%(空气干燥).. 100%(水中)。
int pct = map(raw, RAW_AIR, RAW_WATER, 0, 100);
return constrain(pct, 0, 100);
}
void loop() {
int moisture = readMoisturePct();
unsigned long now = millis();
if (moisture < 0) { // 传感器故障 -> 故障安全:水泵锁定关闭
digitalWrite(RELAY_PIN, RELAY_OFF);
pumping = false;
Serial.println("Sensor fault - pump locked off");
delay(5000);
return;
}
if (!pumping) {
bool dryEnough = (moisture <= START_PUMP_BELOW_PCT);
bool rested = (lastWateringAt == 0) || (now - lastWateringAt >= MIN_GAP_MS);
if (dryEnough && rested) {
pumping = true;
pumpStartedAt = now;
digitalWrite(RELAY_PIN, RELAY_ON);
}
} else {
bool wetEnough = (moisture >= STOP_PUMP_ABOVE_PCT);
bool timedOut = (now - pumpStartedAt >= MAX_PUMP_MS);
if (wetEnough || timedOut) {
pumping = false;
lastWateringAt = now;
digitalWrite(RELAY_PIN, RELAY_OFF);
}
}
Serial.print("Moisture: ");
Serial.print(moisture);
Serial.println(" %");
delay(1000);
}
想在动手之前先看一个类似的“传感器—继电器—水泵”组合是怎么搭起来的?这条视频讲的正是同一条链路:
真实客户最常踩的坑
传感器引脚没有标注。“air sensor takde label VCC/GND/SIG”——有些批次的传感器丝印很淡,甚至完全没印。CAPSOIL 传感器附带的线材通常约定红 = VCC、黑 = GND、黄 = 模拟输出;如果你的线色不一样,先用万用表确认哪个焊盘是供电,再通电。
用 Uno 的 5V 引脚给水泵供电。在桌面上测试看着一切正常,浇到一半 Uno 就重启。给水泵配一个独立的移动电源或充电器,这种“灵异重启”就会消失。
只用一个阈值,而不是一个区间。在阈值附近读数会抖动几个格,继电器就跟着快速开开关关。程序里的滞回区间就是专门用来防这个的。
把传感器一路插到接口。探头部分防腐蚀,顶部的元件可不防。只插到限位线,浇水时也别让水花溅到电子元件上。
常见问题
电容式传感器可以配 ESP32 或其他 3.3V 板子用吗?
可以——供电范围是 3.3–5.5V。但因为部分山寨批次在 5V 以下工作不正常,或输出接近供电电压,所以先单独给传感器上电、量一下输出,确认它不超过 3.3V,再接到 3.3V 的模拟输入。
为什么我的水泵一直抽到花盆溢水?
多半是传感器没插在水实际流到的区域,所以它永远读不到“湿”。把探头挪到出水管滴水处附近的根部区域,并保留程序里的 MAX_PUMP_MS 超时——它是限制单次浇水量的最后一道保险。
整套系统可以用电池跑吗?
一个 USB 移动电源可以同时带动 Uno 和水泵,不过很多移动电源在负载太小时会自动休眠——先整夜测试一下你手上那个。想要更精简的 18650 供电方案,参考我们的 TP4056 18650 充电教程。
为什么 Arduino 开机时继电器会咔哒响一声?
常见原因是初始化顺序:pinMode(pin, OUTPUT) 默认把引脚拉低,在低电平触发的板子上,继电器会先吸合,直到 OFF 写入才松开。这份程序先写入 OFF 状态再启用引脚,所以整个启动过程继电器保持释放;至于上电瞬间模块自身发出的一声轻响,对水泵来说无伤大雅。
水泵可以干转吗?
不行——小型潜水泵靠水来散热和润滑。让进水口一直位于水面以下,水桶见底前记得加水,万一水真的抽完了,就靠代码里的水泵超时来限制损伤。
最后更新:2026年8月。有问题?WhatsApp 联系我们。



Arduino Uno Compatible SMD UNO R3 with Type B Cable - ATMEGA328P with CH340G-Microcontroller Project
Capacitive Soil Moisture Sensor V1.2 Corrosion Resistant with Cable For Arduino IOT Application
Relay Module 3.3V 5V 12V 1/2/4/8 Ways Optocoupler Trigger Relay Module 1 2 4 8 Channel Relay Module - 5V RELAY MODULE(1WAY)
Mini Water Pump Submersible DC 3V-5V - 5V WATER PUMP