Arduino-ESP32 智能灌溉系统:土壤湿度到云端上报的实战
【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
周五傍晚 17:05,手机弹了一条推送:"第三垄灌溉完成,32 秒。"没下楼,没碰大棚,Arduino-ESP32 核心跑的这套智能灌溉固件自己干完了一整轮:读湿度、判该不该浇、开水泵、把数据送上云。整季太阳能供电,靠的是深度睡眠把待机电流压到微安级。
设计逻辑:三个职责边界,数据往两个方向流
这套系统刻意切成三块,边界清晰才好独立调试:感知层负责把物理量变成可信数字——土壤湿度走 ADC、温湿度走单总线、光照走 I2C;决策层只做一件事,把三路数字折合成"浇不浇、浇多久",规则全部收敛在一个函数里;执行与上报层驱动继电器,同时把采样结果沿两条路送出去——Wi-Fi 上的 JSON 报文流向云端,CSV 日志落进 SD 卡。数据流向就一张图的事:
ESP32 开发板管理器怎么装、传感器引脚怎么接
⚠️ 继电器模块一定从外部电源独立取电,别指望 ESP32 的 5V 脚——吸合瞬间的冲击电流足以烧穿主板供电线。
| 器件 | 作用 | 接线 |
|---|---|---|
| ESP32-WROOM-32D | 主控 | — |
| 电容式土壤湿度传感器 | 水分感知,抗电解 | VCC/GND/OUT → 3.3V / GND / GPIO34 |
| DHT11 | 环境温度湿度 | VCC/OUT → 3.3V / GPIO4 |
| BH1750 | 光照强度 | SCL/SDA → I2C(默认 22/21) |
| 继电器模块 | 隔离控制水泵 | IN → GPIO13,外部 5V 供电 |
| SD 卡模块 | 本地 CSV 存档 | CS → GPIO5 |
| 12V 电磁阀 | 执行灌溉 | 串在继电器 COM/NO 回路里 |
引脚定义可对照 esp32-hal-gpio.h。GPIO34/35/36 是纯输入口,放传感器正合适;GPIO13 能驱动继电器,但要留意它兼 BOOT 功能。IDE 侧装包四步走(细节见 installing.rst):
- 文件 → 首选项
- 在「附加开发板管理器网址」填入
https://espressif.github.io/arduino-esp32/package_esp32_index.json - 打开 工具 → 开发板 → 开发板管理器
- 搜esp32,装最新版
土壤湿度 ADC 怎么校准:GPIO34 读数映射成百分比
const int SOIL_PIN = 34; const int DRY_ADC = 4095; // 探头悬空/干土时的读数 const int WET_ADC = 1500; // 探头浸水时的读数 float k = 0.0f; float readSoil() { int raw = analogRead(SOIL_PIN); // ADC1_CH6,12bit,0~4095 float pct = 100.0 * (DRY_ADC - raw) / (float)(DRY_ADC - WET_ADC); k = 0.9f * k + 0.1f * pct; // 一阶低通滤波 return constrain(k, 0.0f, 100.0f); }校准走两点映射:干土记 4095、浸水记 1500,线性折算成百分比——因为电容式探头的原始值随批次和土质漂移,直接拿读数当湿度用等于蒙眼读数。滤波系数 0.1 压掉单次采样抖动,constrain兜住越界值。ADC 默认 11dB 衰减、12 位,底层细节见 esp32-hal-adc.h。
💡 探头要逐个校准,同一探头换一片田,基准都可能挪几十个点。
灌溉阈值怎么定:三参数折中浇水量
struct Plan { bool go; int secs; }; Plan decide(float soil, float temp, float hum, float lux) { Plan p{false, 0}; if (soil < 30.0f) { // 低于干旱线才动作 p.go = true; p.secs = 30; // 基础 30 秒 if (temp > 30.0f && hum < 50.0f) p.secs += 15; // 高温低湿 if (lux > 50000) p.secs += 10; // 强光照 } return p; }规则全部收敛在decide里:湿度定"要不要",温度和光照只修"多久"——蒸发越猛补得越多。30% 这条干旱线不是物理常数,是按作物耐旱度调出来的。想加"雨天禁灌"这类规则,也只改这一个函数。
Wi-Fi JSON 上报怎么发:一次 POST 到位
#include <WiFi.h> #include <HTTPClient.h> void report(float soil, float t, float h, float lux) { if (WiFi.status() != WL_CONNECTED) return; // 没网直接跳过 HTTPClient http; http.begin("http://你的服务器/api/irrigation"); http.addHeader("Content-Type", "application/json"); String body = "{\"soil\":" + String(soil,1) + ",\"t\":" + String(t,1) + ",\"h\":" + String(h,1) + ",\"lux\":" + (int)lux + "}"; int code = http.POST(body); Serial.printf("-> %d\n", code); http.end(); }先用WiFi.status()挡一道,断网时不发请求,省掉无谓的超时等待;String(x,1)把浮点数压成一位小数,报文短、传输快、云端解析也稳。上报用的 WiFi 库 负责联网,HTTPClient发 POST,返回码 200 才算落库成功。
ESP32 深度睡眠怎么压待机功耗
#include "esp_sleep.h" void powerGate(bool on) { digitalWrite(14, on ? HIGH : LOW); } void runCycle() { powerGate(true); delay(100); // 传感器上电,等 100ms 稳定 float soil = readSoil(); // ... 读 DHT11、BH1750,决策,开继电器 ... powerGate(false); // 读完立即断电 delay(100); // 日志发完 esp_sleep_enable_timer_wakeup(300 * 1000000); // 5 分钟后唤醒 esp_deep_sleep_start(); }深度睡眠期间 SoC 时钟停摆,电流掉到微安级,睡 300 秒远比"低功耗模式空转"省。传感器用 GPIO14 驱动 MOSFET 门控供电:采样前拉高、等 100ms 稳定、读完就放掉——土壤湿度和 DHT11 的待机功耗并不小。
⚠️ 采样、上报、进睡的时间窗口要卡在 300 秒内,算一笔:3 秒采样 + 30 秒水泵 + 1 秒上报,余量够宽裕;如果一次灌溉超过 5 分钟,先把定时器拉长再说。
现象→原因→处理:五个高频问题
土壤湿度读数一天内漂移原因:探头批次差异、土质不同、探头发热。 处理:每换一个探头就重新采干土/浸水两个基准;长期漂移大就在探头和土壤之间加隔热片。
水泵随机误触发原因:阈值贴得太紧,湿度在 30% 附近反复穿越。 处理:加迟滞——低于 30% 开、回升到 38% 才关;继电器回路串机械联锁,防触点粘连。
Wi-Fi 重连吃掉整晚电原因:路由器夜里重启,固件死循环重连。 处理:指数退避重连,连续失败 5 次本轮放弃上报直接进睡,SD 卡把数据补上。
SD 卡写不进 CSV原因:卡没识别或 FAT 坏块。 处理:SD.begin(5)返回失败就降级为纯云端模式,重启重试,别卡死在格式化上。
深睡后第一笔读数乱原因:传感器刚上电,100ms 没吃透。 处理:上电延时从 100ms 提到 200ms,或者读两次取第二次。
延伸:跑稳之后的几条路
- Wi-Fi 够不到的地块换 LoRa,数据回传距离翻十倍
- 多节点 Mesh 组网,一套系统铺满整片田
- 板上跑轻量模型做叶片病害初筛
- 历史 CSV 接 Grafana,曲线替代数字
- 用积累的 CSV 训练灌溉量预测,从"阈值反应"走到"按需预灌"
还是傍晚 17:05 那条推送:第三垄 32 秒浇完,人没下楼。代码仓库在这里,clone 下来把阈值和 Wi-Fi 账号换成自己的,烧进去就能跑:
git clone https://gitcode.com/GitHub_Trending/ar/arduino-esp32【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考