XIAO 土壤湿度传感器入门指南

介绍
XIAO 土壤湿度传感器是一款紧凑、低功耗的环境监测器,由 XIAO ESP32-C6 驱动。仅使用一节 AA 电池供电,提供持久的运行时间和实时的土壤状况更新。它具有预校准自适应土壤湿度感应功能,可精确监测土壤状况。同时,它支持动态监测间隔和即时读数,提供准确、响应迅速的数据。完全兼容 Home Assistant,是智能园艺和精准农业的理想选择——高效、可靠,专为可持续植物护理而设计。
特性
1.三级土壤湿度监测
- 🌿 正常: 土壤湿度最佳,无需浇水。
- 🌤 接近干燥: 湿度正在下降,准备尽快浇水。
- 🌵 干燥: 严重缺水,立即浇水。
默认阈值:
- 60% → 绿色到黄色转换。
- 20% → 黄色到红色转换。

2.与 Home Assistant 即插即用
预装 ESPHome — 开箱即用,与 Home Assistant 配合使用,让您直接从智能家居仪表板监控和自动化。
3.自适应监测和即时读数
- 根据湿度水平自动调整检查间隔(8小时 → 1小时 → 15分钟)。
- 随时按一次按钮即可获得即时湿度读数。
4.简单校准(可选)
快速三次按下按钮即可为您的特定土壤重新校准:干燥读数 + 湿润读数 → 系统自动调整。
- 三次短按 → 进入校准模式:
- 红色 LED 闪烁 → 在 10 秒内,将传感器插入完全干燥的土壤中。
- 等待红色 LED 停止闪烁,然后等待 3 秒。
- 绿色 LED 闪烁 → 在 10 秒内,将传感器插入完全湿润的土壤中。
- 等待绿色 LED 停止闪烁,然后等待 3 秒。
- 校准结果:
- 两次快速绿色闪烁 → 成功。
- 两次快速红色闪烁 → 失败(可能是由于干燥/湿润读数颠倒)。
注意:在校准过程中,如果传感器没有及时插入,初始读数可能不稳定。系统将进行多次采样,应用滤波,并对读数进行平均以确保可靠的校准。

5.长电池寿命
由单节 AA 电池供电,通过优化的电源管理设计,可持续使用长达三个月。
硬件概述

入门指南
本节将指导您首次设置 XIAO 土壤湿度传感器。
所需材料
在本文教程内容开始之前,您可能需要准备以下硬件。
Home Assistant Green 是自动化您家庭的最简单且最注重隐私的方式。它提供轻松的设置,让您只需一个系统就能控制所有智能设备,默认情况下所有数据都存储在本地。这款主板受益于蓬勃发展的 Home Assistant 生态系统,并将通过开源每月得到改进。
我们建议在本教程中使用 Home Assistant Green 作为 Home Assistant 主机,或者您可以使用任何带有 Supervisor 的 Home Assistant 主机。
我们还为一些 Seeed Studio 产品编写了如何安装 Home Assistant 的教程,请参考它们。
- 在 ODYSSEY-X86 上开始使用 Home Assistant
- 在 reTerminal 上开始使用 Home Assistant
- 在 LinkStar H68K/reRouter CM4 上开始使用 Home Assistant
如果您没有使用 Seeed Studio 产品,您也可以在官方 Home Assistant 网站上查看并学习如何为其他产品安装 Home Assistant。
步骤 1. 安装 ESPHome
如果您已经安装了 ESPHome,可以跳过此步骤。
转到 Settings -> Add-ons -> ADD-ON STORE


搜索 ESPHome 并点击它。点击 INSTALL 和 START。
如果您在附加组件商店中找不到 ESPHome,请确保您使用的是支持附加组件的 Home Assistant 安装(如 Home Assistant OS 或监督安装)。对于其他安装类型(如 Home Assistant Container),您可能需要使用 Docker 独立运行 ESPHome Device Builder。有关更多详细信息,请参阅官方 ESPHome 文档。

然后,ESPHome Builder 将出现在侧边栏中。

