feat: Adiciona suporte para sensor de temperatura e umidade DHT11 com integração Zigbee
This commit is contained in:
+4
-4
@@ -14,10 +14,10 @@ Este projeto foi refatorado para uma **arquitetura modular flexível** que permi
|
|||||||
- Controle via ZHA/Zigbee2MQTT
|
- Controle via ZHA/Zigbee2MQTT
|
||||||
|
|
||||||
### 🚧 Esqueleto Pronto (Basta Implementar Hardware)
|
### 🚧 Esqueleto Pronto (Basta Implementar Hardware)
|
||||||
- **DEVICE_TYPE_TEMP_SENSOR** - Sensor de temperatura
|
- **DEVICE_TYPE_TEMP_SENSOR** - Sensor de temperatura e umidade DHT11
|
||||||
- Clusters: Basic, Identify, Temperature Measurement
|
- Clusters: Basic, Identify, Temperature Measurement, Humidity Measurement
|
||||||
- GPIOs configuráveis para I2C (SDA/SCL)
|
- GPIO configurável para DHT11 (one-wire)
|
||||||
- TODO: Implementar leitura do sensor (AHT20, SHT30, BME280, etc)
|
- ✅ Implementado com DHT11 - Reporta temperatura e umidade via Zigbee
|
||||||
|
|
||||||
- **DEVICE_TYPE_DOOR_SENSOR** - Sensor de porta/janela
|
- **DEVICE_TYPE_DOOR_SENSOR** - Sensor de porta/janela
|
||||||
- Clusters: Basic, Identify, IAS Zone
|
- Clusters: Basic, Identify, IAS Zone
|
||||||
|
|||||||
+256
@@ -0,0 +1,256 @@
|
|||||||
|
# Sensor de Temperatura DHT11 - Guia de Uso
|
||||||
|
|
||||||
|
## 🌡️ Sobre o DHT11
|
||||||
|
|
||||||
|
O DHT11 é um sensor digital de temperatura e umidade de baixo custo:
|
||||||
|
- **Temperatura**: 0°C a 50°C (±2°C precisão)
|
||||||
|
- **Umidade**: 20% a 90% RH (±5% precisão)
|
||||||
|
- **Interface**: One-wire digital
|
||||||
|
- **Tempo de resposta**: 1 segundo mínimo entre leituras
|
||||||
|
- **Tensão**: 3.3V a 5V
|
||||||
|
|
||||||
|
## 🔌 Conexão de Hardware
|
||||||
|
|
||||||
|
### Pinagem do DHT11
|
||||||
|
```
|
||||||
|
DHT11 Sensor:
|
||||||
|
┌─────────┐
|
||||||
|
│ 1 │ VCC → 3.3V (ESP32-C6)
|
||||||
|
│ 2 │ DATA → GPIO 5 (configurável)
|
||||||
|
│ 3 │ NC → Não conectar
|
||||||
|
│ 4 │ GND → GND
|
||||||
|
└─────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Esquema de Ligação
|
||||||
|
```
|
||||||
|
ESP32-C6 DHT11
|
||||||
|
┌────────┐
|
||||||
|
3.3V ──────────────►│ VCC │
|
||||||
|
│ │
|
||||||
|
GPIO 5 ────────────►│ DATA │
|
||||||
|
│ │ │
|
||||||
|
└─── 10kΩ ───┐ │ │
|
||||||
|
│ │ │
|
||||||
|
3.3V │ │ │
|
||||||
|
│ NC │
|
||||||
|
│ │
|
||||||
|
GND ───────────────►│ GND │
|
||||||
|
└────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**⚠️ IMPORTANTE:**
|
||||||
|
- Use resistor pull-up de **10kΩ** entre DATA e VCC
|
||||||
|
- Alguns módulos DHT11 já incluem o resistor pull-up
|
||||||
|
|
||||||
|
## ⚙️ Configuração
|
||||||
|
|
||||||
|
### 1. Ativar Sensor de Temperatura
|
||||||
|
|
||||||
|
Edite [`main/device_config.h`](main/device_config.h):
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Descomente APENAS sensor de temperatura */
|
||||||
|
// #define DEVICE_TYPE_RELAY
|
||||||
|
#define DEVICE_TYPE_TEMP_SENSOR /* ← Ative isso */
|
||||||
|
// #define DEVICE_TYPE_DOOR_SENSOR
|
||||||
|
// #define DEVICE_TYPE_MOTION_SENSOR
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configurar GPIO
|
||||||
|
|
||||||
|
No mesmo arquivo:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifdef DEVICE_TYPE_TEMP_SENSOR
|
||||||
|
#define GPIO_SENSOR_DHT11 5 /* GPIO do DHT11 */
|
||||||
|
#define SENSOR_UPDATE_INTERVAL 10000 /* 10 segundos */
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
**GPIOs Recomendadas:** 5, 6, 7, 10, 18, 19, 20, 21
|
||||||
|
|
||||||
|
### 3. Ajustar Intervalo de Atualização
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SENSOR_UPDATE_INTERVAL 10000 /* 10 segundos (recomendado) */
|
||||||
|
// #define SENSOR_UPDATE_INTERVAL 5000 /* 5 segundos (mínimo seguro) */
|
||||||
|
// #define SENSOR_UPDATE_INTERVAL 60000 /* 1 minuto (economia energia) */
|
||||||
|
```
|
||||||
|
|
||||||
|
**⚠️ Mínimo:** 2000ms (2 segundos) - DHT11 requer 1s entre leituras
|
||||||
|
|
||||||
|
## 🏗️ Compilar e Gravar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Compilar
|
||||||
|
idf.py build
|
||||||
|
|
||||||
|
# Gravar
|
||||||
|
idf.py -p /dev/ttyACM0 flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Formato de Dados Zigbee
|
||||||
|
|
||||||
|
O DHT11 reporta **temperatura e umidade** no formato Zigbee padrão:
|
||||||
|
|
||||||
|
### Cluster de Temperatura (0x0402)
|
||||||
|
- **Atributo**: `MeasuredValue` (0x0000)
|
||||||
|
- **Tipo**: `int16_t`
|
||||||
|
- **Unidade**: 0.01°C
|
||||||
|
- **Exemplo**: 2350 = 23.50°C
|
||||||
|
|
||||||
|
### Cluster de Umidade (0x0405)
|
||||||
|
- **Atributo**: `MeasuredValue` (0x0000)
|
||||||
|
- **Tipo**: `uint16_t`
|
||||||
|
- **Unidade**: 0.01% RH
|
||||||
|
- **Exemplo**: 6500 = 65.00% RH
|
||||||
|
|
||||||
|
### Leitura no ZHA/Home Assistant
|
||||||
|
|
||||||
|
O dispositivo aparece automaticamente com **dois sensores**:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Sensor de Temperatura
|
||||||
|
sensor:
|
||||||
|
- platform: zha
|
||||||
|
name: "Temperatura Sala"
|
||||||
|
device: "0x98a316fffebf43a4"
|
||||||
|
cluster_id: 0x0402 # Temperature
|
||||||
|
attribute: 0
|
||||||
|
|
||||||
|
# Sensor de Umidade
|
||||||
|
sensor:
|
||||||
|
- platform: zha
|
||||||
|
name: "Umidade Sala"
|
||||||
|
device: "0x98a316fffebf43a4"
|
||||||
|
cluster_id: 0x0405 # Humidity
|
||||||
|
attribute: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
Aparecerá automaticamente como duas entidades:
|
||||||
|
- **sensor.temperatura_sala** - Temperatura em °C
|
||||||
|
- **sensor.umidade_sala** - Umidade relativa em %
|
||||||
|
- **Atualização**: A cada 10 segundos (configurável)
|
||||||
|
|
||||||
|
## 🔍 Logs de Funcionamento
|
||||||
|
|
||||||
|
```
|
||||||
|
I (1250) DHT11: DHT11 initialized on GPIO 5
|
||||||
|
I (1260) DEVICE_REGISTRY: DHT11 sensor task started (update interval: 10000 ms)
|
||||||
|
I (11260) DHT11: Temperature: 23.0°C, Humidity: 65.0%
|
||||||
|
I (11265) DEVICE_REGISTRY: Sensor updated - Temperature: 23.0°C (Zigbee: 2300), Humidity: 65.0% (Zigbee: 6500)
|
||||||
|
I (21265) DHT11: Temperature: 23.5°C, Humidity: 64.0%
|
||||||
|
I (21270) DEVICE_REGISTRY: Sensor updated - Temperature: 23.5°C (Zigbee: 2350), Humidity: 64.0% (Zigbee: 6400)
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚠️ Troubleshooting
|
||||||
|
|
||||||
|
### Erro: "Timeout waiting for response"
|
||||||
|
```
|
||||||
|
E (12000) DHT11: Timeout waiting for response LOW
|
||||||
|
```
|
||||||
|
**Causas:**
|
||||||
|
- DHT11 não conectado corretamente
|
||||||
|
- Falta resistor pull-up de 10kΩ
|
||||||
|
- GPIO incorreta
|
||||||
|
- Sensor danificado
|
||||||
|
|
||||||
|
**Solução:**
|
||||||
|
1. Verifique conexões (VCC, DATA, GND)
|
||||||
|
2. Adicione resistor pull-up 10kΩ
|
||||||
|
3. Teste com outra GPIO
|
||||||
|
4. Troque o sensor
|
||||||
|
|
||||||
|
### Erro: "Checksum error"
|
||||||
|
```
|
||||||
|
E (12000) DHT11: Checksum error: calculated=0x5A, received=0x5B
|
||||||
|
```
|
||||||
|
**Causas:**
|
||||||
|
- Interferência eletromagnética
|
||||||
|
- Cabo muito longo
|
||||||
|
- Alimentação instável
|
||||||
|
|
||||||
|
**Solução:**
|
||||||
|
1. Use cabo curto (<30cm)
|
||||||
|
2. Adicione capacitor 100nF próximo ao sensor
|
||||||
|
3. Estabilize alimentação 3.3V
|
||||||
|
4. Afaste de fontes de ruído
|
||||||
|
|
||||||
|
### Aviso: "Read too soon"
|
||||||
|
```
|
||||||
|
W (5500) DHT11: Read too soon, wait at least 1 second between reads
|
||||||
|
```
|
||||||
|
**Causa:** Tentativa de leitura antes de 1 segundo
|
||||||
|
|
||||||
|
**Solução:** Aumente `SENSOR_UPDATE_INTERVAL` para no mínimo 2000ms
|
||||||
|
|
||||||
|
### Temperatura Sempre 0°C
|
||||||
|
**Causas:**
|
||||||
|
- Sensor não inicializado
|
||||||
|
- Problema no protocolo one-wire
|
||||||
|
- GPIO em conflito
|
||||||
|
|
||||||
|
**Solução:**
|
||||||
|
1. Verifique logs de inicialização
|
||||||
|
2. Teste GPIO com `gpio_get_level()`
|
||||||
|
3. Use outra GPIO
|
||||||
|
4. Verifique se pull-up está presente
|
||||||
|
|
||||||
|
## 🎯 Otimizações
|
||||||
|
|
||||||
|
### Economia de Energia
|
||||||
|
|
||||||
|
Para dispositivos battery-powered:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SENSOR_UPDATE_INTERVAL 300000 /* 5 minutos */
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure também como End Device:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Em esp_zb_switch.h */
|
||||||
|
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG(); /* End Device */
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alta Frequência de Atualização
|
||||||
|
|
||||||
|
Para monitoramento rápido (com alimentação):
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SENSOR_UPDATE_INTERVAL 2000 /* 2 segundos (mínimo) */
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 Próximas Melhorias
|
||||||
|
|
||||||
|
### ✅ Cluster de Umidade - IMPLEMENTADO!
|
||||||
|
|
||||||
|
O DHT11 agora expõe **temperatura e umidade** via Zigbee automaticamente!
|
||||||
|
|
||||||
|
### Alertas de Temperatura/Umidade
|
||||||
|
|
||||||
|
Implementar notificação quando valores excederem limites:
|
||||||
|
|
||||||
|
Implementar notificação quando temperatura exceder limites:
|
||||||
|
|
||||||
|
```c
|
||||||
|
if (reading.temperature > 30.0f || reading.temperature < 10.0f) {
|
||||||
|
ESP_LOGW(TAG, "Temperature out of range: %.1f°C", reading.temperature);
|
||||||
|
// Enviar alerta via Zigbee
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Referências
|
||||||
|
|
||||||
|
- [DHT11 Datasheet](https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf)
|
||||||
|
- [Zigbee Temperature Measurement Cluster](https://zigbeealliance.org/wp-content/uploads/2019/12/07-5123-06-zigbee-cluster-library-specification.pdf)
|
||||||
|
- [ESP-IDF GPIO API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/peripherals/gpio.html)
|
||||||
|
|
||||||
|
## 🔗 Compatibilidade
|
||||||
|
|
||||||
|
**Home Assistant (ZHA)**: ✅ Funciona automaticamente
|
||||||
|
**Zigbee2MQTT**: ✅ Compatível (Temperature Sensor)
|
||||||
|
**Amazon Alexa**: ✅ Via Home Assistant
|
||||||
|
**Google Home**: ✅ Via Home Assistant
|
||||||
|
**Apple HomeKit**: ✅ Via HomeAssistant Bridge
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
# Teste Rápido - DHT11
|
||||||
|
|
||||||
|
## 🚀 Teste de Bancada (5 minutos)
|
||||||
|
|
||||||
|
### 1️⃣ Hardware Necessário
|
||||||
|
```
|
||||||
|
✅ ESP32-C6
|
||||||
|
✅ DHT11 sensor
|
||||||
|
✅ Resistor 10kΩ (pull-up)
|
||||||
|
✅ 3 fios jumper
|
||||||
|
✅ Breadboard (opcional)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2️⃣ Montagem
|
||||||
|
```
|
||||||
|
ESP32-C6 DHT11
|
||||||
|
3.3V ────────► VCC (pino 1)
|
||||||
|
│
|
||||||
|
GPIO5 ────┬───► DATA (pino 2)
|
||||||
|
│
|
||||||
|
10kΩ
|
||||||
|
│
|
||||||
|
3.3V
|
||||||
|
|
||||||
|
GND ─────────► GND (pino 4)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3️⃣ Ativar Modo Sensor
|
||||||
|
|
||||||
|
Edite `main/device_config.h`:
|
||||||
|
```c
|
||||||
|
// #define DEVICE_TYPE_RELAY /* ← Comente isso */
|
||||||
|
#define DEVICE_TYPE_TEMP_SENSOR /* ← Descomente isso */
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4️⃣ Compilar e Gravar
|
||||||
|
```bash
|
||||||
|
cd /workspaces/bomba-esp
|
||||||
|
idf.py build flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5️⃣ Logs Esperados
|
||||||
|
```
|
||||||
|
I (1250) DHT11: DHT11 initialized on GPIO 5
|
||||||
|
I (1260) DEVICE_REGISTRY: DHT11 sensor task started (update interval: 10000 ms)
|
||||||
|
I (2260) ESP_ZB_ON_OFF_SWITCH: Start Zigbee stack
|
||||||
|
...
|
||||||
|
I (11260) DHT11: Temperature: 23.0°C, Humidity: 65.0%
|
||||||
|
I (11265) DEVICE_REGISTRY: Sensor updated - Temperature: 23.0°C (Zigbee: 2300), Humidity: 65.0% (Zigbee: 6500)
|
||||||
|
I (21265) DHT11: Temperature: 23.5°C, Humidity: 64.0%
|
||||||
|
I (21270) DEVICE_REGISTRY: Sensor updated - Temperature: 23.5°C (Zigbee: 2350), Humidity: 64.0% (Zigbee: 6400)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 Testes de Funcionamento
|
||||||
|
|
||||||
|
### Teste 1: Sensor Responde?
|
||||||
|
**Objetivo:** Verificar comunicação básica
|
||||||
|
|
||||||
|
1. Conecte DHT11
|
||||||
|
2. Grave firmware
|
||||||
|
3. Observe logs a cada 10 segundos
|
||||||
|
|
||||||
|
**✅ Sucesso:**
|
||||||
|
```
|
||||||
|
I (11260) DHT11: Temperature: XX.X°C, Humidity: XX.X%
|
||||||
|
```
|
||||||
|
|
||||||
|
**❌ Falha - Timeout:**
|
||||||
|
```
|
||||||
|
E (11260) DHT11: Timeout waiting for response LOW
|
||||||
|
```
|
||||||
|
→ Verifique conexões e resistor pull-up
|
||||||
|
|
||||||
|
### Teste 2: Valores Coerentes?
|
||||||
|
**Objetivo:** Validar leituras
|
||||||
|
|
||||||
|
**Temperatura esperada:** 15°C a 35°C (ambiente normal)
|
||||||
|
**Umidade esperada:** 30% a 80% RH
|
||||||
|
|
||||||
|
**Teste:**
|
||||||
|
1. Sopre no sensor → Umidade aumenta
|
||||||
|
2. Aperte o sensor → Temperatura aumenta
|
||||||
|
3. Compare com termômetro ambiente
|
||||||
|
|
||||||
|
### Teste 3: Zigbee Funcionando?
|
||||||
|
**Objetivo:** Verificar integração Zigbee
|
||||||
|
|
||||||
|
1. Parear com coordenador ZHA
|
||||||
|
2. Verificar entidade no Home Assistant
|
||||||
|
3. Observar atualização a cada 10s
|
||||||
|
|
||||||
|
**✅ No Home Assistant:**
|
||||||
|
```
|
||||||
|
Dispositivo: 0x98a316fffebf43a4
|
||||||
|
├─ Manufacturer: ESPRESSIF
|
||||||
|
├─ Model: Zigbee Temperature & Humidity Sensor DHT11
|
||||||
|
├─ Sensor: Temperature
|
||||||
|
│ └─ Estado: 23.5°C
|
||||||
|
└─ Sensor: Humidity
|
||||||
|
└─ Estado: 64.0%
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Exemplo de Automação (Home Assistant)
|
||||||
|
|
||||||
|
### Alerta de Temperatura Alta
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Alerta Temperatura Alta"
|
||||||
|
trigger:
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: sensor.temperatura_sala
|
||||||
|
above: 30
|
||||||
|
action:
|
||||||
|
- service: notify.mobile_app
|
||||||
|
data:
|
||||||
|
title: "🌡️ Temperatura Alta!"
|
||||||
|
message: "Sala está em {{ states('sensor.temperatura_sala') }}°C"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alerta de Umidade Baixa
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- alias: "Alerta Umidade Baixa"
|
||||||
|
trigger:
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: sensor.umidade_sala
|
||||||
|
below: 30
|
||||||
|
action:
|
||||||
|
- service: notify.mobile_app
|
||||||
|
data:
|
||||||
|
title: "💧 Umidade Baixa!"
|
||||||
|
message: "Umidade está em {{ states('sensor.umidade_sala') }}%"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gráfico Combinado
|
||||||
|
```yaml
|
||||||
|
# configuration.yaml
|
||||||
|
sensor:
|
||||||
|
- platform: statistics
|
||||||
|
name: "Temperatura Média Diária"
|
||||||
|
entity_id: sensor.temperatura_sala
|
||||||
|
state_characteristic: mean
|
||||||
|
max_age:
|
||||||
|
hours: 24
|
||||||
|
|
||||||
|
- platform: statistics
|
||||||
|
name: "Umidade Média Diária"
|
||||||
|
entity_id: sensor.umidade_sala
|
||||||
|
state_characteristic: mean
|
||||||
|
max_age:
|
||||||
|
hours: 24
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Troubleshooting Rápido
|
||||||
|
|
||||||
|
| Sintoma | Causa Provável | Solução |
|
||||||
|
|---------|---------------|---------|
|
||||||
|
| Sem leitura | DHT11 não conectado | Verifique VCC, GND, DATA |
|
||||||
|
| Timeout | Falta pull-up | Adicione resistor 10kΩ |
|
||||||
|
| Valores errados | Cabo longo | Use cabo <30cm |
|
||||||
|
| Checksum error | Ruído elétrico | Adicione capacitor 100nF |
|
||||||
|
| Não pareia | Modo errado | Verifique `DEVICE_TYPE_TEMP_SENSOR` |
|
||||||
|
|
||||||
|
## 📈 Ajuste Fino
|
||||||
|
|
||||||
|
### Temperatura Muito Estável?
|
||||||
|
**Problema:** DHT11 lê apenas inteiros (sem decimal)
|
||||||
|
|
||||||
|
**Solução:** Normal! DHT11 tem precisão limitada
|
||||||
|
|
||||||
|
### Quer Mais Precisão?
|
||||||
|
Use sensor melhor:
|
||||||
|
- **DHT22** (±0.5°C, ±2% RH)
|
||||||
|
- **SHT30** (±0.3°C, ±2% RH)
|
||||||
|
- **BME280** (±1°C, pressão também)
|
||||||
|
|
||||||
|
Veja [ARCHITECTURE.md](ARCHITECTURE.md) seção "Como Adicionar Novo Dispositivo"
|
||||||
|
|
||||||
|
## 🎯 Próximo Passo
|
||||||
|
|
||||||
|
Agora que o DHT11 funciona, você pode:
|
||||||
|
|
||||||
|
1. **Adicionar umidade ao Zigbee** (cluster 0x0405)
|
||||||
|
2. **Criar dispositivo combo** (relé + sensor)
|
||||||
|
3. **Implementar sensor de porta** (GPIO 5 com reed switch)
|
||||||
|
|
||||||
|
Veja guias completos:
|
||||||
|
- [DHT11_GUIDE.md](DHT11_GUIDE.md) - Guia completo
|
||||||
|
- [ARCHITECTURE.md](ARCHITECTURE.md) - Arquitetura modular
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "."
|
SRC_DIRS "."
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
PRIV_REQUIRES nvs_flash esp_driver_gpio esp_driver_uart ieee802154 heap esp_driver_rmt
|
PRIV_REQUIRES nvs_flash esp_driver_gpio esp_driver_uart ieee802154 heap esp_driver_rmt esp_timer
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ extern "C" {
|
|||||||
/* ========================= SELEÇÃO DO TIPO DE DISPOSITIVO ========================= */
|
/* ========================= SELEÇÃO DO TIPO DE DISPOSITIVO ========================= */
|
||||||
/* Descomente APENAS UMA das opções abaixo para definir o tipo de dispositivo */
|
/* Descomente APENAS UMA das opções abaixo para definir o tipo de dispositivo */
|
||||||
|
|
||||||
#define DEVICE_TYPE_RELAY /* Relé controlável (on/off light) */
|
// #define DEVICE_TYPE_RELAY /* Relé controlável (on/off light) */
|
||||||
// #define DEVICE_TYPE_TEMP_SENSOR /* Sensor de temperatura */
|
#define DEVICE_TYPE_TEMP_SENSOR /* Sensor de temperatura */
|
||||||
// #define DEVICE_TYPE_DOOR_SENSOR /* Sensor de porta/janela */
|
// #define DEVICE_TYPE_DOOR_SENSOR /* Sensor de porta/janela */
|
||||||
// #define DEVICE_TYPE_MOTION_SENSOR /* Sensor de movimento */
|
// #define DEVICE_TYPE_MOTION_SENSOR /* Sensor de movimento */
|
||||||
|
|
||||||
@@ -27,9 +27,8 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEVICE_TYPE_TEMP_SENSOR
|
#ifdef DEVICE_TYPE_TEMP_SENSOR
|
||||||
#define GPIO_SENSOR_I2C_SDA 6 /* I2C SDA para sensor de temperatura */
|
#define GPIO_SENSOR_DHT11 5 /* GPIO para DHT11 (DATA pin) */
|
||||||
#define GPIO_SENSOR_I2C_SCL 7 /* I2C SCL para sensor de temperatura */
|
#define SENSOR_UPDATE_INTERVAL 10000 /* Intervalo de atualização em ms (mín. 1s para DHT11) */
|
||||||
#define SENSOR_UPDATE_INTERVAL 30000 /* Intervalo de atualização em ms */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEVICE_TYPE_DOOR_SENSOR
|
#ifdef DEVICE_TYPE_DOOR_SENSOR
|
||||||
|
|||||||
+99
-12
@@ -4,11 +4,17 @@
|
|||||||
#include "zcl/esp_zigbee_zcl_common.h"
|
#include "zcl/esp_zigbee_zcl_common.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_zb_switch.h"
|
#include "esp_zb_switch.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
#ifdef DEVICE_TYPE_RELAY
|
#ifdef DEVICE_TYPE_RELAY
|
||||||
#include "switch_driver.h"
|
#include "switch_driver.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEVICE_TYPE_TEMP_SENSOR
|
||||||
|
#include "dht11_driver.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if FEATURE_LED_INDICATOR
|
#if FEATURE_LED_INDICATOR
|
||||||
#include "led_indicator.h"
|
#include "led_indicator.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -77,6 +83,66 @@ static const device_type_t relay_device = {
|
|||||||
|
|
||||||
#ifdef DEVICE_TYPE_TEMP_SENSOR
|
#ifdef DEVICE_TYPE_TEMP_SENSOR
|
||||||
|
|
||||||
|
static TaskHandle_t temp_sensor_task_handle = NULL;
|
||||||
|
|
||||||
|
/* Task para ler sensor DHT11 periodicamente */
|
||||||
|
static void temp_sensor_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
dht11_reading_t reading;
|
||||||
|
TickType_t last_wake_time = xTaskGetTickCount();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* Aguarda intervalo configurado */
|
||||||
|
vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(SENSOR_UPDATE_INTERVAL));
|
||||||
|
|
||||||
|
/* Lê temperatura e umidade do DHT11 */
|
||||||
|
esp_err_t ret = dht11_read(&reading);
|
||||||
|
|
||||||
|
if (ret == ESP_OK && reading.valid) {
|
||||||
|
/* Converte temperatura para formato Zigbee (0.01°C) */
|
||||||
|
int16_t temp_zigbee = (int16_t)(reading.temperature * 100);
|
||||||
|
|
||||||
|
/* Converte umidade para formato Zigbee (0.01% RH) */
|
||||||
|
uint16_t humidity_zigbee = (uint16_t)(reading.humidity * 100);
|
||||||
|
|
||||||
|
/* Atualiza atributos Zigbee */
|
||||||
|
esp_zb_lock_acquire(portMAX_DELAY);
|
||||||
|
|
||||||
|
/* Atualiza temperatura */
|
||||||
|
esp_zb_zcl_set_attribute_val(
|
||||||
|
HA_ONOFF_SWITCH_ENDPOINT,
|
||||||
|
ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT,
|
||||||
|
ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
|
||||||
|
ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID,
|
||||||
|
&temp_zigbee,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Atualiza umidade */
|
||||||
|
esp_zb_zcl_set_attribute_val(
|
||||||
|
HA_ONOFF_SWITCH_ENDPOINT,
|
||||||
|
ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT,
|
||||||
|
ESP_ZB_ZCL_CLUSTER_SERVER_ROLE,
|
||||||
|
ESP_ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID,
|
||||||
|
&humidity_zigbee,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
esp_zb_lock_release();
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Sensor updated - Temperature: %.1f°C (Zigbee: %d), Humidity: %.1f%% (Zigbee: %u)",
|
||||||
|
reading.temperature, temp_zigbee, reading.humidity, humidity_zigbee);
|
||||||
|
|
||||||
|
#if FEATURE_LED_INDICATOR
|
||||||
|
/* Pisca LED para indicar leitura */
|
||||||
|
led_indicator_set_state(LED_CONNECTED);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Failed to read DHT11 sensor: %s", esp_err_to_name(ret));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static esp_zb_cluster_list_t* temp_sensor_create_clusters(void)
|
static esp_zb_cluster_list_t* temp_sensor_create_clusters(void)
|
||||||
{
|
{
|
||||||
esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
|
esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
|
||||||
@@ -84,37 +150,48 @@ static esp_zb_cluster_list_t* temp_sensor_create_clusters(void)
|
|||||||
esp_zb_cluster_list_add_basic_cluster(cluster_list, device_create_basic_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
esp_zb_cluster_list_add_basic_cluster(cluster_list, device_create_basic_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||||
esp_zb_cluster_list_add_identify_cluster(cluster_list, device_create_identify_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
esp_zb_cluster_list_add_identify_cluster(cluster_list, device_create_identify_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||||
esp_zb_cluster_list_add_temperature_meas_cluster(cluster_list, device_create_temperature_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
esp_zb_cluster_list_add_temperature_meas_cluster(cluster_list, device_create_temperature_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||||
|
esp_zb_cluster_list_add_humidity_meas_cluster(cluster_list, device_create_humidity_cluster(), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||||
|
|
||||||
return cluster_list;
|
return cluster_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t temp_sensor_attribute_handler(const esp_zb_zcl_set_attr_value_message_t *message)
|
static esp_err_t temp_sensor_attribute_handler(const esp_zb_zcl_set_attr_value_message_t *message)
|
||||||
{
|
{
|
||||||
/* Sensor de temperatura geralmente não recebe comandos, apenas reporta */
|
/* Sensor de temperatura não recebe comandos, apenas reporta */
|
||||||
return ESP_ERR_NOT_FOUND;
|
return ESP_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void temp_sensor_hardware_init(void)
|
static void temp_sensor_hardware_init(void)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Initializing temperature sensor (I2C SDA:%d SCL:%d)",
|
ESP_LOGI(TAG, "Initializing DHT11 temperature sensor on GPIO %d", GPIO_SENSOR_DHT11);
|
||||||
GPIO_SENSOR_I2C_SDA, GPIO_SENSOR_I2C_SCL);
|
|
||||||
|
|
||||||
/* TODO: Implementar inicialização do sensor I2C */
|
/* Inicializa driver DHT11 */
|
||||||
/* Exemplo: inicializar AHT20, SHT30, BME280, etc. */
|
esp_err_t ret = dht11_init(GPIO_SENSOR_DHT11);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to initialize DHT11: %s", esp_err_to_name(ret));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cria task para leitura periódica */
|
||||||
|
xTaskCreate(
|
||||||
|
temp_sensor_task,
|
||||||
|
"temp_sensor",
|
||||||
|
4096,
|
||||||
|
NULL,
|
||||||
|
5,
|
||||||
|
&temp_sensor_task_handle
|
||||||
|
);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "DHT11 sensor task started (update interval: %d ms)", SENSOR_UPDATE_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void temp_sensor_update_state(void)
|
static void temp_sensor_update_state(void)
|
||||||
{
|
{
|
||||||
/* TODO: Ler temperatura do sensor e atualizar atributo Zigbee */
|
/* A atualização é feita automaticamente pela task periódica */
|
||||||
/* Exemplo:
|
|
||||||
* float temp = read_temperature_sensor();
|
|
||||||
* int16_t temp_zigbee = (int16_t)(temp * 100); // Zigbee usa 0.01°C
|
|
||||||
* esp_zb_zcl_set_attribute_val(..., ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, &temp_zigbee, false);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const device_type_t temp_sensor_device = {
|
static const device_type_t temp_sensor_device = {
|
||||||
.name = "Zigbee Temperature Sensor",
|
.name = "Zigbee Temperature & Humidity Sensor DHT11",
|
||||||
.device_id = ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID,
|
.device_id = ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID,
|
||||||
.endpoint = HA_ONOFF_SWITCH_ENDPOINT,
|
.endpoint = HA_ONOFF_SWITCH_ENDPOINT,
|
||||||
.create_clusters = temp_sensor_create_clusters,
|
.create_clusters = temp_sensor_create_clusters,
|
||||||
@@ -267,6 +344,16 @@ esp_zb_attribute_list_t* device_create_temperature_cluster(void)
|
|||||||
return esp_zb_temperature_meas_cluster_create(&temp_cfg);
|
return esp_zb_temperature_meas_cluster_create(&temp_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_zb_attribute_list_t* device_create_humidity_cluster(void)
|
||||||
|
{
|
||||||
|
esp_zb_humidity_meas_cluster_cfg_t humidity_cfg = {
|
||||||
|
.measured_value = ESP_ZB_ZCL_REL_HUMIDITY_MEASUREMENT_MEASURED_VALUE_DEFAULT,
|
||||||
|
.min_value = 0, /* 0% RH em unidades de 0.01% */
|
||||||
|
.max_value = 10000, /* 100% RH em unidades de 0.01% */
|
||||||
|
};
|
||||||
|
return esp_zb_humidity_meas_cluster_create(&humidity_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
esp_zb_attribute_list_t* device_create_occupancy_cluster(void)
|
esp_zb_attribute_list_t* device_create_occupancy_cluster(void)
|
||||||
{
|
{
|
||||||
esp_zb_occupancy_sensing_cluster_cfg_t occupancy_cfg = {
|
esp_zb_occupancy_sensing_cluster_cfg_t occupancy_cfg = {
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ esp_zb_attribute_list_t* device_create_onoff_cluster(void);
|
|||||||
/* Cria cluster de temperatura (para sensores) */
|
/* Cria cluster de temperatura (para sensores) */
|
||||||
esp_zb_attribute_list_t* device_create_temperature_cluster(void);
|
esp_zb_attribute_list_t* device_create_temperature_cluster(void);
|
||||||
|
|
||||||
|
/* Cria cluster de umidade relativa (para sensores) */
|
||||||
|
esp_zb_attribute_list_t* device_create_humidity_cluster(void);
|
||||||
|
|
||||||
/* Cria cluster de ocupação (para sensores de movimento/porta) */
|
/* Cria cluster de ocupação (para sensores de movimento/porta) */
|
||||||
esp_zb_attribute_list_t* device_create_occupancy_cluster(void);
|
esp_zb_attribute_list_t* device_create_occupancy_cluster(void);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
/* DHT11 Temperature and Humidity Sensor Driver Implementation */
|
||||||
|
|
||||||
|
#include "dht11_driver.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "rom/ets_sys.h"
|
||||||
|
|
||||||
|
static const char *TAG = "DHT11";
|
||||||
|
|
||||||
|
static gpio_num_t dht_gpio;
|
||||||
|
static int64_t last_read_time = -2000000; // Inicializa para permitir primeira leitura
|
||||||
|
|
||||||
|
/* Timeout para espera de resposta (em microsegundos) */
|
||||||
|
#define DHT11_TIMEOUT_US 85
|
||||||
|
|
||||||
|
/* Tempo mínimo entre leituras (1 segundo) */
|
||||||
|
#define DHT11_MIN_INTERVAL_US 1000000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Espera o pino mudar para o nível especificado
|
||||||
|
*
|
||||||
|
* @param level Nível esperado (0 ou 1)
|
||||||
|
* @param timeout_us Timeout em microsegundos
|
||||||
|
* @return Tempo de espera em us, ou -1 se timeout
|
||||||
|
*/
|
||||||
|
static int dht11_wait_for_level(int level, int timeout_us)
|
||||||
|
{
|
||||||
|
int elapsed = 0;
|
||||||
|
|
||||||
|
while (gpio_get_level(dht_gpio) != level) {
|
||||||
|
if (elapsed++ > timeout_us) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ets_delay_us(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Envia sinal de start para o DHT11
|
||||||
|
*/
|
||||||
|
static esp_err_t dht11_send_start_signal(void)
|
||||||
|
{
|
||||||
|
/* Configura GPIO como saída */
|
||||||
|
gpio_set_direction(dht_gpio, GPIO_MODE_OUTPUT_OD);
|
||||||
|
|
||||||
|
/* Envia sinal de start: LOW por 18ms */
|
||||||
|
gpio_set_level(dht_gpio, 0);
|
||||||
|
ets_delay_us(20000); // 20ms para garantir
|
||||||
|
|
||||||
|
/* Libera o barramento (pull-up externo fará HIGH) */
|
||||||
|
gpio_set_level(dht_gpio, 1);
|
||||||
|
ets_delay_us(40);
|
||||||
|
|
||||||
|
/* Configura GPIO como entrada */
|
||||||
|
gpio_set_direction(dht_gpio, GPIO_MODE_INPUT);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lê 1 byte de dados do DHT11
|
||||||
|
*/
|
||||||
|
static uint8_t dht11_read_byte(void)
|
||||||
|
{
|
||||||
|
uint8_t byte = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
/* Espera sinal LOW (início do bit) */
|
||||||
|
if (dht11_wait_for_level(0, DHT11_TIMEOUT_US) < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Espera sinal HIGH (duração determina bit 0 ou 1) */
|
||||||
|
if (dht11_wait_for_level(1, DHT11_TIMEOUT_US) < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mede duração do HIGH */
|
||||||
|
ets_delay_us(30);
|
||||||
|
|
||||||
|
/* Se ainda HIGH após 30us, é bit 1, senão é bit 0 */
|
||||||
|
if (gpio_get_level(dht_gpio) == 1) {
|
||||||
|
byte |= (1 << (7 - i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t dht11_init(gpio_num_t gpio_num)
|
||||||
|
{
|
||||||
|
dht_gpio = gpio_num;
|
||||||
|
|
||||||
|
/* Configura GPIO com pull-up */
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = (1ULL << dht_gpio),
|
||||||
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_err_t ret = gpio_config(&io_conf);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to configure GPIO %d", dht_gpio);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "DHT11 initialized on GPIO %d", dht_gpio);
|
||||||
|
|
||||||
|
/* Aguarda sensor estabilizar (1 segundo) */
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t dht11_read(dht11_reading_t *reading)
|
||||||
|
{
|
||||||
|
if (reading == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inicializa leitura como inválida */
|
||||||
|
reading->valid = false;
|
||||||
|
reading->temperature = 0.0f;
|
||||||
|
reading->humidity = 0.0f;
|
||||||
|
|
||||||
|
/* Verifica intervalo mínimo entre leituras */
|
||||||
|
int64_t current_time = esp_timer_get_time();
|
||||||
|
if ((current_time - last_read_time) < DHT11_MIN_INTERVAL_US) {
|
||||||
|
ESP_LOGW(TAG, "Read too soon, wait at least 1 second between reads");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desabilita interrupções temporariamente para timing preciso */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Envia sinal de start */
|
||||||
|
dht11_send_start_signal();
|
||||||
|
|
||||||
|
/* Espera resposta do sensor (LOW por 80us) */
|
||||||
|
if (dht11_wait_for_level(0, DHT11_TIMEOUT_US) < 0) {
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
ESP_LOGE(TAG, "Timeout waiting for response LOW");
|
||||||
|
return ESP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Espera HIGH de resposta (80us) */
|
||||||
|
if (dht11_wait_for_level(1, DHT11_TIMEOUT_US) < 0) {
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
ESP_LOGE(TAG, "Timeout waiting for response HIGH");
|
||||||
|
return ESP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Espera início dos dados (LOW) */
|
||||||
|
if (dht11_wait_for_level(0, DHT11_TIMEOUT_US) < 0) {
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
ESP_LOGE(TAG, "Timeout waiting for data start");
|
||||||
|
return ESP_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lê 5 bytes de dados (umidade_int, umidade_dec, temp_int, temp_dec, checksum) */
|
||||||
|
uint8_t data[5] = {0};
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
data[i] = dht11_read_byte();
|
||||||
|
}
|
||||||
|
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Atualiza timestamp da última leitura */
|
||||||
|
last_read_time = esp_timer_get_time();
|
||||||
|
|
||||||
|
/* Verifica checksum */
|
||||||
|
uint8_t checksum = data[0] + data[1] + data[2] + data[3];
|
||||||
|
if (checksum != data[4]) {
|
||||||
|
ESP_LOGE(TAG, "Checksum error: calculated=0x%02X, received=0x%02X",
|
||||||
|
checksum, data[4]);
|
||||||
|
return ESP_ERR_INVALID_CRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DHT11 retorna valores inteiros (sem parte decimal) */
|
||||||
|
reading->humidity = (float)data[0];
|
||||||
|
reading->temperature = (float)data[2];
|
||||||
|
reading->valid = true;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Temperature: %.1f°C, Humidity: %.1f%%",
|
||||||
|
reading->temperature, reading->humidity);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t dht11_read_temperature(float *temperature)
|
||||||
|
{
|
||||||
|
dht11_reading_t reading;
|
||||||
|
esp_err_t ret = dht11_read(&reading);
|
||||||
|
|
||||||
|
if (ret == ESP_OK && reading.valid) {
|
||||||
|
*temperature = reading.temperature;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t dht11_read_humidity(float *humidity)
|
||||||
|
{
|
||||||
|
dht11_reading_t reading;
|
||||||
|
esp_err_t ret = dht11_read(&reading);
|
||||||
|
|
||||||
|
if (ret == ESP_OK && reading.valid) {
|
||||||
|
*humidity = reading.humidity;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/* DHT11 Temperature and Humidity Sensor Driver */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Estrutura para armazenar leitura do DHT11
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
float temperature; /* Temperatura em °C */
|
||||||
|
float humidity; /* Umidade relativa em % */
|
||||||
|
bool valid; /* Indica se a leitura é válida */
|
||||||
|
} dht11_reading_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inicializa o sensor DHT11
|
||||||
|
*
|
||||||
|
* @param gpio_num Número do GPIO conectado ao pino DATA do DHT11
|
||||||
|
* @return ESP_OK em caso de sucesso
|
||||||
|
*/
|
||||||
|
esp_err_t dht11_init(gpio_num_t gpio_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lê temperatura e umidade do DHT11
|
||||||
|
*
|
||||||
|
* @param reading Ponteiro para estrutura que receberá os dados
|
||||||
|
* @return ESP_OK em caso de sucesso, ESP_ERR_TIMEOUT se falhar
|
||||||
|
*
|
||||||
|
* @note O DHT11 requer intervalo mínimo de 1 segundo entre leituras
|
||||||
|
*/
|
||||||
|
esp_err_t dht11_read(dht11_reading_t *reading);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Obtém apenas a temperatura do DHT11
|
||||||
|
*
|
||||||
|
* @param temperature Ponteiro para receber temperatura em °C
|
||||||
|
* @return ESP_OK em caso de sucesso
|
||||||
|
*/
|
||||||
|
esp_err_t dht11_read_temperature(float *temperature);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Obtém apenas a umidade do DHT11
|
||||||
|
*
|
||||||
|
* @param humidity Ponteiro para receber umidade em %
|
||||||
|
* @return ESP_OK em caso de sucesso
|
||||||
|
*/
|
||||||
|
esp_err_t dht11_read_humidity(float *humidity);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user