What is the DHT11 & DHT22?
The DHT11 (blue) and the DHT22 (white, also sold as the AM2302) are the two temperature and humidity sensors almost every maker meets first. They share the same pinout, the same single data wire, the same library and the same code: change one line, DHTTYPE, and a sketch written for one runs on the other.
What differs is the quality of the numbers. The DHT11 is cheap and coarse: whole degrees, ±2 °C, and nothing below 0 °C. The DHT22 costs a little more and returns tenths of a degree, ±0.5 °C, and reaches down to −40 °C. This page explains both side by side: what is inside, every pin, how the single-wire protocol works (with a decoded frame for each sensor), which one to buy, and how to avoid the classic NaN readings. When you are ready to build, the Arduino Uno guide and the ESP32 guide take you from wiring to working projects for either sensor.
Specifications
| Parameter | DHT11 | DHT22 / AM2302 |
|---|---|---|
| Supply voltage | 3.3 to 5.5 V DC | 3.3 to 5.5 V DC (older datasheets quote up to 6 V) |
| Temperature range | 0 to 50 °C | −40 to 80 °C |
| Temperature accuracy | ±2 °C | ±0.5 °C |
| Temperature resolution | 1 °C (newer revisions also report tenths) | 0.1 °C |
| Humidity range | 20 to 90 %RH (newer ASAIR revisions quote 5 to 95 %RH) | 0 to 99.9 %RH (normal working scope 0 to 80 %RH) |
| Humidity accuracy | ±5 %RH | ±2 %RH typical, ±5 %RH max at the extremes |
| Humidity resolution | 1 %RH | 0.1 %RH |
| Sampling period | 1 to 2 s depending on revision; plan on 2 s | 2 s minimum |
| Humidity element | Resistive | Capacitive polymer film |
| Interface | Single-wire, bidirectional (not Dallas 1-Wire) | Same protocol, different data format |
| Supply current | About 0.3 mA measuring (up to 2.5 mA in some revisions), about 60 µA idle | About 1 to 1.5 mA measuring, about 40 to 50 µA idle |
| Body | Blue grille, about 15.5 × 12 × 5.5 mm | White grille, about 25 × 15 × 7.7 mm; the AM2302 is the cased version with three wires |
Swipe sideways to see every column →
Figures from the Aosong (ASAIR) DHT11 datasheet and AM2302 technical manual. Cheap clones can be noticeably less accurate, and current figures vary between datasheet revisions, so budget for the higher number.
Pinout
| Pin | Name | Description |
|---|---|---|
| 1 | VCC | Power, 3.3 to 5.5 V for both sensors. Use the same voltage as your microcontroller's logic (3.3 V for an ESP32). |
| 2 | DATA | Bidirectional data line. Needs a pull-up resistor to VCC (built into most 3-pin modules). |
| 3 | NC | Not connected. Leave it unwired. |
| 4 | GND | Ground, shared with the microcontroller. |
Swipe sideways to see every column →
The DHT11 and DHT22 share this pin order. Pins are numbered left to right with the grille facing you and the legs pointing down. On 3-pin modules the order is printed on the board and varies between sellers.
Wiring & code
Setting up DHT11 & DHT22 with ESP32
Library
DHT sensor library by Adafruit
Arduino IDE > Sketch > Include Library > Manage Libraries > search "DHT sensor library" > install "DHT sensor library" by Adafruit (accept "Adafruit Unified Sensor" when asked)
This guide connects a DHT11 or DHT22 to an ESP32 and takes it from Serial Monitor readings to four Wi-Fi projects: a live web page, a JSON endpoint for Node-RED or Home Assistant, a chart of the last hour on your phone, and a battery-powered outdoor sensor that deep-sleeps between readings. One line, DHTTYPE, selects the sensor. The ESP32 is a 3.3 V board, so there is one wiring rule the Uno guide does not have: power the sensor from 3V3, never from 5V.
What you need
| Qty | Part | Notes |
|---|---|---|
| 1 | ESP32 DevKit (30- or 38-pin) | ESP32-S3 and C3 boards work too; only the pin number changes |
| 1 | DHT11 or DHT22 (AM2302) | Module or bare sensor; the DHT22 is the better pick for Sketches 3 and 4 |
| 1 | 10 kΩ resistor | Only for the bare 4-pin sensor (DATA to 3V3) |
| 1 | Breadboard and jumper wires | A wide breadboard or two half boards fit the DevKit best |
| 1 | USB cable with data lines | Charge-only cables are the most common upload failure |
Swipe sideways to see every column →
Wiring
| DHT pin | ESP32 pin | Notes |
|---|---|---|
| VCC (+) | 3V3 | Not VIN or 5V: the data line is pulled up to VCC and ESP32 pins are not 5 V tolerant |
| DATA (S / OUT) | GPIO 4 | Any free bidirectional GPIO; avoid the pins listed below |
| NC | — | Bare sensor only. Leave unconnected |
| GND (−) | GND | Shared ground |
Swipe sideways to see every column →
Which GPIO? GPIO 4 is a safe default. Avoid:
- GPIO 34 to 39 - input-only. The DHT protocol needs the pin to drive the line low for the start signal.
- GPIO 6 to 11 - wired to the module's flash chip. Using them crashes the board.
- GPIO 0, 2, 12 and 15 - strapping pins read at boot. A pull-up on them can stop the board booting or uploading.
Good alternatives are GPIO 13, 14, 16, 17, 25, 26, 27 and 32.
Warning
A 3-pin module powered from 5V pulls DATA up to 5 V through its built-in resistor, which is above the ESP32's 3.6 V absolute maximum. It may work for a while and then damage the GPIO. Always power the module from 3V3.
Install the library and the board
- 1If the ESP32 is not in your Arduino IDE yet: open Tools > Board > Boards Manager, search for esp32 and install 'esp32 by Espressif Systems'.
- 2Open Sketch > Include Library > Manage Libraries, search for "DHT sensor library" and install the one by Adafruit. Choose Install All so "Adafruit Unified Sensor" comes too.
- 3Select Tools > Board > esp32 > ESP32 Dev Module (or your exact board) and choose its port under Tools > Port.
Tip
If the upload stalls at 'Connecting...', hold the BOOT button on the DevKit until the upload starts. Many boards do this automatically; some clones do not.
Sketch 1 - Read temperature and humidity
The same sketch as on the Uno, with two changes: the data pin is GPIO 4, and the Serial Monitor runs at 115200 baud, which is the ESP32 default.
A DHT22 shows real tenths; a DHT22 that only ever shows .0 is usually still set to DHTTYPE DHT11. Breathe on the sensor and watch humidity rise. If you see an occasional Failed to read, that is normal on the ESP32: Wi-Fi and the second core can interrupt the microsecond timing. The sketch simply retries on the next loop. If every read fails, check the wiring table and the GPIO list above.
Tip
**Line by line** the sketch is identical to the Uno version; only the pin (GPIO 4) and the baud rate (115200) change. The [Uno guide](/sensors/dht11-dht22/arduino-uno) has a table that explains every line.
Sketch 2 - A live web page over Wi-Fi
This is where the ESP32 earns its place. The sketch joins your Wi-Fi, reads the sensor every two seconds in the background, and serves a small page that refreshes itself every five seconds. Open the IP address it prints from any phone or laptop on the same network.
Tip
The ESP32 only joins 2.4 GHz Wi-Fi. If it never connects, check that your router broadcasts a 2.4 GHz network and that the name and password are typed exactly, including capital letters.
How it works. updateReading() uses a millis() timer instead of delay(), so the ESP32 keeps answering web requests while it waits between sensor reads. A failed read keeps the previous good value, so a single bad frame never shows up on the page. From here it is a small step to publish the same numbers over MQTT to Home Assistant or Node-RED.
Add a JSON endpoint for Node-RED, Home Assistant or a script
A web page is for people. Software prefers JSON. Add this handler to Sketch 2 and register it next to the page, and any tool on your network can poll http://<ESP32-IP>/json:
Opening it in a browser shows something like {"temperature_c":24.0,"humidity":55.0,"age_ms":1312}. The age_ms field tells the client how old the reading is, so a stalled sensor is easy to spot, and the 503 status before the first good read lets a client tell "no data yet" from a real 0 °C. To have the ESP32 push readings instead of being polled, see ESP32 MQTT temperature sensor for Home Assistant or the Node-RED ESP32 dashboard.
Sketch 3 - A live chart of the last hour
A single number tells you what the air is doing now. A chart tells you what it has been doing: whether the room is still warming up, how fast an open window cools it, how long a shower's humidity lingers. The ESP32 keeps the last 120 readings (one every 30 seconds, so one hour) in memory, serves them as JSON on /data, and the page draws them as two small charts that refresh every 30 seconds. No cloud account or extra library is needed. A DHT22 draws smooth curves; a DHT11 draws steps of a whole degree.
How it works. sample() stores a reading every 30 seconds in two ring buffers, overwriting the oldest once 120 are stored, so memory use never grows. /data returns them oldest first, and the page's JavaScript scales each series to its own minimum and maximum, so even a 0.3 °C drift is visible. The chart starts empty after a reset; for days of history, push readings to a database such as InfluxDB and Grafana via Node-RED, or stream them with WebSockets.
Sketch 4 - Battery outdoor sensor with deep sleep (DHT22)
Outdoors, the DHT22's −40 °C floor finally matters (a DHT11 stops at 0 °C), but a board running Wi-Fi all day empties a battery in hours. This sketch does the job in a few seconds per wake-up: power the sensor, wait for it to settle, read with retries, remember the day's minimum and maximum in RTC memory, then deep-sleep for 10 minutes.
The sensor's VCC comes from GPIO 25 instead of 3V3, so it draws nothing while the ESP32 sleeps. A DHT22 needs about 1.5 mA, well within what a GPIO can supply.
Wiring for Sketch 4
| DHT22 pin | ESP32 pin | Notes |
|---|---|---|
| VCC (+) | GPIO 25 | Switched supply: HIGH while reading, LOW while asleep |
| DATA (S / OUT) | GPIO 4 | Bare sensor: 10 kΩ pull-up from DATA to GPIO 25, so it is unpowered too |
| GND (−) | GND | Shared ground |
Swipe sideways to see every column →
What battery life to expect. The ESP32 chip sleeps at about 10 µA, but a typical DevKit board draws several milliamps asleep because of its USB-serial chip, LED and voltage regulator. On a DevKit, an 18650 cell lasts days to a couple of weeks; on a bare module or a low-power board with an efficient regulator, the same code can run for months. The ESP32 deep sleep battery life guide shows how to estimate it.
Mounting outdoors. Sun on the plastic grille can make it read 10 °C high, and rain kills the sensor. Mount it in a radiation shield (stacked white plates, open at the sides), about 1.5 m above grass and away from walls. Keep the ESP32 and battery below the sensor or outside the shield, so their warmth does not rise into it.
Troubleshooting on the ESP32
ESP32-specific problems
| Symptom | Likely cause | Fix |
|---|---|---|
| Every read fails | DATA on an input-only pin (34 to 39), wrong DHTPIN, or no pull-up on a bare sensor | Move DATA to GPIO 4 and set DHTPIN 4; add 10 kΩ from DATA to 3V3 on bare sensors |
| Board will not boot or upload after wiring | DATA connected to a strapping pin (0, 2, 12 or 15) | Move the wire to GPIO 4 |
| Frequent random failures once Wi-Fi is on | Wi-Fi interrupts disturbing the bit timing | Read every 2 s or slower and keep the last good value, as in Sketch 2; keep the sensor wire short |
| Readings drift upward after a few minutes | The ESP32 and its regulator warm the air around the sensor | Mount the sensor on a 10 to 20 cm cable away from the board |
| Brownout detector was triggered | Weak USB port or cable while Wi-Fi starts | Use a better cable or a powered hub, and add a 10 µF to 100 µF capacitor across 3V3 and GND |
| Humidity over 1,000 %, or tiny values | DHTTYPE does not match the sensor | DHT11 is the blue one, DHT22 / AM2302 the white one; set DHTTYPE accordingly |
| Sketch 4 always reports no answer | The sensor is read before it has settled, or its VCC is not on GPIO 25 | Keep the 2 s delay after powering it, and check the VCC wire goes to the GPIO set as SENSOR_POWER |
Swipe sideways to see every column →
ESP32 FAQ
Can I use the DHTesp library instead? Yes. DHTesp by beegee_tokyo is written for the ESP32 and ESP8266 and handles both sensors; some people find it more reliable with Wi-Fi active. The wiring is identical; only the code changes.
Does this work on the ESP32-C3 or ESP32-S3? Yes. Pick a free GPIO that is not a strapping or flash pin on your board, update DHTPIN, and select the right board in the IDE.
Can I run it on a battery? Yes: Sketch 4 is built for it. Power the sensor from a GPIO so it sleeps too, and choose a board with a low sleep current.
Can I use MicroPython instead of Arduino?
Yes. MicroPython's built-in dht module reads either sensor in a few lines; see DHT11 and DHT22 with MicroPython.
Why not power it from 5 V for longer cables? Because the pull-up would then raise the data line to 5 V. If you need a long cable, use the bare sensor with its pull-up to 3.3 V, or a small level shifter.
Where next? Send the readings to Home Assistant with ESP32 MQTT temperature sensor, graph them in the Node-RED ESP32 dashboard, try the MicroPython DHT22 web server, or compare with the Arduino Uno guide.