步骤 2:准备土壤湿度传感器
默认情况下,您的设备(XIAO ESP32C6)预装了 XIAO 土壤湿度传感器的固件。但是,如果您需要修改或升级默认固件,可以在下面的资源部分找到出厂 YAML 配置文件。您可以根据需要自定义逻辑并通过 Home Assistant 刷写。
为确保读数准确,请在使用前对传感器进行快速校准。
步骤 3:网络配置
-
启用接入点:
- 首次上电时,模块将创建一个 Wi-Fi 网络(SSID:
Xiao-Soil-Moisture-Monitor
)。
- 首次上电时,模块将创建一个 Wi-Fi 网络(SSID:
-
访问配置:
- 使用手机或电脑连接到该网络。
- 打开浏览器并导航到
http://192.168.4.1
。 - 输入您家庭 Wi-Fi 网络的 SSID 和密码。

- Home Assistant 集成:
- 连接到家庭网络后,模块将在 Home Assistant 的
Settings -> Devices & Services
下可被发现。
- 连接到家庭网络后,模块将在 Home Assistant 的

这样,您可以将模块连接到您的 Home Assistant 网络并让 Home Assistant 发现它。
步骤 4:添加模块设备
-
自动发现:
- 确保在 Home Assistant 中安装了 ESPHome。
- 导航到
Settings -> Devices & Services -> Integrations
并查找设备。
-
手动配置:
- 如果没有自动发现,请通过指定其 IP 地址手动添加设备。
添加设备后,您将在Home Assistant概览页面上看到一个名为Solid_sensor的新传感器卡片,显示电池测量值和当前土壤湿度状态。

现在您的土壤传感器已经启动并运行,请尽情享受监测植物的乐趣吧!

高级用法
您可以修改原始固件逻辑,并直接通过Home Assistant刷写您的自定义版本土壤传感器。
步骤1. 安装ESPHome
请参阅上面步骤1中的安装指南。
步骤2. 添加新设备
转到ESPHome并点击NEW DEVICE。

给设备起一个您喜欢的名称,然后点击NEXT。



创建新设备后,点击EDIT。

步骤3. 安装固件
这里是出厂固件:
这里是一个可直接使用的ESPHome
YAML配置,适用于Home Assistant:
点击这里预览完整代码
esphome:
name: soil-moisture-monitor
friendly_name: XIAO 土壤湿度监测器
platformio_options:
platform: https://github.com/mnowak32/platform-espressif32.git#boards/seeed_xiao_esp32c6
on_boot:
then:
# - output.turn_off: gpio_3_output
- output.turn_on: gpio_14_output
- light.turn_on:
id: pwm_led
brightness: 68% # 设置68%占空比
- if:
condition:
lambda: 'return id(wifi_net_status) == 0;'
then:
- logger.log: "设备尚未设置网络"
- deep_sleep.prevent: deep_sleep_control
else:
- logger.log: "设备已联网"
- delay: 1s
- script.execute: check_moisture_once
esp32:
board: seeed_xiao_esp32c6
variant: ESP32C6
flash_size: 4MB
framework:
type: esp-idf
version: "5.2.1"
platform_version: 6.6.0
sdkconfig_options:
CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y
# LED 黄色 D10 18
# LED 红色 D9 20
# LED 绿色 D8 19
# 按钮 D2 2
# 电池 D0 0
# PWM 输出 D3 21
# 土壤传感器 D1 1
output:
- platform: gpio
pin: GPIO18
id: yellow_led_output
- platform: gpio
pin: GPIO19
id: green_led_output
- platform: gpio
pin: GPIO20
id: red_led_output
- platform: ledc
pin: GPIO21
id: pwm_output
frequency: 200kHz # 设置频率为200kHz
- platform: gpio
pin: GPIO14
id: gpio_14_output
light:
- platform: binary
id: yellow_led
output: yellow_led_output
- platform: binary
id: green_led
output: green_led_output
- platform: binary
id: red_led
output: red_led_output
- platform: monochromatic
output: pwm_output
id: pwm_led
name: "200kHz PWM"
internal: true
default_transition_length: 0s
script:
- id: red_led_blink
mode: restart
then:
- repeat:
count: 10
then:
- light.turn_on: red_led
- delay: 500ms
- light.turn_off: red_led
- delay: 500ms
- id: green_led_blink
mode: restart
then:
- repeat:
count: 10
then:
- light.turn_on: green_led
- delay: 500ms
- light.turn_off: green_led
- delay: 500ms
- id: fast_blink_green
then:
- repeat:
count: 5
then:
- light.turn_on: green_led
- delay: 200ms
- light.turn_off: green_led
- delay: 200ms
- id: fast_blink_red
then:
- repeat:
count: 5
then:
- light.turn_on: red_led
- delay: 200ms
- light.turn_off: red_led
- delay: 200ms
- id: red_led_blink_3_times
then:
- repeat:
count: 1
then:
- light.turn_on: red_led
- delay: 1000ms
- light.turn_off: red_led
- delay: 100ms
- id: yellow_led_blink_3_times
then:
- repeat:
count: 1
then:
- light.turn_on: yellow_led
- delay: 1000ms
- light.turn_off: yellow_led
- delay: 100ms
- id: green_led_blink_3_times
then:
- repeat:
count: 1
then:
- light.turn_on: green_led
- delay: 1000ms
- light.turn_off: green_led
- delay: 100ms
- id: do_calibration
then:
- deep_sleep.prevent: deep_sleep_control
- logger.log: "开始校准"
- script.execute: red_led_blink
- delay: 10s
- script.stop: red_led_blink
- lambda: |-
float sum = 0;
for (int i = 0; i < 10; i++) {
id(soil_sensor).update();
sum += id(soil_sensor).state;
delay(200);
}
id(dry_value) = sum / 10.0;
ESP_LOGI("calibration", "干燥值: %f", id(dry_value));
- delay: 3s
- script.execute: green_led_blink
- delay: 10s
- script.stop: green_led_blink
- lambda: |-
float sum = 0;
for (int i = 0; i < 10; i++) {
id(soil_sensor).update();
sum += id(soil_sensor).state;
delay(200);
}
id(wet_value) = sum / 10.0;
ESP_LOGI("calibration", "湿润值: %f", id(wet_value));
- delay: 3s
- lambda: |-
if (id(dry_value) > id(wet_value)) {
ESP_LOGI("calibration", "校准成功");
id(fast_blink_green).execute();
} else {
ESP_LOGW("calibration", "校准失败");
id(fast_blink_red).execute();
}
- delay: 3s
- script.execute: check_moisture_once
- delay: 3s
- deep_sleep.enter: deep_sleep_control
- id: check_moisture_once
then:
- lambda: |-
for(int i = 0; i < 10; i++){
id(soil_sensor).update();
delay(200);
}
float moisture = id(soil_sensor).state;
ESP_LOGI("moisture_check", "湿度读数: %f", moisture);
float Diff = id(dry_value) - id(wet_value);
ESP_LOGI("moisture_check", "差值为: %f", Diff);
ESP_LOGI("moisture_check", "ref_dry 差值为: %f",id(dry_value) - Diff * id(ref_dry));
ESP_LOGI("moisture_check", "ref_wet 差值为: %f",id(dry_value) - Diff * id(ref_wet));
if (moisture >= (id(dry_value) - Diff * id(ref_dry))) { // 越干燥 -> 电压越高
id(red_led_blink_3_times).execute();
id(deep_sleep_control).set_sleep_duration(900000);
} else if(moisture > (id(dry_value) - Diff * id(ref_wet)) && moisture < (id(dry_value) - Diff * id(ref_dry))){
id(yellow_led_blink_3_times).execute();
id(deep_sleep_control).set_sleep_duration(3600000);
}else{
// moisture > (id(dry_value) - Diff * id(ref_wet))
id(green_led_blink_3_times).execute();
id(deep_sleep_control).set_sleep_duration(28800000);
}
globals:
- id: button_press_count
type: int
restore_value: no
initial_value: '0'
- id: dry_value
type: float
restore_value: yes
initial_value: '2.75'
- id: wet_value
type: float
restore_value: yes
initial_value: '1.2'
- id: wifi_net_status
type: int
restore_value: yes
initial_value: "0"
- id: ref_dry
type: float
restore_value: no
initial_value: "0.23"
- id: ref_wet
type: float
restore_value: no
initial_value: "0.58"
binary_sensor:
- platform: gpio
pin:
number: GPIO2
mode: INPUT_PULLUP
allow_other_uses: true
id: my_button
on_press:
- lambda: |-
id(button_press_count)++;
- delay: 1s # 延迟1秒,看按钮是否连续按下3次
- lambda: |-
if (id(button_press_count) == 3) {
id(button_press_count) = 0;
id(do_calibration).execute(); // 触发校准过程
} else if (id(button_press_count) == 1) {
id(button_press_count) = 0;
id(check_moisture_once).execute(); // 执行一次ADC判断
} else {
id(button_press_count) = 0;
}
deep_sleep:
id: deep_sleep_control
run_duration: 120s
sleep_duration: 180min
wakeup_pin:
number: GPIO2
inverted: true
allow_other_uses: true
mode: INPUT_PULLUP
external_components:
- source: github://pr#7942
components: [ "adc" ]
- source:
type: git
url: https://github.com/ackPeng/esphome.git
ref: api
components: [ api ]
refresh: 0s
sensor:
- platform: adc
id: soil_sensor
pin: GPIO1
name: "土壤湿度测量"
update_interval: 4s
internal: true
attenuation: 12db
- platform: adc
pin: GPIO0
name: "电池测量"
attenuation: 12db
filters: # 当电池电压低于1V时,电池耗尽
- lambda: |-
if (x < 1.0) {
return 0.0;
} else {
return ((x - 1.0) / (1.5 - 1.0)) * 100.0;
}
unit_of_measurement: "%"
update_interval: 5s
force_update: True
- platform: wifi_signal
name: "wifi信号强度"
update_interval: 10s
text_sensor:
- platform: template
name: "土壤湿度状态"
id: soil_status
lambda: |-
float value = id(soil_sensor).state;
float Diff = id(dry_value) - id(wet_value);
if (value >= (id(dry_value) - Diff * id(ref_dry))) {
return {"干燥"};
} else if (value > (id(dry_value) - Diff * id(ref_wet)) && value < (id(dry_value) - Diff * id(ref_dry))) {
return {"接近干燥"};
} else {
return {"湿度正常"};
}
update_interval: never # 不让自动触发上报,我们自己控制
interval:
- interval: 5s
then:
- text_sensor.template.publish:
id: soil_status
state: !lambda |-
return "";
- delay: 10ms
- text_sensor.template.publish:
id: soil_status
state: !lambda |-
float value = id(soil_sensor).state;
float Diff = id(dry_value) - id(wet_value);
if (value >= (id(dry_value) - Diff * id(ref_dry))) {
id(deep_sleep_control).set_sleep_duration(900000);
return "干燥";
} else if (value > (id(dry_value) - Diff * id(ref_wet)) && value < (id(dry_value) - Diff * id(ref_dry))) {
id(deep_sleep_control).set_sleep_duration(3600000);
return "接近干燥";
} else {
id(deep_sleep_control).set_sleep_duration(28800000);
return "湿度正常";
}
# 启用日志记录
logger:
improv_serial:
# 启用Home Assistant API
api:
# encryption:
# key: "YVjz+1l5zHXeyXFVinhaJkqh8RnG0gUVjaWniPEzCj4="
ota:
- platform: esphome
password: "dcad8df988971d761bc72a30d7878a40"
wifi:
# ssid: "my68k"
# password: "1143590135"
on_connect:
then:
- if:
condition:
lambda: 'return id(wifi_net_status) == 0;'
then:
- logger.log: "设备尚未配置,但现在已成功配置"
- globals.set:
id: wifi_net_status
value: '1'
- delay: 5s
- deep_sleep.allow: deep_sleep_control
else:
- logger.log: "设备已联网"
on_disconnect:
then:
- globals.set:
id: wifi_net_status
value: '0'
# 启用备用热点(强制门户),以防wifi连接失败
ap:
ssid: "Xiao-Soil-Moisture-Monitor"
password: ""
captive_portal:
以下是 YAML 配置中使用的关键函数和逻辑概述。
on_boot
– 定义设备启动时发生的操作。
- 输入参数:无。
- 操作:打开 GPIO 14,设置 PWM LED 亮度,检查 Wi-Fi 状态,并触发第一次湿度检查。
scripts (red_led_blink, green_led_blink, fast_blink_green, fast_blink_red, etc.)
– 预定义的 LED 闪烁模式。
- 输入参数:无。
- 操作:以各种模式闪烁 LED 以指示状态或校准步骤。
do_calibration
– 运行干燥和湿润土壤的校准过程。
- 输入参数:无。
- 操作:闪烁红色 LED,等待干燥读数;然后闪烁绿色 LED,等待湿润读数;存储平均值并确认成功或失败。
check_moisture_once
– 读取和评估土壤湿度水平。
- 输入参数:无。
- 操作:进行多次 ADC 读数,计算平均值,与校准阈值比较,确定湿度状态,相应地触发 LED 和深度睡眠设置。
binary_sensor (GPIO2)
– 处理物理按钮按压逻辑。
- 输入参数:无。
- 操作:计算按钮按压次数;单次按压触发湿度检查,三次按压触发校准。
globals
– 存储系统状态和校准数据。
- 变量:
button_press_count
:跟踪按钮按压计数。dry_value
,wet_value
:存储校准的干燥/湿润 ADC 值。wifi_net_status
:跟踪 Wi-Fi 连接状态。ref_dry
,ref_wet
:用于阈值计算的参考缩放因子。
deep_sleep
– 管理省电睡眠周期。
- 输入参数:无。
- 操作:运行 120 秒,然后睡眠最多 180 分钟;在按钮按压或间隔时唤醒。
sensor (ADC)
– 从土壤传感器和电池读取模拟值。
- 输入参数:无。
- 操作:测量土壤湿度和电池电压;电池按比例显示百分比。
text_sensor
– 发布人类可读的土壤湿度状态。
- 输入参数:无。
- 操作:在 Home Assistant 中显示"Dry"、"Almost Dry"或"Normal Moisture"。
wifi
+ api
+ ota
– 管理网络连接、Home Assistant 集成和无线固件更新。
- 输入参数:Wi-Fi SSID 和密码。
- 操作:将设备连接到网络,公开其 API,并启用远程更新。
点击 INSTALL 将代码安装到设备,您将看到以下图像。
- 通过浏览器安装
- 通过主机安装
- 通过 Wi-Fi 安装
如果您的 Home Assistant 主机(Raspberry PI/Green/Yellow 等)距离您很远,我们建议使用此方法。您可以使用手边的计算机进行安装。
首先,您需要点击 Manual download 下载编译好的固件。

打开这个网站,我们将在这里上传固件到 ePaper 面板。

返回 ESPHome 下载固件。

选择 Factory 格式。

使用 USB 线缆将 ePaper 面板连接到您的计算机并点击 CONNECT。

选择 usbmodemxxx(Windows 是 COMxxx)并点击连接。

点击 INSTALL 并选择您刚刚下载的固件。

您的固件将很快被刷入~

如果您的 Home Assistant 主机(Raspberry PI/Green/Yellow 等)就在附近,我们建议使用此方法,因为它更简单。
在将代码安装到设备之前,您需要使用 USB 线缆将此设备连接到运行 Home Assistant 的 Raspberry Pi 或 HA Green(Yellow)等设备。
按照图像中的选项点击,将代码安装到设备。


稍等片刻,您将看到如下图所示的反馈。这意味着代码正在成功运行。

这是最简单的方法,但前提是在第一次安装程序时,您应该首先使用左侧的方法将程序上传到 ePaper 面板。之后,您可以通过 wifi 上传。另外,确保您的 YAML 配置包含正确配置的 ota
和 api
部分,并具有有效的加密密钥,此方法才能正常工作。
这样,您就不需要将 ePaper 面板连接到任何设备,只需确保它在线即可。
点击该选项,固件将自动安装到 ePaper 面板。

稍等片刻,您将看到如下图所示的反馈。如果失败,可能是由于信号较弱。请将设备移近您的路由器。

重置
如果需要重新刷写固件,您可以使用以下链接恢复默认固件:
https://gadgets.seeed.cc/
首先将您的设备连接到计算机。
然后,在页面上找到 XIAO Soil Moisture Monitor 并点击 Connect 以继续重新刷写。
资源
- [PDF] XIAO 土壤湿度传感器原理图
- [Kicad] XIAO 土壤湿度传感器 PCB
- [Yaml] XIAO 土壤湿度传感器 HA Yaml
- [Bin] XIAO 土壤湿度传感器 HA 出厂固件
- [链接] XIAO 土壤湿度传感器 3D 文件 Printtables
- [链接] XIAO 土壤湿度传感器 3D 文件 Thingiverse
技术支持与产品讨论
感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。