一套跑通的 ESP32 智能灌溉系统:自动浇水、远程查看到深度睡眠省电的实操笔记
2026/9/10 9:35:39 网站建设 项目流程

一套跑通的 ESP32 智能灌溉系统:自动浇水、远程查看到深度睡眠省电的实操笔记

【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32

正午的太阳下,番茄叶子耷拉着,浇多了又怕烂根——这套土壤湿度自动灌溉装置就是为解决这件事做的。整个方案基于 arduino-esp32 官方核心包搭建,属于典型的 ESP32 物联网农业项目:电容式土壤湿度传感器负责感知,继电器带水泵自动浇水,Wi-Fi 把数据报回手机,深度睡眠把续航拉到月级。下面是我把它从零装到稳定跑了两周后的完整复盘。

硬件清单:ESP32 物联网农业项目的选型表

🔧 先把 BOM 列清楚,括号里是踩坑后的经验值:

部件型号 / 规格作用选型理由
主控ESP32-WROOM-32D 开发板采集、判断、联网双核 + Wi-Fi,20 元左右,性价比最高
土壤湿度电容式(非电阻式)模块感知土壤干湿探头泡土里不会电解腐蚀,读数稳定
温湿度DHT11修正灌溉时长单总线接线最简单,精度够灌溉用
光照BH1750强光时补水量I2C 两线,省引脚
执行器5V 单路继电器 + 12V 小潜水泵(或电磁阀)自动浇水继电器隔离 12V 负载,ESP32 只出 3.3V 控制信号
电源5W 太阳能板 + 5000mAh 锂电 + TP4056 充电板户外供电白天充电夜里用,配合深睡可跑月级
可选SPI SD 卡模块本地 CSV 备份Wi-Fi 断线时数据不丢

开发环境配置与传感器接线对照表

IDE 四步装好 ESP32 支持包

  1. Arduino IDE「文件 → 首选项」,附加开发板管理器网址填入https://espressif.github.io/arduino-esp32/package_esp32_index.json
  2. 「工具 → 开发板 → 开发板管理器」搜索 "esp32"
  3. 安装 Espressif Systems 的版本(当前 3.x,对应本仓库 3.x 分支代码)
  4. 开发板选 "ESP32 Dev Module",上传速度拉满 921600,少等几十秒

引脚对照表(土壤湿度 / 温湿度 / 光照 / 继电器)

信号ESP32 引脚备注
土壤湿度 AOUTGPIO34ADC1_CH6,只读口,别用 35~39(ADC2 与 Wi-Fi 抢通道,连网时读数为 0)
DHT11 DATAGPIO4单总线,模块自带上拉
BH1750 SDA / SCLGPIO21 / GPIO22I2C 默认引脚
继电器 INGPIO13输出 3.3V 即可驱动
传感器供电开关GPIO14接 P-MOS 栅极,做分时段断电
SD 卡 CSGPIO5SPI 模式

坑位提醒:三个我实际踩过的

  • 继电器必须独立供电:我用 5V 模块单独上电、与 ESP32 共地。从板子 5V 脚直取电的那一版,继电器一吸合整个开发板重启,翻了三次车才定位。
  • 别买电阻式土壤湿度传感器:探头通电泡在湿土里几周就腐蚀发黑,读数漂移没法校准;电容式靠板载小振荡电路出模拟量,长期稳定。
  • GPIO 选择避坑:模拟量只放 ADC1(32/33/34);6、7、8、9、10、11、12、15 是 strapping 或 SPI 内部口,上电瞬间电平会影响启动,留作数字输出都行,别接模拟传感器。

固件思路:采集→判断→执行的三步逻辑

不贴整份工程,只讲骨架,参考 libraries/ESP32/examples/ 里 AnalogRead、DeepSleep 的官方示例改就行。

第一步 采集:土壤湿度读 5 次取平均滤掉抖动,再套校准公式换算成百分比。DRY 和 WET 两个常数不是查表得来的,是我把探头分别悬空、泡进清水实测记下来的(本机 4095 和 1500):

