The blue DHT11 module is the cheapest temperature and humidity sensor in every Indian kit, and it runs happily on the NodeMCU’s 3.3 V. Three wires — 3V3, D5, GND — and the DHT library does the timing.
The one thing to get right is the pin name. The board says D5, the chip calls it GPIO14, and the sketch uses the core’s D5 constant so the two can’t get mixed up.
Wiring
| NodeMCU ESP8266 | DHT11 | Wire | Notes |
|---|---|---|---|
| 3V3 | VCC | red | Run it at 3.3 V so DATA never goes above the ESP8266’s 3.3 V limit. |
| D5 | DATA | yellow | D5 is GPIO14. The 3-pin module already has the pull-up resistor. |
| GND | GND | black |
3.3–5.5 V part, 3.3 V board. Power it from your board's logic voltage so the data line matches the GPIO: 3.3 V on ESP32 and Pico, 5 V on Uno.
Board quirks
- In code
D5is a constant from the ESP8266 core that equals 14. WritingDHT dht(5, DHT11)instead would use GPIO5 — which is the pin marked D1. - D5 keeps D1/D2 free for an I2C display. Avoid D3, D4 and D8: the module’s pull-up on D8 (GPIO15) holds it high at reset and the board won’t boot; D3 and D4 work but tie up boot pins you may need later.
- The DHT11 reports whole numbers (±2 °C, ±5 % RH) and only 0–50 °C. If you need decimals or a wider range, the DHT22 page for this board uses the same wiring.
- Leave at least 1 s between reads (the sketch uses 2 s). Use
delay()ormillis()rather than a busy loop so the ESP8266’s Wi-Fi stack and watchdog keep running.
Code
// DHT11 module (3-pin, pull-up on the module) on a NodeMCU (ESP8266).
// VCC → 3V3, DATA → D5 (GPIO14), GND → GND.
#include <DHT.h>
const uint8_t DHT_PIN = D5; // GPIO14 — no boot role, keeps D1/D2 free for I2C
DHT dht(DHT_PIN, DHT11);
float tMin = 99, tMax = -99;
void setup() {
Serial.begin(115200);
Serial.println();
dht.begin();
Serial.println("DHT11 on D5 (GPIO14) - one reading every 2 s");
}
void loop() {
delay(2000); // the DHT11 needs at least 1 s between reads; delay() also lets Wi-Fi run
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor - check DATA on D5 and 3V3");
return;
}
if (t < tMin) tMin = t;
if (t > tMax) tMax = t;
// The DHT11 reports whole degrees and whole % — the .0 is not extra precision.
Serial.printf("Temp %.0f C Humidity %.0f %% (min %.0f / max %.0f C)\n", t, h, tMin, tMax);
}// DHT11 module (3-pin, pull-up on the module) on a NodeMCU (ESP8266).
// VCC → 3V3, DATA → D5 (GPIO14), GND → GND.
#include <DHT.h>
const uint8_t DHT_PIN = D5; // GPIO14 — no boot role, keeps D1/D2 free for I2C
DHT dht(DHT_PIN, DHT11);
float tMin = 99, tMax = -99;
void setup() {
Serial.begin(115200);
Serial.println();
dht.begin();
Serial.println("DHT11 on D5 (GPIO14) - one reading every 2 s");
}
void loop() {
delay(2000); // the DHT11 needs at least 1 s between reads; delay() also lets Wi-Fi run
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor - check DATA on D5 and 3V3");
return;
}
if (t < tMin) tMin = t;
if (t > tMax) tMax = t;
// The DHT11 reports whole degrees and whole % — the .0 is not extra precision.
Serial.printf("Temp %.0f C Humidity %.0f %% (min %.0f / max %.0f C)\n", t, h, tMin, tMax);
}Library: DHT sensor library (Adafruit (also install Adafruit Unified Sensor)) — compiled with DHT sensor library 1.4.7.
Expected serial output
DHT11 on D5 (GPIO14) - one reading every 2 s
Temp 29 C Humidity 64 % (min 29 / max 29 C)
Temp 29 C Humidity 63 % (min 29 / max 29 C)
Temp 30 C Humidity 63 % (min 29 / max 30 C)DHT11 on D5 (GPIO14) - one reading every 2 s Temp 29 C Humidity 64 % (min 29 / max 29 C) Temp 29 C Humidity 63 % (min 29 / max 29 C) Temp 30 C Humidity 63 % (min 29 / max 30 C)
Common errors
“Failed to read from DHT sensor”
DATA on the wrong pin (D5 in the code, the pin marked D5 on the board), a loose GND, or reads less than 1 s apart. Full fix.
Readings stuck or the humidity is way off
Cheap DHT11s drift. Compare with a known hygrometer; a DHT22 or AHT20 is far more accurate for a few rupees more.
Board won’t boot after wiring the sensor
DATA is on D8 (GPIO15). The module’s pull-up holds it high at reset. Move it to D5.