💡 划重点
- 主控芯片:ESP32-S3,支持 Wi-Fi 与 BLE,适合 MQTT 数据上报与本地控制。
- 传感器:电容式土壤湿度传感器(模拟输出)+ DHT22 空气温湿度。
- 人机交互:0.96 寸 OLED,实时显示土壤湿度、环境温湿度和 Wi-Fi 状态。
- 联网方案:MQTT 协议上报数据到本地或云端 Broker,支持手机 App 查看。
- 供电与功耗:采用 5V USB 供电,代码中启用 modem_sleep 与 light_sleep 机制,实现低功耗待机。
- 总物料成本控制在 60 元以内,适合阳台园艺爱好者 DIY。
需求洞察
目标用户:城市阳台园艺爱好者,尤其是朝九晚五的上班族和刚刚开始养绿植的新手。
真实痛点:浇水完全靠经验或固定日历,夏天容易蒸发过快导致缺水,冬天又容易盆内涝根;出差或加班时无法得知盆栽的真实状态,往往等叶子发黄才发现问题。
为什么值得做:土壤湿度是一个典型的“看不见却致命”的变量。市售智能花盆价格动辄 200-400 元,且传感器集成度低,不能自行扩展。本项目基于 ESP32-S3,用 60 元以内成本搭建一套具备“实时感知—阈值提醒—远程查看—低功耗待机”的完整守护系统,帮助用户把浇水的“玄学”变成“科学”。
方案设计
感知层
- 电容式土壤湿度传感器接入 ESP32-S3 的 GPIO34(ADC1 通道),读取模拟值。该传感器不直接接触金属,可有效延缓电解腐蚀问题。
- DHT22 接入 GPIO15,采集环境温度和湿度,用于修正浇水策略(高温低湿时建议增加浇水频率)。
控制层
- ESP32-S3 为主控制器,负责轮询传感器数据、状态融合与逻辑决策。
- 设定湿度阈值:低于 25% 触发缺水预警;25%-50% 为适宜;高于 70% 提示暂停浇水。阈值可在代码开头宏定义修改。
执行层
- 预留 GPIO4 控制继电器模块,驱动小型潜水泵进行自动补水。
- 同时接一个蜂鸣器至 GPIO5,当土壤湿度极低或持续过高时发出简短提示音。
日志/联网层
- ESP32-S3 通过 MQTT 协议将数据上报至公共 Broker(如
broker.emqx.io),Topic 为balcony/pot/soil。 - OLED 本地显示实时数据和 IP 地址。
- 启用 modem_sleep 和 light_sleep,在两次采样间隔(默认 30 分钟)内不持续占用 Wi-Fi,降低平均功耗。
物料清单
| 物料名称 | 数量 | 用途 | 估算单价(元) |
|---|---|---|---|
| ESP32-S3-DevKitC-1 | 1 | 主控芯片 | 28.0 |
| 电容式土壤湿度传感器 | 1 | 土壤湿度感知 | 8.5 |
| DHT22 温湿度传感器模块 | 1 | 环境温湿度采集 | 7.0 |
| 0.96 寸 OLED(I2C) | 1 | 本地状态显示 | 10.0 |
| 5V 微型继电器模块 | 1 | 控制水泵通断 | 2.5 |
| 3.3V 蜂鸣器模块 | 1 | 预警提示 | 1.2 |
| 杜邦线/JST 连接线 | 若干 | 接线连接 | 2.0 |
| 合计 | - | - | 59.2 |
接线与结构
| 模块 | 引脚 | ESP32-S3 GPIO |
|---|---|---|
| 土壤湿度模块 AO | A0 | GPIO34 |
| 土壤湿度模块 VCC | - | 3.3V |
| 土壤湿度模块 GND | - | GND |
| DHT22 DATA | - | GPIO15 |
| OLED SCL | - | GPIO22 |
| OLED SDA | - | GPIO21 |
| 继电器 IN | - | GPIO4 |
| 蜂鸣器 I/O | - | GPIO5 |
接线说明:本项目完全遵循建议接线,未做 GPIO 微调。OLED 使用 I2C 标准引脚(SCL=22,SDA=21),湿度传感器模拟输出接 ADC 可用通道 GPIO34。继电器和蜂鸣器采用数字输出 GPIO4/5,避免与 I2C 和 ADC 冲突。
核心代码
本方案使用 Arduino 框架(PlatformIO 环境)编写,可直接编译烧录。
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// Wi-Fi 与 MQTT 配置
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const char* mqtt_server = "broker.emqx.io";
WiFiClient espClient;
// 引脚定义
#define SOIL_PIN 34
#define DHT_PIN 15
#define OLED_SDA 21
#define OLED_SCL 22
#define RELAY_PIN 4
#define BUZZER_PIN 5
// 阈值定义
#define DRY_THRESHOLD 25
#define WET_THRESHOLD 70
DHT dht(DHT_PIN, DHT22);
Adafruit_SSD1306 display(128, 64, &Wire;, -1);
unsigned long lastPublish = 0;
const unsigned long interval = 1800000; // 30分钟上报一次
void setup() {
Serial.begin(115200);
pinMode(SOIL_PIN, INPUT);
pinMode(DHT_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
display.clearDisplay();
dht.begin();
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastPublish >= interval) {
lastPublish = now;
int soilRaw = analogRead(SOIL_PIN);
int humidity = map(soilRaw, 2900, 1200, 0, 100); // 根据实际饱和度校准
humidity = constrain(humidity, 0, 100);
float temp = dht.readTemperature();
float airHum = dht.readHumidity();
// 自动浇水逻辑
if (humidity < DRY_THRESHOLD) {
digitalWrite(RELAY_PIN, HIGH);
tone(BUZZER_PIN, 1000, 200);
} else if (humidity > WET_THRESHOLD) {
digitalWrite(RELAY_PIN, LOW);
}
// OLED 显示
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.printf("Soil: %d%%", humidity);
display.setCursor(0, 16);
display.printf("Temp: %.1f C", temp);
display.setCursor(0, 32);
display.printf("AirH: %.1f %%", airHum);
display.display();
// MQTT 发布
String payload = "{\"soil\":" + String(humidity) +
",\"temp\":" + String(temp) +
",\"airh\":" + String(airHum) + "}";
client.publish("balcony/pot/soil", payload.c_str());
// 进入浅睡眠,等待下一个周期
esp_light_sleep_start();
}
}
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP32S3_SoilGuard")) {
} else {
delay(1000);
}
}
}
调试步骤
- 烧录前将代码中的 SSID 和密码改为实际值,MQTT Broker 地址不做更改。
- 将传感器插入干燥土壤,读取串口输出的
soilRaw最大值;再将传感器插入水中,读取最小值。修改map()函数参数完成一对一校准。 - 用手机安装 MQTT 调试工具(如 MQTT Dashboard),订阅
balcony/pot/soil主题,验证数据是否正常上报。 - 调整
DRY_THRESHOLD和WET_THRESHOLD值至适合实际植物的水平。 - 测试自动浇水:将传感器放置在干燥花盆中,确认继电器吸合并水泵启动;再用湿毛巾包裹传感器,确认水泵停止运行。
设计图
阳台盆栽土壤湿度守护结构flow
1
感知输入
→
2
控制处理
→
3
执行反馈
→
4
数据上报
感知输入层包含土壤湿度传感器与 DHT22,数据流经控制处理层后,将指令分发至执行反馈层(继电器/水泵与蜂鸣器),同时通过 MQTT 上报至云端。整个系统由 ESP32-S3 在低功耗循环周期内串联所有环节,实现对盆栽全天候守护。