Como construir um Sensor de Umidade do Solo Capacitivo (HW-390) para ESP8266, ESP32, Raspberry Pi Pico W para Alexa
Nesta parte, vamos orientá-lo na construção de um Sensor de Umidade do Solo Capacitivo que pode ser conectado a um ESP32, ESP8266 ou Raspberry Pi Pico W. Uma vez configurado, você poderá verificar o nível de umidade do solo usando Amazon Alexa, perguntar à Alexa sobre informações dele, e também monitorá-lo através do aplicativo Sinric Pro e enviar uma notificação push quando a umidade do solo estiver seca ou úmida.

Pré-requisitos:
- ESP32, ESP8266 ou Raspberry Pi Pico W x 1.
- Sensor de Umidade do Solo Capacitivo (HW-390) x 1.
- Planta com vaso x 1.
- Cabos Jumper.
Nota: no ESP32, ADC2 (GPIO04, GPIO02, GPIO15) é instável quando Wi-Fi está sendo usado.
Introdução rápida ao Sensor de Umidade do Solo Capacitivo
Sensores de umidade do solo capacitivos medem a resistência elétrica entre duas sondas. A resistência muda dependendo da quantidade de água no solo. O sensor é conectado a um microcontrolador (MCU), que mede a capacitância entre as sondas. O circuito HW-390 converte a medição de capacitância para um sinal de tensão (ADC), que é então enviado para o MCU. O MCU pode usar este sinal para exibir o nível de umidade do solo ou para controlar outros dispositivos.
Nota: Fertilizantes e corrosão podem reduzir a precisão do sensor ao longo do tempo.
Fiação do Sensor de Umidade do Solo Capacitivo

| MCU | Pino GPIO |
|---|---|
| ESP32 | 34 (Analog ADC1_CH6) |
| ESP8266 | A0 |
| Pico W | GP26 (ADC0) |
Vamos verificar se o sensor está conectado corretamente e funcionando.
#if defined(ESP8266)
const int adcPin = A0;
#elif defined(ESP32)
const int adcPin = 34;
#elif defined(ARDUINO_ARCH_RP2040)
const int adcPin = 26;
#endif
void setup() {
Serial.begin(9600);
pinMode(adcPin, INPUT);
}
void loop() {
Serial.println(analogRead(adcPin));
delay(1000);
}

Vamos converter a entrada analógica para um valor de porcentagem.
#if defined(ESP8266)
const int adcPin = A0;
#elif defined(ESP32)
const int adcPin = 34;
#elif defined(ARDUINO_ARCH_RP2040)
const int adcPin = 26;
#endif
const int DRY = 720; // TODO: Este é o valor quando o solo está seco. Ajuste de acordo com seu caso de uso
const int WET = 560; // TODO: Este é o valor quando o solo está úmido. Ajuste de acordo com seu caso de uso
void setup() {
Serial.begin(9600);
pinMode(adcPin, INPUT);
}
void loop() {
int sensorVal = analogRead(adcPin);
int percentage = map(sensorVal, WET, DRY, 100, 0);
Serial.printf("Valor do sensor: %d porcentagem: %d%%\r\n", sensorVal, percentage);
delay(1000);
}

Passo 1: Conectar ao Sinric Pro
Passo 1.1: Criando um tipo de dispositivo personalizado para Sensor de Umidade do Solo Capacitivo.
Sinric Pro não tem um tipo de dispositivo integrado para Sensor de Umidade do Solo Capacitivo, então vamos criar um tipo de dispositivo personalizado para Sensor de Umidade do Solo Capacitivo usando o recurso Device Template para ver.
-
Solo está Úmido ou Seco
-
Nível de umidade.
Nota: Você pode usar o recurso de importação de template de dispositivo mencionado abaixo para pular a criação do template completo.
-
Faça login na sua conta Sinric Pro e vá para Device Templates
-
Clique em Add Device Template. Digite nome e descrição como Capacitive Soil Moisture Sensor e selecione Capacitive Soil Moisture Sensor como tipo de dispositivo

- Clique em Capabilities.
Aqui devemos selecionar as características do nosso Sensor de Umidade do Solo. Queremos saber se o Solo está Úmido ou Seco e o Nível de umidade. Então vamos arrastar uma capacidade Range, Mode e Push Notification.