float readSoilMoisture() { // 5 次平均 + 换算百分比 int sum = 0; for (int i = 0; i < 5; i++) { sum += analogRead(34); delay(10); } int raw = sum / 5; float pct = 100.0 * (DRY - raw) / (DRY - WET); // DRY=4095, WET=1500 return constrain(pct, 0.0, 100.0); }

第二步 判断:主干只有一条——湿度低于 30% 才浇水。温度和光照只做时长修正:基础 30 秒,气温 >30℃ 且空气湿度 <50% 加 15 秒(蒸腾快),光照 >50000 lux 再加 10 秒;单次要封顶 300 秒,两次之间至少隔 3600 秒。判断逻辑和执行写在一个函数里,顺手把保护都塞进去:

void checkAndWater(float m, float t, float h, float lux) { if (m >= 30.0) return; // 不到干旱阈值不动 if (millis() - lastWater < 3600000UL) return;// 最小 1 小时间隔 int dur = 30; // 基础 30 秒 if (t > 30.0 && h < 50.0) dur += 15; // 高温低湿 +15s if (lux > 50000) dur += 10; // 强光 +10s digitalWrite(13, HIGH); delay(min(dur, 300) * 1000UL); // 封顶 300 秒 digitalWrite(13, LOW); lastWater = millis(); }

第三步 执行与记录:继电器动作结束后,把本轮数据追加写一行 CSV(时间戳、湿度、气温、空气湿度、光照、是否浇水、时长)到 SD 卡,再走联网上报。CSV 用逗号分隔、带表头,直接丢进 Excel 就能看趋势。

上云:Wi-Fi 数据上报与手机端查看

🌱 联网部分没有花活:WiFi.begin()后循环等连接、最多重试 20 次(约 10 秒),连上就用 HTTPClient 向自建的一个小服务 POST 一段 JSON,四个字段 soil_moisture / temperature / humidity / light,Content-Type 写成 application/json 即可。服务端我用的是家里 NAS 上跑的一个 50 行小服务,只存最近 7 天的记录。

落点在手机上能干什么,我最终做的是三件事:

  • :最新一组读数 + 24 小时湿度曲线 + 浇水事件时间线(每次继电器动作记一条)
  • :干旱阈值(25%~45% 滑条)、采样间隔(60s~900s)、单次时长上限
  • :一个手动浇水按钮,走同一条 POST 接口反向下发指令,设备下次醒来时执行

阈值和间隔做成可下发而不是写死,是两周联调后最大的心得——不同地块、不同作物,30% 这个数根本不该是常量。

深度睡眠省电配置:常开与睡眠的功耗对比

⚡️ 户外没插座,省电是硬指标。对比很直观(5000mAh 锂电,数字为估算):

模式平均电流(估算)续航(估算)
常开:Wi-Fi 保持连接 + 每秒轮询70~90 mA约 2~3 天
深睡:每 300 秒醒来采样 1 次,上报后入睡平均约 2~3 mA约 60 天以上

做法就是"醒一会儿、睡大觉":醒来后先拉高 GPIO14 给传感器供电(等 120ms 稳定),采样、判断、上报,然后断电传感器、睡 300 秒。定时器唤醒直接用 IDF 接口,官方示例在 libraries/ESP32/examples/DeepSleep/TimerWakeUp/,改个时间参数就能用:

void sleepCycle() { // 一轮:供电→采样→判断→上报→断电→睡 digitalWrite(14, HIGH); delay(120); // 传感器上电稳定 float m = readSoilMoisture(); checkAndWater(m, readTemp(), readHum(), readLux()); reportToCloud(m); // Wi-Fi 上报 JSON digitalWrite(14, LOW); delay(100); // 等串口把日志发完 esp_sleep_enable_timer_wakeup(300ULL * 1000000); // 300 秒 esp_deep_sleep_start(); }

两个细节顺手记一下:睡眠前delay(100)是为了让串口日志发完,否则醒来看到半行字;唤醒后第一次读传感器会偏高,所以我把首次读数丢弃只用第二次,读数立刻老实了。

装上之后:响应速度、节水量与续航实测

装置在阳台两个 20cm 花盆上跑了两周,数据如下(均为估算,因环境而异):

  • 响应:从湿度跌破 30% 到继电器吸合,延迟取决于采样间隔,300 秒周期下约 1~6 分钟;对花盆场景完全够用,种大田要缩短间隔
  • 节水量:对比之前"每天早晚各浇 3 分钟"的定时模式,估算节水 30%~40%,且再没出现过一次烂根
  • 续航:5000mAh + 5W 太阳能,深睡模式下实测阴雨天连续跑约 3 周不掉电,晴天白天充电基本无限续航
  • 翻车记录:前 48 小时出过两次误触发,都是探头表面凝水被当成"很湿",后来加了"连续 2 个周期才改变状态"的确认逻辑就稳定了

FAQ:连不上网、读数漂移与误触发

问:Wi-Fi 总是连不上?先确认是 2.4GHz 频段(ESP32 不支持 5GHz);再查 SSID 里有没有特殊字符、密码有没有引号问题;信号弱的户外加一句"连接失败则睡 60 秒再试"的兜底,别死等。

问:湿度读数漂移或者跳变?90% 是探头问题:探头表面有水膜或冷凝会虚高,擦干后 10 分钟回稳;线缆太长引入干扰就跳变,把信号线拧成对、缩短到 10cm 内。剩下的用 5 次平均 + 连续 2 周期确认两个滤波器解决,别急着换硬件。

问:水泵被误触发一直转?三层保险按顺序检查:时长封顶(我设 300 秒)有没有生效、最小间隔(3600 秒)有没有生效、继电器电源是不是独立供电。三样齐了基本不可能烧泵,我这套跑两周没有再出现过。

问:冬天还能用吗?我在判断逻辑里加了一条低温熔断:气温 <5℃ 直接跳过浇水,防冻伤也防探头结冰。北方露天的建议入冬前整体断电,太阳能板收进屋。

问:两个花盆不够,想扩到一片地?见文末的扩展方向,先说结论:一拖多靠继电器模块加路数,跨区组网再上 LoRa 或 Mesh,固件结构不用推翻。

想再往前一步

方向其实就四条:多区域控制(换 4 路继电器板,每区独立阈值)、拉一个免费天气 API 做降雨预测、Wi-Fi 覆盖不到的棚用 LoRa 远传、多节点 Mesh 组网。代码结构不用大改,判断和执行那两层原样保留。

想继续翻的仓库内资源:libraries/WiFi/ 的 Wi-Fi 接口与示例、libraries/ESP32/examples/DeepSleep/ 的深睡唤醒全家桶、cores/esp32/esp32-hal-adc.h 里 ADC 衰减档位(探头分压偏低时把 11db 换成更高衰减能读得更准)。跑通之后你会发现,这套东西最难的不是代码,是把探头从土里拔出来校准的那一下。

【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询