DHT11 & DHT22 Digital Temperature & Humidity Sensor
Complete engineering manual covering physical operating principles, pinout architecture, circuit schematics, non-blocking Arduino/ESP32 code, and troubleshooting.

What are DHT11 and DHT22 Sensors?
The DHT11 and DHT22 (AM2302) are basic composite digital sensors designed for measuring relative humidity (RH) and ambient temperature. They combine a capacitive humidity sensing element, an NTC thermistor for temperature measurement, and an internal 8-bit microcontroller that performs analog calibration and serializes data packets.
Unlike standard analog thermistors or LM35 sensors that require analog-to-digital conversions on the host microcontroller, DHT sensors transmit calibrated, pre-compensated 40-bit digital frames across a single bidirectional digital data line using a custom single-wire handshake protocol.
Key Technical Specifications
Relative Humidity Range
Measures 20% to 90% RH (DHT11, ±5% accuracy) or 0% to 100% RH (DHT22, ±2% accuracy).
Temperature Range
Senses 0°C to 50°C (DHT11, ±2°C) or -40°C to 80°C (DHT22, ±0.5°C high precision).
Single-Wire Digital Bus
Transmits all telemetry over a single GPIO pin, conserving microcontroller pins.
3.3V & 5V Compatibility
Operates reliably from 3.3V to 5.5V DC, directly compatible with Arduino, ESP32, and Raspberry Pi.
Sampling Rate Limit
Requires 1 Hz (DHT11) or 0.5 Hz (DHT22) polling interval to prevent sensor self-heating.
Checksum Verification
Includes an 8-bit parity checksum in every packet to detect transmission bit errors.
Components Required
| Component | Quantity | Engineering Purpose |
|---|---|---|
| DHT11 & DHT22 Digital Module | 1x | Primary physical environmental sensing module |
| Arduino Uno R3 or ESP32 DevKit | 1x | Microcontroller for ADC sampling and digital processing |
| Solderless Breadboard (830 tie-points) | 1x | Prototyping circuit layout and common power rail distribution |
| Jumper Wires (Male-to-Male, Male-to-Female) | 6x | Interconnecting microcontroller GPIO, power, and ground |
| Decoupling Capacitor (100nF Ceramic) | 1x | Filtering power rail high-frequency switching transient noise |
| Pull-up / Current Limiting Resistor (10kΩ / 220Ω) | 1x | Level conditioning and bus stability |
Pin Configuration & Connection Diagram
VCC
3.3V to 5.5V DC power supply line. Connect to microcontroller regulated power.
DATA
Single-wire bidirectional digital data line. Requires an external 4.7kΩ–10kΩ pull-up resistor.
NC
No Connection pin present on 4-pin raw sensor packages (omit or leave disconnected).
GND
Common 0V ground return reference.
| Sensor Pin | Arduino Uno | ESP32 Node | Signal Description |
|---|---|---|---|
| VCC (Pin 1) | 5V or 3.3V | 3.3V | Power supply rail. Add 100nF ceramic decoupling capacitor across VCC and GND. |
| DATA (Pin 2) | Digital Pin 2 | GPIO 4 | Bidirectional data line. Connect a 4.7kΩ pull-up resistor between DATA and VCC. |
| NC (Pin 3) | Not Connected | Not Connected | Unused internal pin on 4-pin DHT packages. |
| GND (Pin 4) | GND | GND | Common electrical ground. |
Electrical Best Practices & Noise Mitigation:
- When wiring the DHT11 & DHT22 Digital, ensure power leads are kept short to minimize stray loop inductance and inductive bounce during rapid current draw changes.
- If using an analog sensor output with a 3.3V microcontroller like an ESP32 or STM32, verify the maximum sensor output does not exceed 3.3V. If operating from a 5V supply, insert a 2:1 resistive voltage divider (e.g. 2kΩ / 1kΩ) on the signal line.
- Place a 100nF ceramic capacitor across the sensor VCC and GND pins as close to the module package as physically possible to shunt high-frequency ripple generated by nearby motors, servos, or Wi-Fi transients.
Working Principle & Mathematical Modeling
Capacitive Transduction Physics & 40-Bit Single-Wire Protocol
The humidity-sensing element is a polymer capacitive hygrometer. A moisture-absorptive dielectric polymer film is sandwiched between two porous metal electrode layers. As ambient moisture changes, water vapor permeates into the polymer, altering its relative permittivity (dielectric constant) and varying capacitance in proportion to relative humidity.
Data transmission begins with the host MCU pulling the DATA line LOW for 18 ms to wake the sensor. The sensor responds with an 80 µs LOW followed by an 80 µs HIGH acknowledgment. The sensor then transmits 40 bits of serial data: 16 bits of humidity (integer + decimal), 16 bits of temperature, and an 8-bit checksum.
Protocol Timing & Checksum Verification Formula:
Bit "0" Encoding: 50 µs LOW followed by 26–28 µs HIGH
Bit "1" Encoding: 50 µs LOW followed by 70 µs HIGH
Checksum Formula: (Humidity_High + Humidity_Low + Temp_High + Temp_Low) & 0xFF == Checksum
Dew Point Approximation: Td ≈ T - ((100 - RH) / 5)
Note: Because timing tolerances are in microseconds (26 µs vs 70 µs), interrupts should be briefly suspended or DMA/RMT peripheral hardware used on high-speed processors.
Arduino & ESP32 Implementation Code
// Production-Grade DHT11/DHT22 Driver with Non-Blocking Timing
// Platform: Arduino / ESP32 (volt-X Lab Implementation)
#include <DHT.h>
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // Change to DHT22 for AM2302 sensor
DHT dht(DHTPIN, DHTTYPE);
const unsigned long READ_INTERVAL_MS = 2500; // 2.5s between reads (enforces DHT spec)
unsigned long lastReadTime = 0;
void setup() {
Serial.begin(115200);
dht.begin();
Serial.println(F("DHT Environmental Monitoring System Online"));
}
void loop() {
unsigned long currentMillis = millis();
// Non-blocking sampling interval check
if (currentMillis - lastReadTime >= READ_INTERVAL_MS) {
lastReadTime = currentMillis;
// Reading temperature or humidity takes about 250 milliseconds
float humidity = dht.readHumidity();
float tempC = dht.readTemperature();
float tempF = dht.readTemperature(true);
// Check if any reads failed and exit early to try again next cycle
if (isnan(humidity) || isnan(tempC) || isnan(tempF)) {
Serial.println(F("Failed to read from DHT sensor! Check pull-up resistor."));
return;
}
// Compute Heat Index (apparent felt temperature incorporating humidity)
float hic = dht.computeHeatIndex(tempC, humidity, false);
Serial.print(F("Humidity: "));
Serial.print(humidity, 1);
Serial.print(F("% | Temp: "));
Serial.print(tempC, 1);
Serial.print(F("°C ("));
Serial.print(tempF, 1);
Serial.print(F("°F) | Heat Index: "));
Serial.print(hic, 1);
Serial.println(F("°C"));
}
}Code Architecture Breakdown:
- 2.5-Second Non-Blocking Interval: Respects the internal thermal settling time of the DHT substrate, preventing sensor self-heating from corrupting humidity values.
- Float Validation Guard: `isnan()` checks verify checksum integrity before processing data, rejecting corrupted packets caused by loose jumper wires.
- Heat Index Calculation: Incorporates the Steadman equation to calculate perceived apparent environmental heat stress.
- Wide Voltage Compatibility: Library code automatically negotiates microsecond line toggles on both 8-bit AVR and 32-bit ESP32 architectures.
Real-World Engineering Applications
Smart Greenhouse Climate Control
Monitors ambient humidity and activates ventilation exhaust fans or ultrasonic mist humidifiers.
IoT Cloud Weather Station
Streams temperature and relative humidity metrics to Adafruit IO or ThingsBoard via Wi-Fi/MQTT.
Server Rack & Data Center Monitoring
Monitors computer server racks for condensation risk and dew-point threshold violations.
HVAC Dehumidifier Automation
Triggers relays to toggle domestic basement dehumidifiers when relative humidity exceeds 60%.
✅ Engineering Advantages
- Measures both temperature and humidity simultaneously on a single input GPIO pin.
- Factory pre-calibrated digital output requires zero external analog reference calibration.
- Low power consumption makes it well-suited for battery-powered environmental monitoring nodes.
⚠️ Physical Constraints & Limitations
- Slow response time: Requires 1.0 to 2.0 seconds between consecutive readings.
- Limited accuracy on the budget DHT11 (±5% RH and ±2°C error margin).
- Single-wire custom protocol is sensitive to interrupt latency and multi-threading delays on fast RTOS chips.
Diagnostic & Troubleshooting Guide
| Fault / Symptom | Probable Root Cause | Corrective Action |
|---|---|---|
| Serial monitor repeatedly outputs "Failed to read from DHT sensor" | Missing pull-up resistor between the DATA line and VCC, or wire length > 2 meters. | Add a 4.7kΩ or 10kΩ pull-up resistor between DATA and VCC rails. |
| Readings only update once every several minutes or freeze | Code is querying the sensor too rapidly, causing the internal microcontroller to lock up. | Ensure `millis()` timer delays at least 2000 ms between consecutive read commands. |
| Humidity stays locked at 99% or 1% | Water condensation has soaked the polymer dielectric layer, shorting the capacitor. | Dry the sensor in a warm, low-humidity airflow environment for 24 hours. |
Frequently Asked Questions (EE/ECE Reference)
Q: What is the technical difference between the DHT11 and the DHT22 (AM2302)?
While both sensors share the same pinout and single-wire protocol, the DHT22 is significantly more precise. The DHT11 measures 20% to 90% humidity (±5% error) and 0°C to 50°C (±2°C error). The DHT22 measures 0% to 100% humidity (±2% error) and -40°C to 80°C (±0.5°C error) with full decimal point resolution.
Q: Why is an external pull-up resistor required on the DHT data line?
The DHT uses an open-drain bidirectional bus architecture. Neither the sensor nor the microcontroller actively drives the line HIGH during idle states. An external pull-up resistor (typically 4.7kΩ to 10kΩ) is required to pull the signal line to VCC when neither device is pulling it to ground.
Q: How does the DHT 40-bit transmission protocol work?
When the MCU signals a start pulse, the DHT responds with 40 serial bits. The bits encode: Byte 1 (Humidity Integer), Byte 2 (Humidity Decimal), Byte 3 (Temperature Integer), Byte 4 (Temperature Decimal), and Byte 5 (Parity Checksum). If Byte 1 + Byte 2 + Byte 3 + Byte 4 matches Byte 5, the data is verified as error-free.
Q: Why do my DHT readings fail when running under FreeRTOS on an ESP32?
The DHT single-wire protocol requires strict microsecond-level timing (e.g., detecting a 28 µs pulse vs a 70 µs pulse). In a multi-threaded FreeRTOS environment, an interrupt or task switch can delay MCU sampling by tens of microseconds, corrupting the bit frame. Wrap the read function in a critical section or use the ESP32 hardware RMT peripheral.