-
O que é capacidade Range?
A capacidade Range pode ser usada para representar um número. ex: velocidade atual de um liquidificador.
-
O que é capacidade Mode?
A capacidade Mode pode ser usada para representar um valor de uma lista de valores predefinidos. ex: modo de ciclo de lavagem atual de uma máquina de lavar.
-
O que é capacidade Push Notification?
A capacidade Notification fornece a habilidade de enviar uma mensagem de notificação push do código.
Clique no botão Configure e configure as duas capacidades como abaixo.

Clique em Save para salvar.

Clique em Save para salvar o template.

Agora você pode ver o template que acabamos de criar.
Importar um template existente?
Se você está com preguiça de configurar todos os valores dos Modos e Range, você pode usar o recurso de importação.

Cole este Template:
{
"name": "Capacitive Soil Moisture Sensor",
"description": "Capacitive Soil Moisture Sensor",
"deviceTypeId": "6522320f2b090cc39f39fb32",
"capabilities": [
{
"id": "5ff0b41b994fd31b7d5e8961",
"mode": {
"instanceId": "modeInstance1",
"locale": "en-US",
"modeName": "Moisture",
"nonControllable": true,
"modeValues": [
"Wet",
"Dry"
]
}
},
{
"id": "5ff0b45f994fd31b7d5e89c2",
"range": {
"instanceId": "rangeInstance1",
"locale": "en-US",
"rangeName": "Moisture Level",
"minimumValue": 1,
"maximumValue": 100,
"precision": 1,
"unitOfMeasure": "5ffbeefbfaa11451974c6bbd",
"presets": [],
"nonControllable": true
}
},
{
"id": "62a707bd9e2f39090569e2d3"
}
]
}
-
Faça login na sua conta Sinric Pro, vá ao menu Dispositivos à esquerda e clique no botão Adicionar Dispositivo (no canto superior esquerdo).
-
Digite o nome do dispositivo Jardim, descrição Meu Jardim e selecione o tipo de dispositivo como Capacitive Soil Moisture Sensor.

-
Clique na aba Outros e Clique em Salvar
-
A próxima tela mostrará as credenciais necessárias para conectar o dispositivo que você acabou de criar.

-
Copie o ID do Dispositivo, Chave do App e Segredo do App Mantenha esses valores seguros. NÃO OS COMPARTILHE EM FÓRUNS PÚBLICOS!
-
Clique em Code Generator para Gerar o código. Clique em Download para baixar o código.

Passo 2: Conectar ao Sinric Pro
Passo 2.1 Instalar a Biblioteca Sinric Pro

