ESP32 DHT22 Simulator: Wiring, Code and a Live Circuit
This is a DHT22 temperature and humidity sensor wired to an ESP32 DevKit, running live: the board reads the sensor every two seconds and prints both numbers on the serial monitor. Open it in the editor and drag the sensor’s sliders: the next reading follows them.
The ESP32 is a 3.3 V board, so the sensor is powered from 3V3 and DATA goes to GPIO 4 (D4). Below are the wiring with the board’s real pin names, the sketch, and the mistakes people make with this pair.
- 3.3 V logic
- Library: DHT.h (Adafruit)
- Data on GPIO 4 (D4)
- Powered from 3V3
Wiring the DHT22 to the ESP32
Every connection in the circuit above, with the board’s own pin names.
| DHT22 pin | ESP32 pin | Why |
|---|---|---|
| VCC (+) | 3V3 | The sensor runs from 3.3 V, and so does its pull-up, so DATA never rises above what the pin can take. |
| DATA (out) | GPIO 4 (D4) | One wire, both directions: the board pulls it low to ask, the sensor answers with 40 bits. |
| GND (-) | GND | A shared ground, or the board cannot read the sensor’s levels. |
The three-pin module carries a pull-up resistor from DATA to VCC. Powered from VIN (5 V from USB), that resistor would hold a ESP32 pin at 5 V, which the ESP32 (Xtensa LX6) is not rated for. From 3V3 the whole line stays at 3.3 V and the sensor still reads normally.
Pins to leave alone on the ESP32
GPIO 34, 35, 36 (VP) and 39 (VN) are input only: they cannot drive a pin or take an internal pull-up. GPIO 0, 2, 5, 12 and 15 are strapping pins, read at power-on, and GPIO 6 to 11 are the flash chip.
On a real bench
The thirty-pin DevKit straddles a breadboard with one row of holes free on each side, which is where the DHT22’s jumpers go. Many ESP32 boards are wider and cover both rows; then use two breadboards side by side. Hold BOOT while uploading if the IDE cannot connect.
The code
The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.
#include "DHT.h"
#define DHT_PIN 4 // DATA, GPIO 4 (D4)
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
void setup() {
Serial.begin(115200);
dht.begin();
Serial.println("DHT22 on the ESP32");
}
void loop() {
delay(2000); // the DHT22 measures every 2 s
float celsius = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(celsius) || isnan(humidity)) { // a failed read is NAN
Serial.println("No reading from the DHT22");
return;
}
Serial.print("Temperature: ");
Serial.print(celsius, 1);
Serial.print(" C Humidity: ");
Serial.print(humidity, 1);
Serial.println(" %");
}
DHT dht(DHT_PIN, DHT_TYPE) names the pin and the sensor type, and dht.begin() releases the line so the module’s pull-up holds it high. The Adafruit DHT library’s calls compile here as written, on the ESP32 as on every board in the simulator.
readTemperature() and readHumidity() each return a float, or NAN when the sensor did not answer. Both come from the same 40-bit frame, so a failed read is NAN in both, and the sketch checks isnan() on both before printing anything. A failed reading is normal on a real bench now and then, and the first one after power-up always fails.
The two-second delay is the sensor’s own pace: a DHT22 starts a new measurement at most every two seconds and hands back the last one in between. Serial.begin(115200) opens the serial monitor. Serial is UART0 on the USB bridge. ESP32 sketches usually run it at 115200 baud, which this one does.
Common mistakes with the DHT22 on the ESP32
Reading faster than every two seconds
A DHT22 needs two seconds between measurements. Ask sooner and it returns the previous reading, or nothing at all, so a fast loop looks like a stuck sensor. Keep the delay(2000), or time the reads with millis().
Powering the module from VIN (5 V from USB)
It works for a while, which is the trap. The module’s pull-up then holds DATA at 5 V, above the ESP32 (Xtensa LX6)’s absolute maximum, and the pin can be damaged slowly. Use 3V3, as in the circuit above.
Putting the DHT22’s DATA line on an input-only pin
GPIO 34, 35, 36 and 39 on the ESP32 have no output driver at all. pinMode() to OUTPUT on one of them does nothing and the line never moves, which looks exactly like a dead part. GPIO 4 (D4) is a safe choice; so are GPIO 13, 14, 16 to 19, 23, 25 to 27 and 32 to 33.
Questions and answers
Can I simulate a DHT22 with an ESP32 DevKit online?
Yes. The circuit at the top of this page is an ESP32 DevKit with a DHT22, running in your browser on a simulated ESP32 (Xtensa LX6). The sensor’s sliders set the temperature and humidity it reports, so you can test a thermostat or an alarm threshold without heating anything. Press Run it in the editor to change the wiring or the code; it is free and needs no account.
Which ESP32 pin should the DHT22 DATA wire use?
Any digital pin that can be both an output and an input. This circuit uses GPIO 4 (D4). Avoid GPIO 34 to 39, which are input only.
How do I use a DHT11 instead?
Change DHT22 to DHT11 in the #define and wire it the same way. The DHT11 reads whole degrees and whole percent, from 0 to 50 C, and it can be asked once a second. In the editor, set the sensor’s model property to dht11.
Why does the serial monitor say there is no reading?
Either the sketch asked within the sensor’s first second after power-up, the DATA wire is on a different pin from the one in the #define, or the pull-up is missing. On an ESP32 DevKit check that DHT_PIN is 4.
Build your own DHT22 project
Open this circuit in the editor, change the wiring or the code, and keep your version in a free account.