Skip to content

Temperature & Humidity · ESP32 guide

Interfacing DHT11 & DHT22 Temperature and Humidity Sensors with ESP32

The two classic single-wire temperature and humidity sensors: same pins, same code, one line apart. The DHT11 is cheap and coarse; the DHT22 reads tenths of a degree and below zero.

Updated November 3, 2026 Arduino C++DHT sensor libraryAlso forArduino Uno

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

ParameterDHT11DHT22 / AM2302
Supply voltage3.3 to 5.5 V DC3.3 to 5.5 V DC (older datasheets quote up to 6 V)
Temperature range0 to 50 °C−40 to 80 °C
Temperature accuracy±2 °C±0.5 °C
Temperature resolution1 °C (newer revisions also report tenths)0.1 °C
Humidity range20 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 resolution1 %RH0.1 %RH
Sampling period1 to 2 s depending on revision; plan on 2 s2 s minimum
Humidity elementResistiveCapacitive polymer film
InterfaceSingle-wire, bidirectional (not Dallas 1-Wire)Same protocol, different data format
Supply currentAbout 0.3 mA measuring (up to 2.5 mA in some revisions), about 60 µA idleAbout 1 to 1.5 mA measuring, about 40 to 50 µA idle
BodyBlue grille, about 15.5 × 12 × 5.5 mmWhite 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

PinNameDescription
1VCCPower, 3.3 to 5.5 V for both sensors. Use the same voltage as your microcontroller's logic (3.3 V for an ESP32).
2DATABidirectional data line. Needs a pull-up resistor to VCC (built into most 3-pin modules).
3NCNot connected. Leave it unwired.
4GNDGround, 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)

Library guide

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

QtyPartNotes
1ESP32 DevKit (30- or 38-pin)ESP32-S3 and C3 boards work too; only the pin number changes
1DHT11 or DHT22 (AM2302)Module or bare sensor; the DHT22 is the better pick for Sketches 3 and 4
110 kΩ resistorOnly for the bare 4-pin sensor (DATA to 3V3)
1Breadboard and jumper wiresA wide breadboard or two half boards fit the DevKit best
1USB cable with data linesCharge-only cables are the most common upload failure

Swipe sideways to see every column →

Wiring

DHT pinESP32 pinNotes
VCC (+)3V3Not VIN or 5V: the data line is pulled up to VCC and ESP32 pins are not 5 V tolerant
DATA (S / OUT)GPIO 4Any free bidirectional GPIO; avoid the pins listed below
NC—Bare sensor only. Leave unconnected
GND (−)GNDShared 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

  1. 1If the ESP32 is not in your Arduino IDE yet: open Tools > Board > Boards Manager, search for esp32 and install 'esp32 by Espressif Systems'.
  2. 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.
  3. 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.

C++

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.

C++

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:

C++

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.

C++

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 pinESP32 pinNotes
VCC (+)GPIO 25Switched supply: HIGH while reading, LOW while asleep
DATA (S / OUT)GPIO 4Bare sensor: 10 kΩ pull-up from DATA to GPIO 25, so it is unpowered too
GND (−)GNDShared ground

Swipe sideways to see every column →

C++

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

SymptomLikely causeFix
Every read failsDATA on an input-only pin (34 to 39), wrong DHTPIN, or no pull-up on a bare sensorMove 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 wiringDATA connected to a strapping pin (0, 2, 12 or 15)Move the wire to GPIO 4
Frequent random failures once Wi-Fi is onWi-Fi interrupts disturbing the bit timingRead 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 minutesThe ESP32 and its regulator warm the air around the sensorMount the sensor on a 10 to 20 cm cable away from the board
Brownout detector was triggeredWeak USB port or cable while Wi-Fi startsUse 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 valuesDHTTYPE does not match the sensorDHT11 is the blue one, DHT22 / AM2302 the white one; set DHTTYPE accordingly
Sketch 4 always reports no answerThe sensor is read before it has settled, or its VCC is not on GPIO 25Keep 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.

Keep learning

Related guides & projects