Primeiros passos com o XIAO Soil Moisture Sensor

Introdução
O XIAO Soil Moisture Sensor é um monitor ambiental compacto e de baixo consumo, alimentado pelo XIAO ESP32-C6. Funcionando com uma única bateria AA, ele oferece operação de longa duração e atualizações em tempo real das condições do solo. Possui detecção adaptativa de umidade do solo pré-calibrada para um monitoramento preciso. Ao mesmo tempo, permite intervalos de monitoramento dinâmicos e leituras instantâneas para dados precisos e responsivos. Totalmente compatível com o Home Assistant, é ideal para jardinagem inteligente e agricultura de precisão — eficiente, confiável e feito para um cuidado sustentável das plantas.
Recursos
1. Monitoramento de umidade do solo em três níveis
- 🌿 Normal: A umidade do solo está ideal, não é necessário regar.
- 🌤 Quase seco: A umidade está diminuindo, prepare-se para regar em breve.
- 🌵 Seco: Criticamente baixa, regue imediatamente.
Limiares padrão:
- 60% → Transição de verde para amarelo.
- 20% → Transição de amarelo para vermelho.

2. Plug-and-Play com Home Assistant
Pré-carregado com ESPHome — funciona imediatamente com o Home Assistant, permitindo monitorar e automatizar diretamente a partir do painel da sua casa inteligente.
3. Monitoramento adaptativo e leitura instantânea
- Ajusta automaticamente os intervalos de verificação (8h → 1h → 15min) dependendo do nível de umidade.
- Pressione o botão uma vez para obter uma leitura instantânea de umidade a qualquer momento.
4. Calibração simples (opcional)
Pressione rapidamente o botão três vezes para recalibrar para o seu solo específico: leitura em solo seco + leitura em solo molhado → o sistema se ajusta automaticamente.
- Três pressões curtas → Entrar no modo de calibração:
- O LED vermelho pisca → Em até 10 segundos, insira o sensor em solo completamente seco.
- Aguarde até o LED vermelho parar de piscar e então espere 3 segundos.
- O LED verde pisca → Em até 10 segundos, insira o sensor em solo totalmente molhado.
- Aguarde até o LED verde parar de piscar e então espere 3 segundos.
- Resultado da calibração:
- Dois rápidos flashes verdes → Sucesso.
- Dois rápidos flashes vermelhos → Falha (provavelmente devido à inversão das leituras de solo seco/molhado).
Observação: Durante a calibração, as leituras iniciais podem ser instáveis se o sensor não for inserido rapidamente. O sistema fará múltiplas amostragens, aplicará filtragem e fará a média das leituras para uma calibração confiável.

Visão geral do hardware

Primeiros passos
Esta seção irá guiá-lo na configuração do seu XIAO Soil Moisture Sensor pela primeira vez.
Materiais necessários
Antes de iniciar o conteúdo do tutorial deste artigo, talvez você precise ter o seguinte hardware pronto.
| XIAO Soil Moisture Sensor | Home Assistant Green |
|---|---|
![]() | ![]() |
O Home Assistant Green é a forma mais fácil e com maior foco em privacidade para automatizar sua casa. Ele oferece uma configuração sem esforço e permite controlar todos os dispositivos inteligentes com apenas um sistema, onde todos os dados são armazenados localmente por padrão. Esta placa se beneficia do ecossistema em crescimento do Home Assistant e será melhorada todos os meses por meio de código aberto.
Recomendamos usar o Home Assistant Green como o host do Home Assistant para este tutorial, ou você pode usar qualquer host de Home Assistant com Supervisor.
Também escrevemos como instalar o Home Assistant para alguns produtos da Seeed Studio, consulte-os.
- Primeiros passos com Home Assistant no ODYSSEY-X86
- Primeiros passos com Home Assistant no reTerminal
- Primeiros passos com Home Assistant no LinkStar H68K/reRouter CM4
Se você não estiver usando um produto Seeed Studio, também pode verificar e aprender como instalar o Home Assistant para outros produtos no site oficial do Home Assistant.
Etapa 1. Instalar o ESPHome
Se você já instalou o ESPHome, pode pular esta etapa.
Vá para Settings -> Add-ons -> ADD-ON STORE


Pesquise por ESPHome e clique nele. Clique em INSTALL e START.
Se você não encontrar o ESPHome na loja de complementos, certifique-se de que está usando uma instalação do Home Assistant que oferece suporte a complementos (como Home Assistant OS ou instalações supervisionadas). Para outros tipos de instalação (como Home Assistant Container), talvez seja necessário executar o ESPHome Device Builder de forma independente usando Docker. Consulte a documentação oficial do ESPHome para mais detalhes.