2.2 Código Completo
CapacitiveSoilMoistureSensor.h
#ifndef _CAPACITIVESOILMOISTURESENSOR_H_
#define _CAPACITIVESOILMOISTURESENSOR_H_
#include <SinricProDevice.h>
#include <Capabilities/ModeController.h>
#include <Capabilities/RangeController.h>
#include <Capabilities/PushNotification.h>
class CapacitiveSoilMoistureSensor
: public SinricProDevice
, public ModeController<CapacitiveSoilMoistureSensor>
, public RangeController<CapacitiveSoilMoistureSensor>
, public PushNotification<CapacitiveSoilMoistureSensor> {
friend class ModeController<CapacitiveSoilMoistureSensor>;
friend class RangeController<CapacitiveSoilMoistureSensor>;
friend class PushNotification<CapacitiveSoilMoistureSensor>;
public:
CapacitiveSoilMoistureSensor(const String &deviceId) : SinricProDevice(deviceId, "CapacitiveSoilMoistureSensor") {};
};
#endif
sinricpro-capacitive-soil-moisture-sensor.ino
// #define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <WiFi.h>
#endif
#include <SinricPro.h>
#include "CapacitiveSoilMoistureSensor.h"
// Grab it from https://portal.sinric.pro.
#define APP_KEY "" //Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET "" //Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define DEVICE_ID "" //Should look like "6534xxxxxxxc08c6ea1b"
#define SSID "" // Your WiFi SSID
#define PASS "" // Your WiFi Password
#define BAUD_RATE 115200 // Change baudrate to your need (used for serial monitor)
#define EVENT_WAIT_TIME 60000 // send event every 60 seconds
#if defined(ESP8266)
const int adcPin = A0;
#elif defined(ESP32)
const int adcPin = 34;
#elif defined(ARDUINO_ARCH_RP2040)
const int adcPin = 26;
#endif
const int VERY_DRY = 720; // TODO: This is when soil is dry. Adjust according to your sensor
const int VERY_WET = 560; // TODO: This is when soil is wet. Adjust according to your sensor
const int NEITHER_DRY_OR_WET = 620; // TODO: This is when soil is neither wet or dry. Adjust according to your sensor
const int DRY_PUSH_NOTIFICATION_THRESHHOLD = 700; // TODO: This is when to send a push notification to the mobile phone. Adjust according to your sensor
const int UNPLUGGED = 735; // This is the value sensor produce when it's not in the ground.
int lastSoilMoisture = 0;
String lastSoilMoistureStr = "";
CapacitiveSoilMoistureSensor &capacitiveSoilMoistureSensor = SinricPro[DEVICE_ID];
void updateSoilState(String mode) {
capacitiveSoilMoistureSensor.sendModeEvent("modeInstance1", mode, "PHYSICAL_INTERACTION");
}
void updateMoistureLevel(int value) {
capacitiveSoilMoistureSensor.sendRangeValueEvent("rangeInstance1", value);
}
void sendPushNotification(String message) {
capacitiveSoilMoistureSensor.sendPushNotification(message);
}
void handleCapacitiveSoilMoistureSensor() {
if (SinricPro.isConnected() == false) {
return;
}
static unsigned long last_millis;
unsigned long current_millis = millis();
if (last_millis && current_millis - last_millis < EVENT_WAIT_TIME) return;
last_millis = current_millis;
int soilMoisture = analogRead(adcPin);
int percentage = map(soilMoisture, VERY_WET, VERY_DRY, 100, 0);
percentage = constrain(percentage, 1, 100);
Serial.printf("Soil Moisture: %d. as a percentage: %d%%\r\n", soilMoisture, percentage);
if (isnan(soilMoisture)) { // reading failed...
Serial.printf("Capacitive Soil Moisture Sensor reading failed!\r\n"); // print error message
return; // try again next time
}
if (soilMoisture == lastSoilMoisture) {
Serial.printf("Soil moisture did not changed. do nothing...!\r\n");
return;
}
// Determine Wet or Dry.
String soilMoistureStr = "";
if(soilMoisture > NEITHER_DRY_OR_WET) {
soilMoistureStr = "Dry"; // NOTE: must be Wet, Dry. This is from modes list in template.
} else {
soilMoistureStr = "Wet";
}
// Update Moisture label
if(lastSoilMoistureStr != soilMoistureStr) {
lastSoilMoistureStr = soilMoistureStr;
updateSoilState(soilMoistureStr);
}
delay(500);
// Update Moisture level label
updateMoistureLevel(percentage);
// Send push notifications
if(soilMoisture > DRY_PUSH_NOTIFICATION_THRESHHOLD) {
sendPushNotification("Plants are too dry. Time to water the plants!");
}
if(soilMoisture > UNPLUGGED) {
sendPushNotification("Sensor seems to be unhooked. Please check!");
}
lastSoilMoisture = soilMoisture; // save to compare next time.
}
/*********
* Setups *
*********/
void setupSinricPro() {
SinricPro.onConnected([]{ Serial.printf("[SinricPro]: Connected\r\n"); });
SinricPro.onDisconnected([]{ Serial.printf("[SinricPro]: Disconnected\r\n"); });
SinricPro.begin(APP_KEY, APP_SECRET);
};
void setupSensor() {
pinMode(adcPin, INPUT);
}
void setupWiFi() {
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.setAutoReconnect(true);
#elif defined(ESP32)
WiFi.setSleep(false);
WiFi.setAutoReconnect(true);
#endif
WiFi.begin(SSID, PASS);
Serial.printf("[WiFi]: Connecting to %s", SSID);
while (WiFi.status() != WL_CONNECTED) {
Serial.printf(".");
delay(250);
}
Serial.printf("connected\r\n");
}
void setup() {
Serial.begin(BAUD_RATE);
setupSensor();
setupWiFi();
setupSinricPro();
}
/********
* Loop *
********/
void loop() {
SinricPro.handle();
handleCapacitiveSoilMoistureSensor();
}
Agora você deve conseguir ver a umidade do solo via Alexa, App Sinric Pro
Alexa, Qual é a umidade (nome do modo) no jardim(nome do dispositivo)
Alexa, Qual é o nível de umidade(nome do range) no jardim(nome do dispositivo)


Solução de Problemas
-
Google Home ou SmartThings não são suportados.
-
Consulte nossa página de Solução de Problemas para mais detalhes.
Este documento é código aberto. Viu um erro de digitação? Por favor, crie uma issue