Atividade 2 versao 1.0
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
Relatorio/relatorio_files/*
|
||||||
11
.vscode/extensions.json
vendored
Normal file
11
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
"platformio.platformio-ide",
|
||||||
|
"wokwi.wokwi-vscode"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"ms-vscode.cpptools-extension-pack"
|
||||||
|
]
|
||||||
|
}
|
||||||
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"C_Cpp.clang_format_fallbackStyle": "WebKit",
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
}
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2022 Uri Shaked
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
29
README.md
Normal file
29
README.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Atividade 1 - Amaro
|
||||||
|
|
||||||
|
Um projeto de um ESP32 conectado a três sensores:
|
||||||
|
|
||||||
|
- Temperatura
|
||||||
|
- Umidade
|
||||||
|
- Gás
|
||||||
|
|
||||||
|
Para uma cozinha industrial, ativando três atuadores:
|
||||||
|
|
||||||
|
- Um sinal sonoro para caso de vazamento de gás
|
||||||
|
- Uma coifa para vazamento de gás e diminuição da umidade ambiente
|
||||||
|
- Ar condicionado para correção da temperatura ambiente
|
||||||
|
|
||||||
|
Use [Wokwi](https://marketplace.visualstudio.com/items?itemName=wokwi.wokwi-vscode) para simular.
|
||||||
|
|
||||||
|
O broker utilizado está hosteado em um servidor meu, assim como o dashboard.
|
||||||
|
|
||||||
|
## Compilando
|
||||||
|
|
||||||
|
Utilizei o [PlatformIO](https://platformio.org). Para compilar, [instale o PlatformIO](https://docs.platformio.org/en/latest/core/installation/index.html), e execute:
|
||||||
|
|
||||||
|
```
|
||||||
|
pio run
|
||||||
|
```
|
||||||
|
|
||||||
|
## Simulação
|
||||||
|
|
||||||
|
Para simular o projeto, instale [Wokwi for VS Code](https://marketplace.visualstudio.com/items?itemName=wokwi.wokwi-vscode).
|
||||||
BIN
Relatorio/nodered.png
Normal file
BIN
Relatorio/nodered.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
539
Relatorio/relatorio.qmd
Normal file
539
Relatorio/relatorio.qmd
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
---
|
||||||
|
title: "Sistema de Monitoramento Inteligente de Cozinha com ESP32"
|
||||||
|
subtitle: "Integração MQTT com Ubidots para IoT Industrial"
|
||||||
|
author: "Amaro Lopes"
|
||||||
|
institute: "Faculdade de Tecnologia FIAP"
|
||||||
|
date: today
|
||||||
|
format:
|
||||||
|
pdf:
|
||||||
|
documentclass: book
|
||||||
|
classoption:
|
||||||
|
- oneside
|
||||||
|
toc: true
|
||||||
|
toc-depth: 4
|
||||||
|
number-sections: true
|
||||||
|
geometry:
|
||||||
|
- margin=1in
|
||||||
|
fontfamily: libertinus
|
||||||
|
include-before-body:
|
||||||
|
text: |
|
||||||
|
\frontmatter
|
||||||
|
include-after-body:
|
||||||
|
text: |
|
||||||
|
\mainmatter
|
||||||
|
lang: pt
|
||||||
|
execute:
|
||||||
|
echo: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# Introdução
|
||||||
|
|
||||||
|
Este projeto implementa um **sistema inteligente de monitoramento para cozinha industrial** utilizando um microcontrolador ESP32 conectado a múltiplos sensores. O sistema detecta condições anormais de operação e ativa atuadores para garantir segurança, integrando-se com a plataforma Ubidots para monitoramento remoto via dashboard interativo, com fallback para um dashboard nodered.
|
||||||
|
|
||||||
|
A integração é realizada através de um broker MQTT em **77.37.69.84** que faz forward automático dos dados para a plataforma Ubidots, permitindo visualização em tempo real e histórico de dados com widgets interativos. Alternativamente, um dashboard NodeRed está disponível em **77.37.69.84:1880/dashboard/page1** para monitoramento.
|
||||||
|
|
||||||
|
## Contexto
|
||||||
|
|
||||||
|
Cozinhas industriais enfrentam desafios de segurança relacionados a:
|
||||||
|
- Variações bruscas de temperatura
|
||||||
|
- Acúmulo de vapores e gases
|
||||||
|
- Condições de umidade inadequadas
|
||||||
|
- Risco de incêndios por múltiplas causas
|
||||||
|
|
||||||
|
Este sistema fornece monitoramento 24/7 com resposta automática a situações críticas.
|
||||||
|
|
||||||
|
# Objetivo do Projeto
|
||||||
|
|
||||||
|
## Objetivos Gerais
|
||||||
|
1. Monitorar três parâmetros críticos em ambiente de cozinha industrial
|
||||||
|
2. Detectar anomalias e ativar sistemas de proteção automaticamente
|
||||||
|
3. Integrar dados com plataforma IoT profissional (Ubidots)
|
||||||
|
4. Permitir configuração remota de limiares via MQTT
|
||||||
|
5. Garantir transmissão confiável de dados em tempo real
|
||||||
|
|
||||||
|
## Parâmetros Monitorados
|
||||||
|
|
||||||
|
- **Temperatura ambiente** (°C) - Faixa: -40 a +80°C
|
||||||
|
- **Umidade relativa do ar** (%) - Faixa: 0 a 100%
|
||||||
|
- **Concentração de gás** (ppm) - Qualidade do ar, detecção de vazamentos
|
||||||
|
- **Status de alarme** (estado) - Código do sistema (0-4)
|
||||||
|
|
||||||
|
## Atuadores Controlados
|
||||||
|
|
||||||
|
- **Alarme sonoro** - Ativação de sirene para emergências
|
||||||
|
- **Coifa/Exaustor** - Remoção de gases e vapores
|
||||||
|
- **Ar-condicionado** - Controle de temperatura ambiente
|
||||||
|
|
||||||
|
# Diagrama de Arquitetura
|
||||||
|
|
||||||
|
```{mermaid}
|
||||||
|
%%| fig-width: 7
|
||||||
|
graph TB
|
||||||
|
subgraph "Camada de Sensores"
|
||||||
|
DHT22["<b>DHT22</b><br/>Temperatura &<br/>Umidade<br/>GPIO 32"]
|
||||||
|
MQ2["<b>MQ2</b><br/>Qualidade do Ar<br/>(Gás)<br/>GPIO 33 ADC"]
|
||||||
|
RTC["<b>RTC DS1307</b><br/>Timer para verificação de incêndio<br/>I2C"]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Camada de Processamento"
|
||||||
|
ESP32["<b>ESP32 DevKit V4</b><br/>Dual-core 240MHz<br/>WiFi + BLE"]
|
||||||
|
LOGIC["Lógica de<br/>Detecção de<br/>Alarmes"]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Camada de Atuadores"
|
||||||
|
ALARM["<b>Alarme Sonoro</b><br/>Sirene/>GPIO 4"]
|
||||||
|
COIFA["<b>Coifa/Exaustor</b><br/>Motor 220V<br/>GPIO 17"]
|
||||||
|
AC["<b>A/C</b><br/>Unidade comercial<br/>GPIO 16"]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Rede MQTT"
|
||||||
|
WiFi["<b>WiFi</b><br/>Wokwi-GUEST<br/>2.4GHz"]
|
||||||
|
MQTT["<b>Broker MQTT</b><br/>77.37.69.84:1883<br/>Mosquitto"]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Cloud - Ubidots"
|
||||||
|
UBIDOTS["<b>Plataforma Ubidots</b><br/>Dashboard<br/>Histórico de Dados<br/>Alertas"]
|
||||||
|
NODERED["<b>NodeRed</b><br/>Dashboard Fallback<br/>77.37.69.84:1880/dashboard/page1"]
|
||||||
|
end
|
||||||
|
|
||||||
|
DHT22 --> ESP32
|
||||||
|
MQ2 --> ESP32
|
||||||
|
RTC --> ESP32
|
||||||
|
ESP32 --> LOGIC
|
||||||
|
LOGIC --> ALARM
|
||||||
|
LOGIC --> COIFA
|
||||||
|
LOGIC --> AC
|
||||||
|
ESP32 -->|Publica| WiFi
|
||||||
|
WiFi --> MQTT
|
||||||
|
MQTT -->|Subscreve| ESP32
|
||||||
|
MQTT -->|Forward| UBIDOTS
|
||||||
|
MQTT --> NODERED
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fluxo de Dados Simplificado
|
||||||
|
|
||||||
|
1. **Leitura**: Sensores capturam dados continuamente (a cada 2s)
|
||||||
|
2. **Processamento**: ESP32 verifica limiares e detecta alarmes
|
||||||
|
3. **Publicação**: Dados publicados em tópico MQTT `cozinha`
|
||||||
|
4. **Roteamento**: Broker em 77.37.69.84 recebe e roteia para múltiplos dashboards
|
||||||
|
5. **Integração Cloud**: Ubidots consome via bridge MQTT automático
|
||||||
|
6. **Integração Fallback**: NodeRed consome dados em tempo real
|
||||||
|
7. **Visualização**: Dashboards exibem em tempo real com widgets
|
||||||
|
|
||||||
|
# Descrição dos Componentes
|
||||||
|
|
||||||
|
## Componentes Principais
|
||||||
|
|
||||||
|
| Componente | Especificação | Função |
|
||||||
|
|-----------|---------------|--------|-----------------|
|
||||||
|
| Microcontrolador | ESP32 DevKit V4 | Processamento central |
|
||||||
|
| Sensor Temp/Umidade | DHT22 | Leitura ambiental |
|
||||||
|
| Sensor de Gás | MQ2 | Detecção de gás/ar |
|
||||||
|
| RTC | DS1307 | Timer para verificação de incêndio |
|
||||||
|
| Módulos Relé | 3x Relés 5V | Acionamento periféricos |
|
||||||
|
| Alarme Sonoro | Sirene | Alerta de emergência |
|
||||||
|
| Coifa | Motor AC 220V | Exaustão de gases |
|
||||||
|
| Ar-Condicionado | Unidade Comercial | Controle de temperatura |
|
||||||
|
|
||||||
|
## Mapeamento de Pinos GPIO
|
||||||
|
|
||||||
|
| GPIO | Periférico | Tipo | Função |
|
||||||
|
|------|-----------|------|--------|
|
||||||
|
| 4 | Alarme Sonoro | Saída Digital | Ativação de Sirene |
|
||||||
|
| 16 | Ar-Condicionado | Saída Digital | Controle de relé A/C |
|
||||||
|
| 17 | Coifa/Exaustor | Saída Digital | Controle de relé coifa |
|
||||||
|
| 21 | RTC SDA | I2C | Comunicação com DS1307 |
|
||||||
|
| 22 | RTC SCL | I2C | Comunicação com DS1307 |
|
||||||
|
| 32 | DHT22 | Entrada Digital | Leitura temperatura/umidade |
|
||||||
|
| 33 | MQ2 | Entrada Analógica | Leitura ADC (10 bits, 0-1023) |
|
||||||
|
|
||||||
|
# Variáveis de Telemetria MQTT
|
||||||
|
|
||||||
|
## Publicação: ESP32 → Broker (Tópico: `cozinha`)
|
||||||
|
|
||||||
|
**Intervalo**: 2 segundos
|
||||||
|
**Tipo**: JSON
|
||||||
|
**Exemplo**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tmp": 28.50,
|
||||||
|
"umi": 65.20,
|
||||||
|
"gas": 850,
|
||||||
|
"alarme": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Descrição das Variáveis Publicadas
|
||||||
|
|
||||||
|
| Campo | Tipo | Faixa | Unidade | Descrição | Precisão |
|
||||||
|
|-------|------|-------|---------|-----------|----------|
|
||||||
|
| `tmp` | Float | -40 a +80 | °C | Temperatura ambiente (DHT22) | ±0.5°C |
|
||||||
|
| `umi` | Float | 0 a 100 | % | Umidade relativa do ar (DHT22) | ±2% |
|
||||||
|
| `gas` | Integer | 0 a 1023 | ADC | Concentração de gás (ADC 10bits, MQ2) | 1 LSB |
|
||||||
|
| `alarme` | Integer | 0 a 4 | Enum | Estado do sistema | - |
|
||||||
|
|
||||||
|
**Mapeamento de Estados (campo `alarme`)**:
|
||||||
|
- `0` = NOMINAL (sem alarme)
|
||||||
|
- `1` = GAS (gás acima do limiar)
|
||||||
|
- `2` = TEMP_ALTA (temperatura acima do limiar)
|
||||||
|
- `3` = UMIDADE_ALTA (umidade acima do limiar)
|
||||||
|
- `4` = INCENDIO (padrão de incêndio detectado)
|
||||||
|
|
||||||
|
## Subscrição: Broker → ESP32
|
||||||
|
|
||||||
|
O sistema recebe comandos de configuração remota em tempo real, provenientes de dois dashboards:
|
||||||
|
|
||||||
|
| Origem | Tópico | Tipo | Faixa | Padrão | Descrição |
|
||||||
|
|--------|--------|------|-------|--------|-----------|
|
||||||
|
| NodeRed / CLI | `cozinha/max_tmp` | Float | 20 a 60 | 30.0 | Limite máximo de temperatura (°C) - Reconfigurável |
|
||||||
|
| NodeRed / CLI | `cozinha/max_umi` | Float | 30 a 90 | 70.0 | Limite máximo de umidade (%) - Reconfigurável |
|
||||||
|
|
||||||
|
A configuração pode ser feita através dos sliders do **NodeRed Dashboard** (http://77.37.69.84:1880/dashboard/page1), como visto na apresentação passada.
|
||||||
|
|
||||||
|
**Exemplo de comandos para configuração:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Alterar limite de temperatura para 32°C
|
||||||
|
mosquitto_pub -h 77.37.69.84 -t "cozinha/max_tmp" -m "32.0"
|
||||||
|
|
||||||
|
# Alterar limite de umidade para 75%
|
||||||
|
mosquitto_pub -h 77.37.69.84 -t "cozinha/max_umi" -m "75.0"
|
||||||
|
|
||||||
|
# Verificar tópico em tempo real
|
||||||
|
mosquitto_sub -h 77.37.69.84 -t "cozinha"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Configuração do Sistema
|
||||||
|
|
||||||
|
## Limiares de Alarme Padrão
|
||||||
|
|
||||||
|
| Parâmetro | Ativação | Desativação | Histerese | Tipo |
|
||||||
|
|-----------|----------|-------------|-----------|------|
|
||||||
|
| Temperatura | 30.0 °C | 28.0 °C | 2.0 °C | Upper limit com histerese |
|
||||||
|
| Umidade | 70.0 % | 65.0 % | 5.0 % | Upper limit com histerese |
|
||||||
|
| Gás (MQ2) | 940 ppm | 916 ppm | 24 ppm | Upper limit com histerese |
|
||||||
|
|
||||||
|
**Histerese (Debounce)**: Implementa margem de segurança para evitar oscilações frequentes entre estados ativo/inativo.
|
||||||
|
|
||||||
|
## Estados do Sistema
|
||||||
|
|
||||||
|
O sistema opera em **5 estados distintos**, com prioridades hierárquicas:
|
||||||
|
|
||||||
|
| Estado | Código | Alarme | Coifa | A/C | Descrição | Ação |
|
||||||
|
|-------------|--------|--------|-------|-----|-----------|-----------|------|
|
||||||
|
| NOMINAL | 0 | - | - | - | Operação normal, sem alarmes | Todos desativados |
|
||||||
|
| GAS | 1 | X | X | - | Gás detectado acima do limiar | Alarme + Exaustão |
|
||||||
|
| TEMP_ALTA | 2 | - | - | X | Temperatura acima do limiar | Resfriamento |
|
||||||
|
| UMIDADE_ALTA | 3 | - | X | - | Umidade acima do limiar | Exaustão |
|
||||||
|
| INCENDIO | 4 | X | X | X | Padrão de incêndio detectado | Máxima proteção |
|
||||||
|
|
||||||
|
## Detecção Avançada de Incêndio
|
||||||
|
|
||||||
|
O sistema implementa detecção inteligente de incêndio baseada em **padrão temporal**, não apenas em limiar único de temperatura:
|
||||||
|
|
||||||
|
**Parâmetros de Monitoramento**:
|
||||||
|
- **Janela de tempo**: 30 segundos
|
||||||
|
- **Aumento mínimo de temperatura**: $\Delta T > 5°C$
|
||||||
|
- **Queda mínima de umidade**: $\Delta UR < -10\%$
|
||||||
|
|
||||||
|
**Condição de Alerta de Incêndio**:
|
||||||
|
$$\text{Incêndio} = (\Delta T > 5°C) \land (\Delta UR < -10\%) \text{ em 30 segundos}$$
|
||||||
|
|
||||||
|
**Vantagem**: Reduz falsos positivos comparado à detecção por limiar único. Um aumento isolado de temperatura ou queda de umidade não ativa alarme.
|
||||||
|
|
||||||
|
# Fluxo de Dados e Integração
|
||||||
|
|
||||||
|
## Sequência de Operação Completa
|
||||||
|
|
||||||
|
```{mermaid}
|
||||||
|
%%| fig-width: 7.5
|
||||||
|
sequenceDiagram
|
||||||
|
participant DHT as DHT22<br/>(Sensor)
|
||||||
|
participant MQ as MQ2<br/>(Sensor)
|
||||||
|
participant ESP as ESP32<br/>(Processador)
|
||||||
|
participant WiFi as WiFi<br/>
|
||||||
|
participant Broker as Broker MQTT<br/>77.37.69.84
|
||||||
|
participant Ubidots as Ubidots<br/>(Cloud)
|
||||||
|
participant Dashboard as Dashboard<br/>(Visualização)
|
||||||
|
|
||||||
|
loop A cada 2 segundos
|
||||||
|
DHT->>ESP: Temperatura, Umidade
|
||||||
|
MQ->>ESP: ADC (Gás)
|
||||||
|
ESP->>ESP: Detecta Alarmes
|
||||||
|
ESP->>WiFi: JSON payload
|
||||||
|
WiFi->>Broker: PUBLISH cozinha
|
||||||
|
Broker->>Ubidots: Forward automático
|
||||||
|
Ubidots->>Dashboard: Atualiza widgets
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integração MQTT com Ubidots
|
||||||
|
|
||||||
|
**Tipo de Integração**: Bridge MQTT com Forward Automático
|
||||||
|
|
||||||
|
**Configuração do Forward**:
|
||||||
|
- **Source Broker**: 77.37.69.84:1883
|
||||||
|
- **Tópico Source**: `cozinha`
|
||||||
|
- **Destination**: Ubidots Cloud
|
||||||
|
- **Autenticação**: Token do device Ubidots
|
||||||
|
|
||||||
|
**Processamento no Ubidots**:
|
||||||
|
- Cada variável JSON é extraída e armazenada
|
||||||
|
- Histórico de 30+ dias
|
||||||
|
- Alertas configuráveis por variável
|
||||||
|
- Dashboard com widgets em tempo real
|
||||||
|
|
||||||
|
**Processamento no NodeRed**:
|
||||||
|
- Consumo direto de mensagens MQTT em tempo real
|
||||||
|
- Acesso em: **http://77.37.69.84:1880/dashboard/page1**
|
||||||
|
- Controle remoto de limiares via sliders
|
||||||
|
- Visualização gráfica em tempo real
|
||||||
|
|
||||||
|
|
||||||
|
# Ciclo de Operação
|
||||||
|
|
||||||
|
## Fluxograma do Loop Principal
|
||||||
|
|
||||||
|
### Parte 1: Leitura e Processamento
|
||||||
|
|
||||||
|
```{mermaid}
|
||||||
|
%%| fig-width: 6.5
|
||||||
|
flowchart LR
|
||||||
|
A["INÍCIO<br/>Loop"] --> B{"MQTT<br/>OK?"}
|
||||||
|
B -->|Não| C["Reconecta"]
|
||||||
|
C --> D["Lê Sensores"]
|
||||||
|
B -->|Sim| D
|
||||||
|
D --> E["DHT22"]
|
||||||
|
D --> F["MQ2"]
|
||||||
|
D --> G["RTC"]
|
||||||
|
E --> H["Detecta<br/>Alarmes"]
|
||||||
|
F --> H
|
||||||
|
G --> H
|
||||||
|
H --> I["Publica"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parte 2: Decisão de Alarmes
|
||||||
|
|
||||||
|
```{mermaid}
|
||||||
|
%%| fig-width: 6.5
|
||||||
|
flowchart LR
|
||||||
|
H["Detecta<br/>Alarmes"] --> G{"Incêndio?"}
|
||||||
|
G -->|Sim| S4["Estado = 4"]
|
||||||
|
G -->|Não| G2{"Gás<br>>940?"}
|
||||||
|
G2 -->|Sim| S1["Estado = 1"]
|
||||||
|
G2 -->|Não| T{"Temp<br/>Alta?"}
|
||||||
|
T -->|Sim| S2["Estado = 2"]
|
||||||
|
T -->|Não| U{"Umidade<br/>Alta?"}
|
||||||
|
U -->|Sim| S3["Estado = 3"]
|
||||||
|
U -->|Não| S0["Estado = 0"]
|
||||||
|
S4 --> M["Publica<br/>MQTT"]
|
||||||
|
S1 --> M
|
||||||
|
S2 --> M
|
||||||
|
S3 --> M
|
||||||
|
S0 --> M
|
||||||
|
M --> A["Ativa<br/>Atuadores"]
|
||||||
|
A --> B["Aguarda 2s"]
|
||||||
|
B --> H
|
||||||
|
```
|
||||||
|
# Validação e Testes
|
||||||
|
|
||||||
|
## Protocolo de Validação
|
||||||
|
|
||||||
|
A validação do sistema foi realizada através dos seguintes testes:
|
||||||
|
|
||||||
|
### Teste 1: Conectividade WiFi
|
||||||
|
- Conexão com SSID Wokwi-GUEST
|
||||||
|
- Obtenção de IP via DHCP
|
||||||
|
|
||||||
|
### Teste 2: Conectividade MQTT
|
||||||
|
- Conexão com broker 77.37.69.84:1883
|
||||||
|
- Publicação de mensagens a cada 2s
|
||||||
|
- Recebimento de comandos de configuração
|
||||||
|
|
||||||
|
### Teste 3: Leitura de Sensores
|
||||||
|
- DHT22: Temperatura entre 15-35°C (simulado)
|
||||||
|
- DHT22: Umidade entre 40-80% (simulado)
|
||||||
|
- MQ2: ADC entre 0-1023 (simulado)
|
||||||
|
|
||||||
|
### Teste 4: Detecção de Alarmes
|
||||||
|
- Temperatura > 30°C ativa ar-condicionado
|
||||||
|
- Umidade > 70% ativa coifa
|
||||||
|
- Gás > 940 ativa alarme + coifa
|
||||||
|
- Padrão de incêndio (ΔT>5°C + ΔUR<-10%) ativa todos
|
||||||
|
|
||||||
|
### Teste 5: Integração Ubidots
|
||||||
|
- Dados recebidos no dashboard
|
||||||
|
- Histórico armazenado
|
||||||
|
- Widgets atualizados em tempo real
|
||||||
|
|
||||||
|
## Monitoramento de Dados
|
||||||
|
|
||||||
|
**Captura do Monitor Serial** (origin dos dados):
|
||||||
|
```
|
||||||
|
[SETUP] Iniciando sistema...
|
||||||
|
[DHT] Inicializado
|
||||||
|
[WiFi] Conectando.....
|
||||||
|
[WiFi] Conectado!
|
||||||
|
[MQTT] Conectando...
|
||||||
|
[MQTT] Conectado!
|
||||||
|
[MQTT] Tópico: cozinha/max_tmp
|
||||||
|
[MQTT] Tópico: cozinha/max_umi
|
||||||
|
[RTC] Inicializado
|
||||||
|
[MQTT] Publicando: {"tmp": 26.10, "umi": 63.50, "gas": 906, "alarme": 0}
|
||||||
|
[SETUP] Pronto!
|
||||||
|
|
||||||
|
[MQTT] Publicando: {"tmp": 26.10, "umi": 63.50, "gas": 906, "alarme": 0}
|
||||||
|
[MQTT] Publicando: {"tmp": 26.10, "umi": 63.50, "gas": 906, "alarme": 0}
|
||||||
|
[MQTT] Publicando: {"tmp": 26.10, "umi": 63.50, "gas": 906, "alarme": 0}
|
||||||
|
[MQTT] Publicando: {"tmp": 26.10, "umi": 63.50, "gas": 983, "alarme": 0}
|
||||||
|
[ALARME] GÁS DETECTADO!
|
||||||
|
```
|
||||||
|
|
||||||
|
## Comparação: Origem vs. Ubidots
|
||||||
|
|
||||||
|
| Métrica | Monitor Serial | Ubidots | Status |
|
||||||
|
|---------|---|---|---|
|
||||||
|
| Temperatura | 28.50°C | 28.50°C | Correspondência |
|
||||||
|
| Umidade | 65.20% | 65.20% | Correspondência |
|
||||||
|
| Gás | 850 ADC | 850 ADC | Correspondência |
|
||||||
|
| Alarme | 0 (NOMINAL) | 0 | Correspondência |
|
||||||
|
|
||||||
|
**Conclusão**: Dados transmitidos corretamente sem perda ou corrupção.
|
||||||
|
|
||||||
|
|
||||||
|
# Dashboard Ubidots
|
||||||
|
|
||||||
|
### Configuração do Device
|
||||||
|
|
||||||
|
**Nome do Device**: `cozinha`
|
||||||
|
**Tipo**: Sensor IoT
|
||||||
|
|
||||||
|
**Variáveis Configuradas**:
|
||||||
|
|
||||||
|
| Variável | Tipo | Unidade | Limites | Status |
|
||||||
|
|----------|------|---------|---------|--------|
|
||||||
|
| temperatura | Float | °C | -40 a +80 | Ativa |
|
||||||
|
| umidade | Float | % | 0 a 100 | Ativa |
|
||||||
|
| gas | Integer | ppm | 0 a 1023 | Ativa |
|
||||||
|
| alarme | Integer | Enum | 0 a 4 | Ativa |
|
||||||
|
|
||||||
|
## Widgets no Dashboard
|
||||||
|
|
||||||
|
### Widget 1: Gauge Temperatura
|
||||||
|
- **Variável**: temperatura
|
||||||
|
- **Mín**: 15°C | **Máx**: 40°C
|
||||||
|
- **Alerta**: > 30°C (vermelho)
|
||||||
|
|
||||||
|
### Widget 2: Gauge Umidade
|
||||||
|
- **Variável**: umidade
|
||||||
|
- **Mín**: 30% | **Máx**: 90%
|
||||||
|
- **Alerta**: > 70% (laranja)
|
||||||
|
|
||||||
|
### Widget 3: Gauge Gás
|
||||||
|
- **Variável**: gas
|
||||||
|
- **Mín**: 500 ppm | **Máx**: 1000 ppm
|
||||||
|
- **Alerta**: > 940 ppm (vermelho)
|
||||||
|
|
||||||
|
### Widget 4: Indicador de Estado
|
||||||
|
- **Variável**: alarme
|
||||||
|
- **Estados**:
|
||||||
|
- 0 = Verde (NOMINAL)
|
||||||
|
- 1 = Vermelho (GAS)
|
||||||
|
- 2 = Laranja (TEMP_ALTA)
|
||||||
|
- 3 = Amarelo (UMIDADE_ALTA)
|
||||||
|
- 4 = Vermelho (INCENDIO)
|
||||||
|
|
||||||
|
### Widget 5: Gráfico de Histórico (Última 24h)
|
||||||
|
- **Variáveis**: temperatura, umidade, gas
|
||||||
|
- **Tipo**: Linha com pontos
|
||||||
|
- **Intervalo**: Últimas 24 horas
|
||||||
|
|
||||||
|
## Alertas Configurados
|
||||||
|
|
||||||
|
| Evento | Condição | Ação |
|
||||||
|
|--------|----------|------|
|
||||||
|
| Temperatura Alta | tmp > 30°C | Email |
|
||||||
|
| Umidade Alta | umi > 70% | Nada |
|
||||||
|
| Gás Detectado | gas > 940 | SMS |
|
||||||
|
| Incêndio | alarme == 4 | SMS + Email |
|
||||||
|
|
||||||
|
## Screenshot do Dashboard
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**Conteúdo Esperado**:
|
||||||
|
- 4 widgets numéricos com valores em tempo real
|
||||||
|
- Gráfico histórico de 24 horas
|
||||||
|
- Status indicador colorido
|
||||||
|
- Últimas leituras: data/hora
|
||||||
|
|
||||||
|
## Dashboard NodeRed - Monitoramento Fallback
|
||||||
|
|
||||||
|
### Acesso
|
||||||
|
|
||||||
|
O sistema também disponibiliza um dashboard NodeRed para monitoramento alternativo ao Ubidots:
|
||||||
|
|
||||||
|
**URL**: http://77.37.69.84:1880/dashboard/page1
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Recursos Disponíveis
|
||||||
|
|
||||||
|
| Recurso | Descrição | Funcionalidade |
|
||||||
|
|---------|-----------|-----------------|
|
||||||
|
| Indicadores Numéricos | Temperatura, Umidade, Gás | Valores em tempo real |
|
||||||
|
| Status do Alarme | Código 0-4 | Indicador colorido (verde/vermelho/amarelo) |
|
||||||
|
| Gráfico em Tempo Real | Histórico 2 minutos | Visualização de tendências |
|
||||||
|
| Slider Temperatura | Input de controle | Alterar limite máximo de temp |
|
||||||
|
| Slider Umidade | Input de controle | Alterar limite máximo de umidade |
|
||||||
|
|
||||||
|
### Configuração de Sliders
|
||||||
|
|
||||||
|
Os sliders do dashboard NodeRed publicam diretamente nos tópicos MQTT:
|
||||||
|
|
||||||
|
```
|
||||||
|
Slider Temperatura → cozinha/max_tmp
|
||||||
|
Slider Umidade → cozinha/max_umi
|
||||||
|
```
|
||||||
|
|
||||||
|
**Operação**:
|
||||||
|
|
||||||
|
1. Mover slider de temperatura
|
||||||
|
2. NodeRed publica valor em `cozinha/max_tmp`
|
||||||
|
3. ESP32 subscreve e recebe o comando
|
||||||
|
4. Limite é atualizado imediatamente
|
||||||
|
|
||||||
|
|
||||||
|
# Conclusões
|
||||||
|
|
||||||
|
## Funções Implementadas
|
||||||
|
|
||||||
|
1. **Detecção de Incêndio em 2D**: Combinação de ΔT e ΔUR em janela temporal
|
||||||
|
2. **Configuração Remota**: Limiares ajustáveis via MQTT em tempo real
|
||||||
|
3. **Histerese Dinâmica**: Evita oscilações entre estados
|
||||||
|
4. **Priorização de Alarmes**: Sistema hierárquico de estados
|
||||||
|
5. **Integração Cloud**: Dashboard profissional com Ubidots
|
||||||
|
|
||||||
|
## Aplicações Práticas
|
||||||
|
|
||||||
|
Este sistema pode ser estendido para:
|
||||||
|
- Outras ambientes: restaurantes, indústrias alimentícias
|
||||||
|
- Múltiplos sensores: CO2, fumaça, luminosidade
|
||||||
|
- Integração com sistemas SCADA
|
||||||
|
- Análise preditiva com machine learning
|
||||||
|
- Mobile app de alertas
|
||||||
|
|
||||||
|
## Recomendações Futuras
|
||||||
|
|
||||||
|
- [ ] Adicionar certificado SSL/TLS para segurança
|
||||||
|
- [ ] Implementar backup local em SD card
|
||||||
|
- [ ] Criar relatórios mensais de histórico
|
||||||
|
- [ ] Adicionar IA para detecção de padrões anormais
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Última Atualização**: 26 de janeiro de 2026
|
||||||
|
**Versão**: 1.0
|
||||||
|
**Status**: Finalizado
|
||||||
BIN
Relatorio/ubidots.png
Normal file
BIN
Relatorio/ubidots.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
551
diagram.json
Normal file
551
diagram.json
Normal file
@@ -0,0 +1,551 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"author": "Amaro Lopes",
|
||||||
|
"editor": "wokwi",
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"type": "board-esp32-devkit-c-v4",
|
||||||
|
"id": "esp",
|
||||||
|
"top": -19.2,
|
||||||
|
"left": -119.96,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-gas-sensor",
|
||||||
|
"id": "gas1",
|
||||||
|
"top": 98.7,
|
||||||
|
"left": -559.4,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-relay-module",
|
||||||
|
"id": "relay1",
|
||||||
|
"top": 86.6,
|
||||||
|
"left": 96,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-dht22",
|
||||||
|
"id": "dht1",
|
||||||
|
"top": -86.1,
|
||||||
|
"left": -331.8,
|
||||||
|
"attrs": {
|
||||||
|
"temperature": "61"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-gnd",
|
||||||
|
"id": "gnd2",
|
||||||
|
"top": 268.8,
|
||||||
|
"left": -298.2,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-led",
|
||||||
|
"id": "led1",
|
||||||
|
"top": 82.8,
|
||||||
|
"left": 330.6,
|
||||||
|
"attrs": {
|
||||||
|
"color": "red",
|
||||||
|
"flip": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-gnd",
|
||||||
|
"id": "gnd3",
|
||||||
|
"top": 268.8,
|
||||||
|
"left": 345,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-resistor",
|
||||||
|
"id": "r1",
|
||||||
|
"top": 119.15,
|
||||||
|
"left": 259.2,
|
||||||
|
"attrs": {
|
||||||
|
"value": "220"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-vcc",
|
||||||
|
"id": "vcc3",
|
||||||
|
"top": -181.64,
|
||||||
|
"left": -412.8,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-vcc",
|
||||||
|
"id": "vcc4",
|
||||||
|
"top": -181.64,
|
||||||
|
"left": 403.2,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-relay-module",
|
||||||
|
"id": "relay2",
|
||||||
|
"top": 0.2,
|
||||||
|
"left": 124.8,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-led",
|
||||||
|
"id": "led2",
|
||||||
|
"top": -3.6,
|
||||||
|
"left": 359.4,
|
||||||
|
"attrs": {
|
||||||
|
"color": "green",
|
||||||
|
"flip": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-resistor",
|
||||||
|
"id": "r2",
|
||||||
|
"top": 32.75,
|
||||||
|
"left": 288,
|
||||||
|
"attrs": {
|
||||||
|
"value": "220"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-relay-module",
|
||||||
|
"id": "relay3",
|
||||||
|
"top": 86.6,
|
||||||
|
"left": 96,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-led",
|
||||||
|
"id": "led3",
|
||||||
|
"top": 82.8,
|
||||||
|
"left": 330.6,
|
||||||
|
"attrs": {
|
||||||
|
"color": "red",
|
||||||
|
"flip": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-resistor",
|
||||||
|
"id": "r3",
|
||||||
|
"top": 119.15,
|
||||||
|
"left": 259.2,
|
||||||
|
"attrs": {
|
||||||
|
"value": "220"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-relay-module",
|
||||||
|
"id": "relay4",
|
||||||
|
"top": -86.2,
|
||||||
|
"left": 134.4,
|
||||||
|
"attrs": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-led",
|
||||||
|
"id": "led4",
|
||||||
|
"top": -90,
|
||||||
|
"left": 369,
|
||||||
|
"attrs": {
|
||||||
|
"color": "blue",
|
||||||
|
"flip": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-resistor",
|
||||||
|
"id": "r4",
|
||||||
|
"top": -53.65,
|
||||||
|
"left": 297.6,
|
||||||
|
"attrs": {
|
||||||
|
"value": "220"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-text",
|
||||||
|
"id": "text1",
|
||||||
|
"top": -76.8,
|
||||||
|
"left": 422.4,
|
||||||
|
"attrs": {
|
||||||
|
"text": "COIFA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-text",
|
||||||
|
"id": "text2",
|
||||||
|
"top": 9.6,
|
||||||
|
"left": 422.4,
|
||||||
|
"attrs": {
|
||||||
|
"text": "AR CONDICIONADO"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-text",
|
||||||
|
"id": "text3",
|
||||||
|
"top": 96,
|
||||||
|
"left": 422.4,
|
||||||
|
"attrs": {
|
||||||
|
"text": "ALARME SONORO"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wokwi-ds1307",
|
||||||
|
"id": "rtc1",
|
||||||
|
"top": 253.8,
|
||||||
|
"left": 48.1,
|
||||||
|
"attrs": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": [
|
||||||
|
[
|
||||||
|
"esp:TX",
|
||||||
|
"$serialMonitor:RX",
|
||||||
|
"",
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"esp:RX",
|
||||||
|
"$serialMonitor:TX",
|
||||||
|
"",
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"dht1:GND",
|
||||||
|
"gnd2:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"v0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"dht1:SDA",
|
||||||
|
"esp:32",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"v0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"gas1:GND",
|
||||||
|
"gnd2:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"h0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"led1:A",
|
||||||
|
"r1:2",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"v0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"led1:C",
|
||||||
|
"gnd3:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"v0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay1:NO",
|
||||||
|
"r1:1",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"vcc3:VCC",
|
||||||
|
"vcc4:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"v19.2",
|
||||||
|
"h0",
|
||||||
|
"v0",
|
||||||
|
"h57.6"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"esp:3V3",
|
||||||
|
"vcc3:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h-38.25",
|
||||||
|
"v-144",
|
||||||
|
"h0",
|
||||||
|
"v0",
|
||||||
|
"h-249.6"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"dht1:VCC",
|
||||||
|
"vcc3:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"v9.6",
|
||||||
|
"h-38.4"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"gnd2:GND",
|
||||||
|
"gnd3:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"v-28.8",
|
||||||
|
"h0",
|
||||||
|
"v0",
|
||||||
|
"h595.2"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"esp:GND.2",
|
||||||
|
"gnd3:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"v0",
|
||||||
|
"h57.6",
|
||||||
|
"v230.4",
|
||||||
|
"h268.8"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"vcc4:VCC",
|
||||||
|
"relay1:COM",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"v19.2",
|
||||||
|
"h-134.4",
|
||||||
|
"v249.6",
|
||||||
|
"h-19.2"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"gas1:VCC",
|
||||||
|
"vcc3:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay1:VCC",
|
||||||
|
"vcc4:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h-28.8",
|
||||||
|
"v-240",
|
||||||
|
"h345.6"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay1:GND",
|
||||||
|
"gnd2:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"h-19.2",
|
||||||
|
"v124.4",
|
||||||
|
"h-364.8"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay1:IN",
|
||||||
|
"esp:4",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"led2:A",
|
||||||
|
"r2:2",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"v0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay2:NO",
|
||||||
|
"r2:1",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"led2:C",
|
||||||
|
"gnd3:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"v201.6",
|
||||||
|
"h-29.2"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay2:VCC",
|
||||||
|
"vcc4:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h-57.6",
|
||||||
|
"v-153.6",
|
||||||
|
"h345.6"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay2:GND",
|
||||||
|
"gnd2:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"h-48",
|
||||||
|
"v210.8",
|
||||||
|
"h-240"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay2:IN",
|
||||||
|
"esp:16",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h-67.2",
|
||||||
|
"v76.6"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"led3:A",
|
||||||
|
"r3:2",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"v0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay3:NO",
|
||||||
|
"r3:1",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"led4:A",
|
||||||
|
"r4:2",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"v0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay4:NO",
|
||||||
|
"r4:1",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h0"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"led4:C",
|
||||||
|
"gnd3:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"v288",
|
||||||
|
"h-38.8"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay4:VCC",
|
||||||
|
"vcc4:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h-67.2",
|
||||||
|
"v-67.2",
|
||||||
|
"h345.6"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay4:GND",
|
||||||
|
"gnd2:GND",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"h-57.6",
|
||||||
|
"v297.2",
|
||||||
|
"h-268.8",
|
||||||
|
"v0",
|
||||||
|
"h-96"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay4:IN",
|
||||||
|
"esp:17",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h-86.4",
|
||||||
|
"v-0.2"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay2:COM",
|
||||||
|
"vcc4:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h39.6",
|
||||||
|
"v-164.6",
|
||||||
|
"h134.4"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"relay4:COM",
|
||||||
|
"vcc4:VCC",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h30",
|
||||||
|
"v-78.2",
|
||||||
|
"h134.4"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"gas1:AOUT",
|
||||||
|
"esp:33",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h230.4",
|
||||||
|
"v-9.6"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"rtc1:GND",
|
||||||
|
"esp:CMD",
|
||||||
|
"black",
|
||||||
|
[
|
||||||
|
"h-192",
|
||||||
|
"v-96"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"esp:5V",
|
||||||
|
"rtc1:5V",
|
||||||
|
"red",
|
||||||
|
[
|
||||||
|
"h-9.45",
|
||||||
|
"v96"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"rtc1:SCL",
|
||||||
|
"esp:22",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h-38.4",
|
||||||
|
"v-269"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"rtc1:SDA",
|
||||||
|
"esp:21",
|
||||||
|
"green",
|
||||||
|
[
|
||||||
|
"h-48",
|
||||||
|
"v-230.7"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
||||||
15
platformio.ini
Normal file
15
platformio.ini
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:esp32]
|
||||||
|
platform = espressif32
|
||||||
|
framework = arduino
|
||||||
|
board = esp32dev
|
||||||
|
lib_deps = hwspeedy/DHT-Sensor, knolleary/PubSubClient, adafruit/RTClib
|
||||||
429
src/esp32-ntp-clock.ino
Normal file
429
src/esp32-ntp-clock.ino
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
// ============================================================================
|
||||||
|
// Sistema de monitoramento de cozinha com ESP32
|
||||||
|
// Monitora temperatura, umidade e gás com detecção avançada de incêndio
|
||||||
|
// Envia dados via MQTT e controla coifa e ar-condicionado
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// INCLUDES
|
||||||
|
#include <DHT.h> // Sensor DHT22
|
||||||
|
#include <PubSubClient.h> // MQTT
|
||||||
|
#include <RTClib.h> // RTC DS1307
|
||||||
|
#include <WiFi.h> // WiFi
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// DEFINES - Pinos GPIO
|
||||||
|
// ============================================================================
|
||||||
|
#define DHTPIN 32 // Sensor DHT22 (temperatura/umidade)
|
||||||
|
#define DHTTYPE DHT22 // Tipo sensor DHT
|
||||||
|
#define MQ2PIN 33 // Sensor MQ2 (qualidade do ar/gás)
|
||||||
|
#define ALARME_SONORO 4 // Alarme sonoro
|
||||||
|
#define COIFA 17 // Coifa (exaustor)
|
||||||
|
#define AR_CONDICIONADO 16 // Ar-condicionado
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ENUMS
|
||||||
|
// ============================================================================
|
||||||
|
enum statusCozinha {
|
||||||
|
NOMINAL, // Sem alerta
|
||||||
|
GAS, // Detecção de gás
|
||||||
|
TEMP_ALTA, // Temperatura acima do limite
|
||||||
|
UMIDADE_ALTA, // Umidade acima do limite
|
||||||
|
INCENDIO // Possível incêndio (padrão: ΔT > 5°C + Δumidade < -10% em 30s)
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CONSTANTES - Limiares de alarme
|
||||||
|
// ============================================================================
|
||||||
|
const int GAS_ON = 940; // Ativação gás (~1000ppm)
|
||||||
|
const int GAS_OFF = 916; // Desativação gás (~500ppm)
|
||||||
|
const float TEMP_ON_DEFAULT = 30.0; // Temperatura máxima padrão (°C)
|
||||||
|
const float TEMP_HISTERESE = 2.0; // Histerese temperatura
|
||||||
|
const float UMIDADE_ON_DEFAULT = 70.0; // Umidade máxima padrão (%)
|
||||||
|
const float UMIDADE_HISTERESE = 5.0; // Histerese umidade
|
||||||
|
|
||||||
|
// Detecção de incêndio
|
||||||
|
const uint32_t JANELA_TEMPO_INCENDIO = 30; // Janela: 30 segundos
|
||||||
|
const float DELTA_TEMP_INCENDIO = 5.0; // Aumento mínimo: 5°C
|
||||||
|
const float DELTA_UMIDADE_INCENDIO = -10.0; // Queda mínima: -10%
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CONSTANTES - WiFi e MQTT
|
||||||
|
// ============================================================================
|
||||||
|
const char* WIFI_SSID = "Wokwi-GUEST";
|
||||||
|
const char* WIFI_PASSWORD = "";
|
||||||
|
const char* MQTT_BROKER = "77.37.69.84";
|
||||||
|
const int MQTT_PORT = 1883;
|
||||||
|
const char* MQTT_SUB_TOPICS[] = { "cozinha/max_tmp", "cozinha/max_umi" };
|
||||||
|
const char* MQTT_PUB_TOPIC = "cozinha";
|
||||||
|
const int MQTT_SUB_COUNT = sizeof(MQTT_SUB_TOPICS) / sizeof(MQTT_SUB_TOPICS[0]);
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// VARIÁVEIS GLOBAIS - Objetos
|
||||||
|
// ============================================================================
|
||||||
|
DHT dht(DHTPIN, DHTTYPE);
|
||||||
|
RTC_DS1307 RTC;
|
||||||
|
WiFiClient espClient;
|
||||||
|
PubSubClient mqtt(espClient);
|
||||||
|
DateTime now;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// VARIÁVEIS GLOBAIS - Estado do sistema
|
||||||
|
// ============================================================================
|
||||||
|
int alarmStatus = NOMINAL;
|
||||||
|
float umidade = 0.0;
|
||||||
|
float temperatura = 0.0;
|
||||||
|
int iqAR = 0;
|
||||||
|
|
||||||
|
// Variáveis de configuração (atualizáveis via MQTT)
|
||||||
|
float TEMP_ON = TEMP_ON_DEFAULT;
|
||||||
|
float TEMP_OFF = TEMP_ON - TEMP_HISTERESE;
|
||||||
|
float UMIDADE_ON = UMIDADE_ON_DEFAULT;
|
||||||
|
float UMIDADE_OFF = UMIDADE_ON - UMIDADE_HISTERESE;
|
||||||
|
|
||||||
|
// Variáveis para detecção de incêndio
|
||||||
|
float temp_inicio = 0.0;
|
||||||
|
float umidade_inicio = 0.0;
|
||||||
|
uint32_t timestamp_inicio = 0;
|
||||||
|
|
||||||
|
// Buffer MQTT
|
||||||
|
char msg[256];
|
||||||
|
char MQTT_CLIENTID[32];
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// FUNÇÕES AUXILIARES - Callbacks MQTT
|
||||||
|
// ============================================================================
|
||||||
|
void mqttCallback(char* topic, byte* payload, unsigned int length)
|
||||||
|
{
|
||||||
|
Serial.print("[MQTT] Mensagem em [");
|
||||||
|
Serial.print(topic);
|
||||||
|
Serial.println("]");
|
||||||
|
|
||||||
|
// Copia payload para buffer null-terminated
|
||||||
|
char buf[64];
|
||||||
|
int n = (length < (int)sizeof(buf) - 1) ? length : (int)sizeof(buf) - 1;
|
||||||
|
memcpy(buf, payload, n);
|
||||||
|
buf[n] = '\0';
|
||||||
|
|
||||||
|
Serial.print("[MQTT] payload: ");
|
||||||
|
Serial.println(buf);
|
||||||
|
|
||||||
|
// Processa tópicos
|
||||||
|
if (strcmp(topic, "cozinha/max_tmp") == 0) {
|
||||||
|
float v = atof(buf);
|
||||||
|
if (!isnan(v)) {
|
||||||
|
TEMP_ON = v;
|
||||||
|
TEMP_OFF = TEMP_ON - TEMP_HISTERESE;
|
||||||
|
Serial.print("[MQTT] TEMP_ON = ");
|
||||||
|
Serial.println(TEMP_ON);
|
||||||
|
}
|
||||||
|
} else if (strcmp(topic, "cozinha/max_umi") == 0) {
|
||||||
|
float v = atof(buf);
|
||||||
|
if (!isnan(v)) {
|
||||||
|
UMIDADE_ON = v;
|
||||||
|
UMIDADE_OFF = UMIDADE_ON - UMIDADE_HISTERESE;
|
||||||
|
Serial.print("[MQTT] UMIDADE_ON = ");
|
||||||
|
Serial.println(UMIDADE_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// FUNÇÕES AUXILIARES - Conectividade
|
||||||
|
// ============================================================================
|
||||||
|
// Conecta o ESP32 à rede WiFi
|
||||||
|
void connectWiFi()
|
||||||
|
{
|
||||||
|
Serial.print("[WiFi] Conectando...");
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
int attempts = 0;
|
||||||
|
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
Serial.println("\r\n[WiFi] Conectado!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inscreve em tópicos MQTT para receber atualizações de limiares
|
||||||
|
void mqttSubscribe()
|
||||||
|
{
|
||||||
|
Serial.println("[MQTT] Conectado!");
|
||||||
|
for (int i = 0; i < MQTT_SUB_COUNT; ++i) {
|
||||||
|
if (mqtt.subscribe(MQTT_SUB_TOPICS[i])) {
|
||||||
|
Serial.print("[MQTT] Tópico: ");
|
||||||
|
Serial.println(MQTT_SUB_TOPICS[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conecta ao broker MQTT
|
||||||
|
void connectMQTT()
|
||||||
|
{
|
||||||
|
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
|
||||||
|
mqtt.setCallback(mqttCallback);
|
||||||
|
|
||||||
|
while (!mqtt.connected()) {
|
||||||
|
Serial.println("[MQTT] Conectando...");
|
||||||
|
if (mqtt.connect(MQTT_CLIENTID)) {
|
||||||
|
mqttSubscribe();
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
Serial.print("[MQTT] Falha rc=");
|
||||||
|
Serial.println(mqtt.state());
|
||||||
|
delay(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// FUNÇÕES AUXILIARES - Sensores
|
||||||
|
// ============================================================================
|
||||||
|
// Lê valores de temperatura e umidade do sensor DHT22
|
||||||
|
void read_DHT()
|
||||||
|
{
|
||||||
|
umidade = dht.readHumidity();
|
||||||
|
temperatura = dht.readTemperature();
|
||||||
|
|
||||||
|
if (isnan(umidade) || isnan(temperatura)) {
|
||||||
|
Serial.println("[DHT] Erro na leitura!");
|
||||||
|
umidade = 0.0;
|
||||||
|
temperatura = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_MQ2()
|
||||||
|
{
|
||||||
|
iqAR = analogRead(MQ2PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// FUNÇÕES - Detecção de alarmes
|
||||||
|
// ============================================================================
|
||||||
|
// Detecta padrão de possível incêndio: aumento de temperatura > 5°C + queda de umidade > 10% em 30 segundos
|
||||||
|
void detect_fire()
|
||||||
|
{
|
||||||
|
// Inicializa janela de monitoramento na primeira chamada
|
||||||
|
if (temp_inicio == 0.0) {
|
||||||
|
temp_inicio = temperatura;
|
||||||
|
umidade_inicio = umidade;
|
||||||
|
timestamp_inicio = now.secondstime();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calcula tempo decorrido
|
||||||
|
uint32_t tempo_decorrido = now.secondstime() - timestamp_inicio;
|
||||||
|
|
||||||
|
// Verifica padrão de incêndio a cada 30 segundos
|
||||||
|
if (tempo_decorrido >= JANELA_TEMPO_INCENDIO) {
|
||||||
|
float delta_temp = temperatura - temp_inicio;
|
||||||
|
float delta_umidade = umidade - umidade_inicio;
|
||||||
|
|
||||||
|
// Debug: exibe deltas
|
||||||
|
Serial.print("[INCENDIO] ΔT: ");
|
||||||
|
Serial.print(delta_temp);
|
||||||
|
Serial.print("°C | ΔUmidade: ");
|
||||||
|
Serial.print(delta_umidade);
|
||||||
|
Serial.println("%");
|
||||||
|
|
||||||
|
// Verifica condições críticas
|
||||||
|
if (delta_temp > DELTA_TEMP_INCENDIO && delta_umidade < DELTA_UMIDADE_INCENDIO) {
|
||||||
|
Serial.println("[ALERTA] INCÊNDIO DETECTADO!");
|
||||||
|
alarmStatus = INCENDIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reseta janela
|
||||||
|
temp_inicio = temperatura;
|
||||||
|
umidade_inicio = umidade;
|
||||||
|
timestamp_inicio = now.secondstime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica qual alarme deve ser ativado baseado nos limites
|
||||||
|
void check_alarm()
|
||||||
|
{
|
||||||
|
// Atualiza RTC
|
||||||
|
now = RTC.now();
|
||||||
|
|
||||||
|
// Detecção de incêndio (máxima prioridade)
|
||||||
|
detect_fire();
|
||||||
|
if (alarmStatus == INCENDIO) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica gás
|
||||||
|
if (alarmStatus == GAS) {
|
||||||
|
if (iqAR <= GAS_OFF) {
|
||||||
|
alarmStatus = NOMINAL;
|
||||||
|
}
|
||||||
|
} else if (iqAR > GAS_ON) {
|
||||||
|
alarmStatus = GAS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica umidade
|
||||||
|
if (alarmStatus == UMIDADE_ALTA) {
|
||||||
|
if (umidade <= UMIDADE_OFF) {
|
||||||
|
alarmStatus = NOMINAL;
|
||||||
|
}
|
||||||
|
} else if (umidade > UMIDADE_ON) {
|
||||||
|
alarmStatus = UMIDADE_ALTA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica temperatura
|
||||||
|
if (alarmStatus == TEMP_ALTA) {
|
||||||
|
if (temperatura <= TEMP_OFF) {
|
||||||
|
alarmStatus = NOMINAL;
|
||||||
|
}
|
||||||
|
} else if (temperatura > TEMP_ON) {
|
||||||
|
alarmStatus = TEMP_ALTA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nenhum alarme ativo
|
||||||
|
if (alarmStatus != GAS && alarmStatus != UMIDADE_ALTA
|
||||||
|
&& alarmStatus != TEMP_ALTA) {
|
||||||
|
alarmStatus = NOMINAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// FUNÇÕES - Leitura e publicação
|
||||||
|
// ============================================================================
|
||||||
|
// Realiza leitura de todos os sensores e publica dados via MQTT
|
||||||
|
void leitura_sensores()
|
||||||
|
{
|
||||||
|
read_DHT();
|
||||||
|
read_MQ2();
|
||||||
|
|
||||||
|
// Formata e publica via MQTT
|
||||||
|
snprintf(msg, sizeof(msg),
|
||||||
|
"{\"tmp\": %.2f, \"umi\": %.2f, \"gas\": %d, \"alarme\": %d}",
|
||||||
|
temperatura, umidade, iqAR, alarmStatus);
|
||||||
|
Serial.print("[MQTT] Publicando: ");
|
||||||
|
Serial.println(msg);
|
||||||
|
mqtt.publish(MQTT_PUB_TOPIC, msg);
|
||||||
|
|
||||||
|
// Verifica alarmes
|
||||||
|
check_alarm();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processa ativação de periféricos baseado no alarme
|
||||||
|
void processa_alarme()
|
||||||
|
{
|
||||||
|
// Desativa todos antes de processar
|
||||||
|
digitalWrite(ALARME_SONORO, LOW);
|
||||||
|
digitalWrite(COIFA, LOW);
|
||||||
|
digitalWrite(AR_CONDICIONADO, LOW);
|
||||||
|
|
||||||
|
if (alarmStatus == NOMINAL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ativa periféricos conforme alarme
|
||||||
|
switch (alarmStatus) {
|
||||||
|
case INCENDIO:
|
||||||
|
digitalWrite(ALARME_SONORO, HIGH);
|
||||||
|
digitalWrite(COIFA, HIGH);
|
||||||
|
digitalWrite(AR_CONDICIONADO, HIGH);
|
||||||
|
Serial.println("[ALARME] INCÊNDIO!");
|
||||||
|
break;
|
||||||
|
case GAS:
|
||||||
|
digitalWrite(ALARME_SONORO, HIGH);
|
||||||
|
digitalWrite(COIFA, HIGH);
|
||||||
|
Serial.println("[ALARME] GÁS DETECTADO!");
|
||||||
|
break;
|
||||||
|
case UMIDADE_ALTA:
|
||||||
|
digitalWrite(COIFA, HIGH);
|
||||||
|
Serial.println("[ALARME] UMIDADE ALTA!");
|
||||||
|
break;
|
||||||
|
case TEMP_ALTA:
|
||||||
|
digitalWrite(AR_CONDICIONADO, HIGH);
|
||||||
|
Serial.println("[ALARME] TEMPERATURA ALTA!");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// FUNÇÕES - Inicialização
|
||||||
|
// ============================================================================
|
||||||
|
void rtc_setup()
|
||||||
|
{
|
||||||
|
if (!RTC.begin()) {
|
||||||
|
Serial.println("[RTC] Erro: não encontrado!");
|
||||||
|
while (1)
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
Serial.println("[RTC] Inicializado");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicializa o ESP32 e configura os periféricos
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
Serial.println("\n[SETUP] Iniciando sistema...");
|
||||||
|
|
||||||
|
// Inicializa DHT
|
||||||
|
dht.begin();
|
||||||
|
Serial.println("[DHT] Inicializado");
|
||||||
|
|
||||||
|
// Gera ID único MQTT
|
||||||
|
snprintf(MQTT_CLIENTID, sizeof(MQTT_CLIENTID), "esp32_%08X",
|
||||||
|
(uint32_t)(ESP.getEfuseMac() & 0xFFFFFFFF));
|
||||||
|
|
||||||
|
// Configura ADC
|
||||||
|
analogReadResolution(10);
|
||||||
|
|
||||||
|
// Configura pinos
|
||||||
|
pinMode(ALARME_SONORO, OUTPUT);
|
||||||
|
pinMode(COIFA, OUTPUT);
|
||||||
|
pinMode(AR_CONDICIONADO, OUTPUT);
|
||||||
|
pinMode(MQ2PIN, INPUT);
|
||||||
|
pinMode(DHTPIN, INPUT);
|
||||||
|
|
||||||
|
// Desativa todos os atuadores
|
||||||
|
digitalWrite(ALARME_SONORO, LOW);
|
||||||
|
digitalWrite(COIFA, LOW);
|
||||||
|
digitalWrite(AR_CONDICIONADO, LOW);
|
||||||
|
|
||||||
|
// Conecta
|
||||||
|
connectWiFi();
|
||||||
|
connectMQTT();
|
||||||
|
rtc_setup();
|
||||||
|
|
||||||
|
// Primeira leitura
|
||||||
|
now = RTC.now();
|
||||||
|
leitura_sensores();
|
||||||
|
|
||||||
|
Serial.println("[SETUP] Pronto!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// LOOP PRINCIPAL
|
||||||
|
// ============================================================================
|
||||||
|
// Loop principal - executa continuamente
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// Verifica MQTT
|
||||||
|
if (!mqtt.connected()) {
|
||||||
|
connectMQTT();
|
||||||
|
}
|
||||||
|
mqtt.loop();
|
||||||
|
|
||||||
|
// Lê sensores
|
||||||
|
leitura_sensores();
|
||||||
|
|
||||||
|
// Processa alarme
|
||||||
|
processa_alarme();
|
||||||
|
|
||||||
|
// Aguarda 2 segundos
|
||||||
|
unsigned long start = millis();
|
||||||
|
while (millis() - start < 2000UL) {
|
||||||
|
mqtt.loop();
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
wokwi.toml
Normal file
4
wokwi.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[wokwi]
|
||||||
|
version = 1
|
||||||
|
elf = ".pio/build/esp32/firmware.elf"
|
||||||
|
firmware = ".pio/build/esp32/firmware.bin"
|
||||||
Reference in New Issue
Block a user