Em seguida, o ESPHome Builder aparecerá na barra lateral.

Etapa 2: Preparando o Soil Moisture Sensor
Por padrão, seu dispositivo (XIAO ESP32C6) vem pré-gravado com o firmware para o XIAO Soil Moisture Sensor. No entanto, se você precisar modificar ou atualizar o firmware padrão, um arquivo de configuração YAML de fábrica está disponível na seção Recursos abaixo. Você pode personalizar a lógica conforme necessário e gravá-lo via Home Assistant.
Para garantir leituras precisas, basta realizar uma rápida calibração do sensor antes de usar.
Etapa 3: Configuração de rede
-
Ativar o ponto de acesso:
- Ao ligar pela primeira vez, o módulo criará uma rede Wi-Fi (SSID:
Xiao-Soil-Moisture-Monitor).
- Ao ligar pela primeira vez, o módulo criará uma rede Wi-Fi (SSID:
-
Acessar a configuração:
- Conecte-se à rede usando um telefone ou PC.
- Abra um navegador e acesse
http://192.168.4.1. - Insira o SSID e a senha da sua rede Wi-Fi doméstica.

- Integração com Home Assistant:
- Depois de conectado à rede doméstica, o módulo poderá ser descoberto no Home Assistant em
Settings -> Devices & Services.
- Depois de conectado à rede doméstica, o módulo poderá ser descoberto no Home Assistant em

Dessa forma, você pode conectar o módulo à sua rede Home Assistant e deixar o Home Assistant descobri-lo.
Etapa 4: Adicionar o dispositivo do módulo
-
Descoberta automática:
- Certifique-se de que o ESPHome esteja instalado no Home Assistant.
- Navegue até
Settings -> Devices & Services -> Integrationse procure pelo dispositivo.
-
Configuração manual:
- Se não for descoberto automaticamente, adicione o dispositivo manualmente especificando seu endereço IP.
Depois de adicionar o dispositivo, você verá um novo cartão de sensor chamado Solid_sensor na página Overview do Home Assistant, exibindo tanto a medição da bateria quanto o status atual de umidade do solo.

Agora que seu sensor de solo está funcionando, divirta-se monitorando suas plantas!

Uso avançado
Você pode modificar a lógica original do firmware e gravar sua versão personalizada do sensor de solo diretamente através do Home Assistant.
Passo 1. Instale o ESPHome
Veja o guia de instalação no Passo 1 acima.
Passo 2. Adicione um novo dispositivo
Vá para o ESPHome e clique em NEW DEVICE.

Dê ao dispositivo um nome de sua preferência e clique em NEXT.



Depois de criar um novo dispositivo, clique em EDIT.

Passo 3. Instale o firmware
Aqui está o firmware de fábrica:
Aqui está uma configuração YAML ESPHome pronta para uso no Home Assistant:
Clique aqui para visualizar o código completo
# ==== AUTO-SYNC START: xiao-soil-moisture-monitor/xiao-soil-moisture-monitor.yaml ====
substitutions:
name: "xiao-soil-moisture"
friendly_name: "XIAO Soil Moisture Monitor"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
name_add_mac_suffix: true
project:
name: "xiao.soil-moisture-monitor"
version: "1.0"
on_boot:
then:
- output.turn_off: gpio_3_output
- output.turn_on: gpio_14_output
- light.turn_on:
id: pwm_led
brightness: 68% # Set 68% duty cycle
- if:
condition:
lambda: 'return id(wifi_net_status) == 0;'
then:
- logger.log: "The device has not been set to the network"
- deep_sleep.prevent: deep_sleep_control
else:
- logger.log: "The device has been networked"
- delay: 1s
- script.execute: check_moisture_once
esp32:
board: esp32-c6-devkitc-1
framework:
type: esp-idf
# LED Yellow D10 18
# LED RED D9 20
# LED Green D8 19
# button D2 2
# Battery D0 0
# PWM out D3 21
# Soil sensor 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 # Set the frequency to 200kHz
- platform: gpio
pin: GPIO3
id: gpio_3_output
- 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: "Starting calibration"
- 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", "Dry value: %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", "Wet value: %f", id(wet_value));
- delay: 3s
- lambda: |-
if (id(dry_value) > id(wet_value)) {
ESP_LOGI("calibration", "Calibration success");
id(fast_blink_green).execute();
} else {
ESP_LOGW("calibration", "Calibration failed");
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", "Moisture reading: %f", moisture);
float Diff = id(dry_value) - id(wet_value);
ESP_LOGI("moisture_check", "Diff is: %f", Diff);
ESP_LOGI("moisture_check", "ref_dry Diff is: %f",id(dry_value) - Diff * id(ref_dry));
ESP_LOGI("moisture_check", "ref_wet Diff is: %f",id(dry_value) - Diff * id(ref_wet));
if (moisture >= (id(dry_value) - Diff * id(ref_dry))) { // The drier -> the higher the voltage
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 # Delay 1 second to see if the button is pressed 3 times in a row
- lambda: |-
if (id(button_press_count) == 3) {
id(button_press_count) = 0;
id(do_calibration).execute(); // Trigger calibration process
} else if (id(button_press_count) == 1) {
id(button_press_count) = 0;
id(check_moisture_once).execute(); // Perform an ADC decision
} else {
id(button_press_count) = 0;
}
# interval:
# - interval: 10s
# then:
# - script.execute: check_moisture_once
# Deep sleep configuration
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
sensor:
- platform: adc
id: soil_sensor
pin: GPIO1
name: "Soil moisture measurement"
update_interval: 4s
internal: true
attenuation: 12db
- platform: adc
pin: GPIO0
name: "Battery measurement"
attenuation: 12db
# internal: true
filters: # When the battery drops below 1V, it is dead.
- lambda: |-
if (x < 1.2) {
return 0.0;
}else if(x > 1.5){
return 1.0 * 100.0;
}else {
return ((x - 1.2) / (1.5 - 1.2)) * 100.0;
}
unit_of_measurement: "%"
update_interval: 5s
force_update: True
- platform: wifi_signal
name: "wifi singnal strength"
update_interval: 10s
# text_sensor:
# - platform: template
# name: "Soil Moisture Status" # ✅ Status displayed on the HA panel
# id: soil_status
# # internal: true
# 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(red_led_blink_3_times).execute();
# return {"Dry"};
# } else if (value > (id(dry_value) - Diff * id(ref_wet)) && value < (id(dry_value) - Diff * id(ref_dry))) {
# //id(yellow_led_blink_3_times).execute();
# return {"Almost Dry"};
# } else {
# //id(green_led_blink_3_times).execute();
# return {"Normal Moisture"};
# }
# update_interval: 5s
text_sensor:
- platform: template
name: "Soil Moisture Status"
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 {"Dry"};
} else if (value > (id(dry_value) - Diff * id(ref_wet)) && value < (id(dry_value) - Diff * id(ref_dry))) {
return {"Almost Dry"};
} else {
return {"Normal Moisture"};
}
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 "Dry";
} 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 "Almost Dry";
} else {
id(deep_sleep_control).set_sleep_duration(28800000);
return "Normal Moisture";
}
# Enable logging
logger:
improv_serial:
# Enable Home Assistant API
api:
ota:
- platform: esphome
wifi:
on_connect:
then:
- if:
condition:
lambda: 'return id(wifi_net_status) == 0;'
then:
- logger.log: "The device has not been configured yet, but now it is successfully configured"
- globals.set:
id: wifi_net_status
value: '1'
- delay: 5s
- deep_sleep.allow: deep_sleep_control
else:
- logger.log: "The device has been networked"
on_disconnect:
then:
- globals.set:
id: wifi_net_status
value: '0'
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "XIAO-Soil-Moisture-Monitor"
captive_portal:
# ==== AUTO-SYNC END ====
Aqui está uma visão geral das principais funções e lógicas usadas na configuração YAML.
on_boot – Define o que acontece quando o dispositivo é inicializado.
- Parâmetros de entrada: Nenhum.
- Ação: Liga o GPIO 14, define o brilho do LED PWM, verifica o status do Wi‑Fi e aciona a primeira verificação de umidade.
scripts (red_led_blink, green_led_blink, fast_blink_green, fast_blink_red, etc.) – Padrões predefinidos de piscar de LED.
- Parâmetros de entrada: Nenhum.
- Ação: Faz os LEDs piscarem em vários padrões para indicar status ou etapas de calibração.
do_calibration – Executa o processo de calibração para solo seco e úmido.
- Parâmetros de entrada: Nenhum.
- Ação: Pisca o LED vermelho, aguarda a leitura em seco; depois pisca o LED verde, aguarda a leitura em úmido; armazena valores médios e confirma sucesso ou falha.
check_moisture_once – Lê e avalia os níveis de umidade do solo.
- Parâmetros de entrada: Nenhum.
- Ação: Faz múltiplas leituras do ADC, calcula a média, compara com os limiares calibrados, decide o estado de umidade, aciona os LEDs e as configurações de deep sleep de acordo.
binary_sensor (GPIO2) – Lida com a lógica de pressionamento do botão físico.
- Parâmetros de entrada: Nenhum.
- Ação: Conta os pressionamentos do botão; um toque aciona uma verificação de umidade, três toques acionam a calibração.
globals – Armazena o estado do sistema e os dados de calibração.
- Variáveis:
button_press_count: Rastreia a contagem de pressionamentos do botão.dry_value,wet_value: Armazena valores ADC calibrados para seco/úmido.wifi_net_status: Rastreia o estado da conexão Wi‑Fi.ref_dry,ref_wet: Fatores de escala de referência para cálculos de limiar.
deep_sleep – Gerencia ciclos de economia de energia em modo de suspensão.
- Parâmetros de entrada: Nenhum.
- Ação: Executa por 120 segundos e depois entra em suspensão por até 180 minutos; acorda ao pressionar o botão ou em intervalos.
sensor (ADC) – Lê valores analógicos do sensor de solo e da bateria.
- Parâmetros de entrada: Nenhum.
- Ação: Mede a umidade do solo e a tensão da bateria; a bateria é escalonada para mostrar a porcentagem.
text_sensor – Publica o status de umidade do solo em formato legível por humanos.
- Parâmetros de entrada: Nenhum.
- Ação: Exibe "Dry", "Almost Dry" ou "Normal Moisture" no Home Assistant.
wifi + api + ota – Gerencia a conexão de rede, a integração com o Home Assistant e as atualizações de firmware over‑the‑air.
- Parâmetros de entrada: SSID e senha do Wi‑Fi.
- Ação: Conecta o dispositivo à rede, expõe sua API e permite atualizações remotas.
Clique em INSTALL para instalar o código no dispositivo e você verá a seguinte imagem.
- Install through browser
- Install through host
- Install through Wi-Fi
Se o seu Home Assistant Host (Raspberry PI/Green/Yellow etc.) estiver longe de você, recomendamos usar este método. Você pode instalar com o computador que tiver em mãos.
Primeiro, você precisa clicar em Manual download para baixar o firmware compilado.

