DHT11 Humidity Sensor Arduino: Quick Start & Spec Sheet
The DHT11 is a basic, low-cost capacitive humidity and thermistor sensor widely used in entry-level environmental monitoring. If you are wiring a DHT11 humidity sensor to an Arduino, the direct answer for a standard 3-pin breakout module is: connect VCC to 5V, GND to GND, and the DATA pin to Digital Pin 2, using a 2-second polling interval in your code.
Unlike I2C or SPI sensors (such as the BME280), the DHT11 uses a proprietary single-bus protocol. The microcontroller must bit-bang the communication line, pulling it low to initiate a read and then timing the high/low pulses to decode the 40-bit data payload. This timing sensitivity is the root cause of 90% of debugging headaches on the bench.
Estimated Time: 15 minutes for wiring and code upload; 30+ minutes if debugging bare 4-pin components.
Sensor Specification Sheet
| Parameter | DHT11 Specification | Practical Bench Notes |
|---|---|---|
| Operating Voltage | 3.3V to 5.5V DC | Use 5V on Arduino Uno; use 3.3V on ESP32/Raspberry Pi Pico. |
| Humidity Range | 20% to 80% RH | Readings outside this range will flatline or return errors. |
| Temperature Range | 0°C to 50°C (32°F to 122°F) | Not suitable for freezers or high-heat enclosures. |
| Sampling Rate | 1 Hz (1 reading per second) | Code MUST include a delay(2000) to allow sensor recovery. |
| Accuracy | ±5% RH, ±2°C | Expect variance between two DHT11s on the same bench. |
Hardware Requirements & Pin Mapping
For this guide, we are targeting the Arduino Uno R3 (ATmega328P) running at 5V logic. We recommend using the 3-pin DHT11 breakout module rather than the bare 4-pin blue plastic component. The 3-pin module includes a built-in 10kΩ pull-up resistor and a filter capacitor, eliminating the most common wiring errors.
Parts List
- Microcontroller: Arduino Uno R3 (or compatible clone with ATmega328P)
- Sensor: DHT11 3-pin breakout module (often sold as "DHT11 Digital Temperature and Humidity Module")
- Wiring: 3x Male-to-Female or Male-to-Male Dupont jumper wires
- Prototyping: Half-size breadboard (optional if using M-F jumpers directly to Uno headers)
Pin Mapping Table
| DHT11 Module Pin | Arduino Uno R3 Pin | Wire Color (Recommended) |
|---|---|---|
| VCC (or +) | 5V | Red |
| GND (or -) | GND | Black |
| DATA (or OUT / S) | Digital Pin 2 | Yellow or Green |
Complete Arduino Code with Error Handling
This code targets the Arduino Uno R3 and uses the industry-standard Adafruit DHT Sensor Library. You must install both the DHT sensor library and its dependency, the Adafruit Unified Sensor library, via the Arduino IDE Library Manager before compiling.
#include <DHT.h>
// --- PIN DEFINITIONS & CONFIGURATION ---
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // Sensor type: DHT11, DHT22, or DHT21
// Initialize DHT sensor for normal 16MHz Arduino
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
Serial.println(F("DHT11 Humidity Sensor Arduino Test"));
// The DHT11 requires a brief stabilization time on boot
dht.begin();
delay(2000);
}
void loop() {
// Wait a minimum of 2 seconds between readings (1Hz max sample rate)
delay(2000);
// Read humidity and temperature
float h = dht.readHumidity();
float t = dht.readTemperature(); // Celsius by default
float f = dht.readTemperature(true); // Fahrenheit
// --- ERROR HANDLING ---
// Check if any reads failed and exit early (to try again)
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Compute heat index (Fahrenheit)
float hif = dht.computeHeatIndex(f, h);
// --- SERIAL OUTPUT ---
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% | Temp: "));
Serial.print(t);
Serial.print(F("°C / "));
Serial.print(f);
Serial.print(F("°F | Heat Index: "));
Serial.print(hif);
Serial.println(F("°F"));
}
Debugging: "Failed to read from DHT sensor!"
If your Serial Monitor outputs the exact string Failed to read from DHT sensor!, the Arduino's isnan() (is Not a Number) check has triggered. This means the microcontroller sent the start signal, but the sensor failed to return a valid 40-bit checksum payload.
The First 3 Things to Check When It Fails
- Verify the 2-Second Polling Delay: The DHT11 hardware needs time to sample the ambient air and reset its internal state machine. If your
loop()polls the sensor faster than once per second (e.g., adelay(500)), the sensor will lock up and ignore subsequent start signals. Ensuredelay(2000)is at the top of your loop. - Check for the Pull-Up Resistor: The single-bus protocol relies on an open-drain architecture. If you are using a bare 4-pin DHT11 without a breakout board, the data line will float, resulting in garbage data or no response. Verify the 10kΩ resistor is physically bridging VCC and DATA.
- Measure Power Sag at the Sensor: Use a multimeter to measure DC voltage directly at the sensor's VCC and GND pins while the circuit is powered. Breadboard contact resistance can cause voltage drops. If the DHT11 sees less than 3.1V, it will brownout and fail to drive the data line high.
Ranked Causes for Persistent Read Failures
If the first three checks pass, move down this ranked list of edge cases:
- Cause 1: Interrupt Conflicts (Most Likely in Complex Sketches). The DHT protocol requires microsecond-level timing to read the 40-bit payload. If your sketch uses heavy interrupts (e.g., software serial, high-frequency PWM, or timer interrupts for displays), the Arduino will miss the sensor's pulses. Fix: Disable interrupts right before reading and re-enable them after, though the Adafruit library attempts this automatically on AVR boards.
- Cause 2: Parasitic Capacitance on Long Wires. The DHT11 data line is highly sensitive to capacitance. Using ribbon cables or jumper wires longer than 1 meter (3 feet) will smear the digital edges, causing the Arduino to misread the bit timings. Fix: Keep data wires under 50cm, or add a stronger 4.7kΩ pull-up resistor.
- Cause 3: Sensor Saturation / Condensation. If the sensor was exposed to 100% humidity, breath, or liquid water, the internal capacitive polymer may be saturated. Fix: Place the sensor in a dry environment (or gently warm it with a hair dryer on low from 12 inches away) for 24 hours to evaporate trapped moisture.
Extending and Simplifying the Build
Once your baseline Arduino Uno and DHT11 setup is logging data reliably, you will likely hit the physical limits of the sensor or the board. Here is how to adapt the project.
How to Simplify the Build
If you want to reduce wiring complexity and eliminate breadboard faults, switch to an Arduino Nano and solder the DHT11 module directly to a custom PCB or perfboard. Alternatively, use a Grove or Qwiic shield system if you prefer plug-and-play modularity, though you will need to buy a proprietary adapter cable for the DHT11.
How to Extend the Build
- Upgrade to DHT22 (AM2302): If your environment drops below 0°C or exceeds 80% humidity, swap the DHT11 for a DHT22. The wiring and pinout remain identical; you only need to change
#define DHTTYPE DHT11toDHT22in the code. The DHT22 offers ±2% RH accuracy and a -40°C to 80°C range. - Add Wireless Telemetry: Move the project to an ESP32 DevKit V1. The ESP32 has built-in WiFi. You can use the exact same Adafruit DHT library, but add the
PubSubClientlibrary to publish the humidity and temperature payloads to an MQTT broker (like Mosquitto) for integration with Home Assistant. - Local Display Output: Wire a 0.96" I2C OLED display (SSD1306) to the A4/A5 pins. Use the
Adafruit_SSD1306library to render the temperature and humidity locally without needing a PC connected to the Serial Monitor.
Frequently Asked Questions
Why is my DHT11 reading 0% humidity or NaN?
A reading of exactly 0% usually indicates a hardware communication failure rather than an actual environmental measurement, triggering the library's fallback or your code's isnan() check. This happens when the Arduino sends the 18ms pull-down start signal, but the sensor fails to pull the line high in response. Check your wiring, ensure the 2-second delay is present, and verify the sensor isn't damaged by static discharge.
Can I use the DHT11 humidity sensor with an Arduino Nano or ESP32?
Yes. The DHT11 operates on 3.3V to 5.5V, making it compatible with the 5V logic of the Arduino Nano and the 3.3V logic of the ESP32. If using an ESP32, connect VCC to the 3.3V pin (or VIN if powered via USB) and DATA to a GPIO pin (avoid GPIO 0, 2, and 12 due to boot-strapping requirements). The Adafruit library handles the timing differences between 16MHz AVR and 240MHz Xtensa processors automatically.
DHT11 vs DHT22: When should I upgrade my Arduino project?
Upgrade to the DHT22 (AM2302) when your project requires monitoring environments outside the 20-80% RH and 0-50°C bounds. The DHT11 is fine for basic indoor room temperature logging, but the DHT22 provides decimal-point precision (e.g., 23.4°C instead of just 23°C), a wider operating range (-40°C to 80°C), and a faster 0.5Hz sampling rate. The DHT22 typically costs $4-$6 compared to the DHT11's $1-$2 price tag.
Do I need a resistor for the DHT11 data pin on Arduino?
It depends on the module. If you bought the bare, blue 4-pin DHT11 component, you absolutely need a 10kΩ pull-up resistor between VCC and the DATA pin. If you bought the 3-pin or 4-pin DHT11 mounted on a small PCB breakout board (usually with a tiny black SMD resistor visible on the back), the pull-up resistor is already integrated, and you can wire it directly to the Arduino.






