Driver DHT22 implementado em C puro para Arduino Uno, sem bibliotecas externas — protocolo 1-Wire com decodificação manual de timing, comunicação I²C via registradores diretos e alarme sonoro com lógica de histerese.
Monitor de temperatura e umidade em tempo real com alarme sonoro, desenvolvido para Arduino Uno. O objetivo principal é implementar todos os protocolos de comunicação do zero — sem nenhuma biblioteca pronta — entendendo cada bit transmitido entre o microcontrolador e os periféricos.
Por que sem bibliotecas? Em sistemas embarcados industriais, depender de bibliotecas de terceiros é um risco: elas podem não existir para o hardware alvo, conter bugs ocultos ou consumir recursos desnecessários. Implementar do zero garante controle total, código auditável e conhecimento profundo do hardware — requisito em ambientes críticos como defesa, aeroespacial e automação industrial.
- Entender o protocolo 1-Wire do DHT22 em nível de bit e timing
- Implementar comunicação I²C via registradores TWI do ATmega328P (TWCR, TWDR, TWBR)
- Aplicar lógica de histerese para controle de alarme sem chattering
- Manipular registradores DDRx / PORTx / PINx diretamente para GPIO
- Adicionar log de dados em memória EEPROM
| Componente | Descrição |
|---|---|
| Arduino Uno | Microcontrolador ATmega328P — 16MHz, 32KB Flash |
| Sensor DHT22 | Temperatura (−40°C a +80°C) e umidade (0–100%), protocolo 1-Wire |
| LCD 16x2 I²C | Display com módulo PCF8574, endereço padrão 0x27 |
| Buzzer passivo | Alarme sonoro controlado por PWM via Timer1 |
| Resistor 10kΩ | Pull-up do pino de dados do DHT22 |
Simulador: Wokwi — circuito simulado antes de montar fisicamente.
Arduino Uno
|
├── D2 ────────── DHT22 (DATA) + resistor 10kΩ pull-up para VCC
├── D9 ────────── Buzzer (positivo)
├── A4 (SDA) ───── LCD I²C (SDA)
├── A5 (SCL) ───── LCD I²C (SCL)
├── 5V ────────── VCC (DHT22, LCD, Buzzer)
└── GND ────────── GND (todos os componentes)
monitor-temperatura-embarcado/
├── src/
│ ├── main.ino # Loop principal e inicialização
│ ├── dht22.h # Interface do driver DHT22
│ ├── dht22.c # Protocolo 1-Wire — decodificação manual de pulsos
│ ├── i2c.h # Interface I²C
│ ├── i2c.c # Implementação TWI via registradores do ATmega328P
│ ├── lcd_i2c.h # Interface do display LCD
│ ├── lcd_i2c.c # Driver LCD via I²C sem Wire.h
│ ├── alarme.h # Interface do módulo de alarme
│ └── alarme.c # Histerese + controle do buzzer via Timer1
├── docs/
│ ├── timing_dht22.png # Diagrama de timing do protocolo 1-Wire
│ └── schematic.png # Esquemático do circuito
└── README.md
O DHT22 usa um protocolo proprietário de fio único sem clock externo. O MCU puxa o pino LOW por 1ms para acordar o sensor, que responde com handshake de 80µs+80µs. Em seguida transmite 40 bits onde a duração do pulso HIGH determina o valor: ~28µs = bit 0, ~70µs = bit 1. A decodificação é feita medindo o estado do pino após 40µs do início do HIGH. Os 40 bits carregam umidade (16 bits), temperatura (16 bits) e checksum CRC (8 bits) para validação de integridade.
Implementação manual do protocolo I²C usando diretamente os registradores TWCR (controle), TWDR (dado), TWBR (bit rate) e TWSR (status) do ATmega328P, sem uso da biblioteca Wire.h. Cobre geração de START/STOP conditions, envio de endereço com bit R/W e transmissão de bytes com verificação de ACK/NACK.
O alarme usa dois limiares distintos para evitar chattering: liga ao atingir 30°C e só desliga abaixo de 28°C (banda morta de 2°C configurável). Conceito fundamental em sistemas de controle industrial como termostatos, pressostatos e controladores PID em ambientes OT.
- Acesse o projeto no Wokwi: [link em breve]
- Clique em Play — nenhuma instalação necessária
# 1. Clone o repositório
git clone https://github.com/[SEU_USUARIO]/monitor-temperatura-embarcado.git
# 2. Abra src/main.ino no Arduino IDE
# 3. Tools > Board > Arduino Uno
# 4. Selecione a porta COM correta
# 5. Upload (Ctrl+U)TEMP:28.5,UMID:65.3
TEMP:29.1,UMID:64.8
TEMP:30.2,UMID:64.1 ← ALARME LIGOU
TEMP:30.5,UMID:63.9
TEMP:29.8,UMID:64.2 ← zona morta (histerese ativa)
TEMP:27.9,UMID:64.5 ← ALARME DESLIGOU
| Teste | Resultado esperado | Status |
|---|---|---|
| Leitura normal do DHT22 | Temperatura e umidade corretas | ✅ Passou |
| Checksum inválido | Retorna erro sem travar o sistema | ✅ Passou |
| Timeout de sensor desconectado | Sistema continua operando | ✅ Passou |
| Alarme acima de 30°C | Buzzer aciona imediatamente | ✅ Passou |
| Histerese na descida | Alarme desliga apenas abaixo de 28°C | ✅ Passou |
| Chattering na faixa limiar | Sem oscilações indevidas | ✅ Passou |
- Implementar 1-Wire na mão deixou claro por que sistemas embarcados críticos precisam de timing determinístico — um
delay()no lugar errado corrompe toda a leitura - Escrever diretamente nos registradores TWI revelou o que a biblioteca Wire.h abstrai: geração de clock, arbitragem do barramento e tratamento de ACK/NACK byte a byte
- Debugar o chattering do alarme no simulador antes do hardware físico economizou horas — a histerese resolve um problema real que só aparece quando o sensor está na faixa limiar
- A separação em módulos (dht22, i2c, lcd, alarme) torna o código auditável e reutilizável — prática padrão em firmware industrial
Estudante de ADS | Sistemas Embarcados & OT Security | Guarulhos, SP