Abra este site onde faremos o upload do firmware para o painel ePaper.

Volte para o ESPHome para baixar o firmware.

Selecione o formato Factory.

Use um cabo USB para conectar o painel ePaper ao seu computador e clique em CONNECT.

Selecione usbmodemxxx (no Windows é COMxxx) e clique em connect.

Clique em INSTALL e selecione o firmware que você acabou de baixar.

Seu firmware será gravado em breve ~

Se o seu Home Assistant Host (Raspberry PI/Green/Yellow etc.) estiver por perto, recomendamos usar este método, pois é mais simples.
Antes de instalar o código no dispositivo, você precisa usar um cabo USB para conectar este dispositivo ao seu Raspberry Pi ou HA Green(Yellow) etc. que está executando o Home Assistant.
Clique nas opções conforme a imagem para instalar o código no dispositivo.


Aguarde um momento e você verá o retorno como na imagem a seguir. Isso significa que o código está sendo executado com sucesso.

Este é o método mais simples, mas com o pré-requisito de que, ao instalar o programa pela primeira vez, você deve primeiro fazer o upload do programa para o painel ePaper usando o método à esquerda. Depois disso, você pode fazer o upload via Wi‑Fi. Além disso, certifique‑se de que sua configuração YAML inclua seções ota e api devidamente configuradas com chaves de criptografia válidas para que este método funcione.
Dessa forma, você não precisa conectar o painel ePaper a nada, apenas certifique‑se de que ele esteja online.
Clique na opção e o firmware será instalado automaticamente no painel ePaper.

Aguarde um momento e você verá o retorno como na imagem a seguir. Se falhar, pode ser devido a um sinal fraco. Por favor, aproxime o dispositivo do seu roteador.

Resetar
Se o firmware precisar ser regravado, você pode usar o seguinte link para restaurar o firmware padrão:
https://gadgets.seeed.cc/
Conecte primeiro o seu dispositivo ao computador.
Depois, encontre XIAO Soil Moisture Monitor na página e clique em Connect para prosseguir com a nova gravação.
Recursos
- [PDF] XIAO Soil Moisture Sensor SCH
- [Kicad] XIAO Soil Moisture Sensor PCB
- [Yaml] XIAO Soil Moisture Sensor HA Yaml
- [Bin] XIAO Soil Moisture Sensor HA Factory Bin
- [LINK] XIAO Soil Moisture Sensor 3D file Printtables
- [LINK] XIAO Soil Moisture Sensor 3D file Thingiverse
Suporte Técnico & Discussão de Produto
Obrigado por escolher nossos produtos! Estamos aqui para oferecer diferentes tipos de suporte para garantir que sua experiência com nossos produtos seja a mais tranquila possível. Oferecemos vários canais de comunicação para atender a diferentes preferências e necessidades.

