The DHT11 temp sensor communicates via a proprietary single-wire digital serial protocol, outputting a 40-bit data packet containing relative humidity and temperature. It does not output an analog voltage, nor does it use standard digital buses like I2C or SPI. If you are connecting this to an Arduino Uno or an ESP32 DevKit V1, you must use a specific microsecond-timed read sequence and a 4.7kΩ pull-up resistor on the data line to see valid readings.

Sensing Principle and Internal Architecture

Temperature is measured using an internal NTC (Negative Temperature Coefficient) thermistor. As ambient temperature rises, the resistance of the sensor's ceramic and polymer composite drops. The internal 8-bit microcontroller samples this voltage drop across a known internal precision resistor to determine the current thermal state.

Humidity is measured via a capacitive polymer dielectric layer. Moisture absorption changes the dielectric constant, altering the capacitance between two internal electrodes. The onboard MCU digitizes both readings, applies factory calibration coefficients stored in OTP (One-Time Programmable) memory, and formats them into the 40-bit serial output. Because the calibration coefficients are burned into the chip at the factory, no user-side calibration, baseline offset mapping, or floating-point scaling math is required on the microcontroller side.

Wiring Pinout and Hardware Setup

When working with the bare 4-pin DHT11 component (not a pre-assembled PCB module), pin 1 is on the far left when the grid face is pointing at you. If you are using a breakout module with 3 pins, the manufacturer has already handled the internal pull-up resistor and omitted the unconnected pin.

DHT11 Pinout and Electrical Specifications
Pin Number Name Function Notes & Constraints
1 VCC Power Supply Supply range: 3.3V to 5.5V DC. Do not exceed 5.5V.
2 DATA Serial Data I/O Requires a 4.7kΩ pull-up resistor to VCC.
3 NC No Connection Leave floating. Do not wire to GND or VCC.
4 GND Ground Connect to microcontroller common ground.
Bench Tip: If you are wiring the bare 4-pin component on a breadboard, you must place a 4.7kΩ (or 10kΩ) resistor between the VCC and DATA pins. The DHT11 uses an open-drain output architecture; without the pull-up resistor, the data line will never return to a logic HIGH state, and your microcontroller will read a continuous stream of zeros.

Decoding the Raw 40-Bit Output Signal

Unlike analog sensors where you map a 0-5V reading to a temperature range, the DHT11 outputs a strict digital 40-bit packet. The microcontroller must trigger the sensor by pulling the DATA line LOW for at least 18 milliseconds, then releasing it HIGH for 40 microseconds. The sensor then takes control of the line and clocks out 40 bits of data.

The 40 bits are divided into five 8-bit bytes. Here is the exact raw-to-unit math required to parse the physical values from the raw binary payload:

  • Byte 0: Relative Humidity Integer part
  • Byte 1: Relative Humidity Decimal part
  • Byte 2: Temperature Integer part
  • Byte 3: Temperature Decimal part
  • Byte 4: Checksum

Physical Unit Math:
To get the final physical units, you combine the integer and decimal bytes. Note that the DHT11 specification dictates that the decimal byte for temperature is currently always zero on standard revisions, but you should still write your code to handle it for forward compatibility with the DHT22.

Humidity (%RH) = Byte[0] + (Byte[1] × 0.1)
Temperature (°C) = Byte[2] + (Byte[3] × 0.1)

Checksum Validation:
Before accepting the data, you must verify the integrity of the transmission. The checksum is the last 8 bits of the sum of the first four bytes.

Checksum = (Byte[0] + Byte[1] + Byte[2] + Byte[3]) & 0xFF

If Byte[4] does not equal the calculated Checksum, the read was corrupted by electrical noise or timing drift, and the data must be discarded. According to Adafruit's DHT Sensor Guide, you should enforce a minimum 2-second delay between read attempts, as the sensor's internal sampling rate cannot exceed 1 Hz.

Interference, Timing, and Debugging

The single-wire protocol used by the DHT11 is highly susceptible to environmental and architectural interference because it relies on microsecond-level pulse width modulation to distinguish between a binary '0' (26µs HIGH) and a binary '1' (70µs HIGH). Here are the most common interference sources and how to mitigate them:

1. Wire Capacitance and Length
Long wires act as parasitic capacitors. If you run a wire longer than 1 meter (approx. 3 feet) between the DHT11 and your ESP32 or Arduino, the capacitance will round off the sharp microsecond edges of the digital signal. The microcontroller's interrupt routine will misinterpret the pulse widths, resulting in checksum failures. Fix: Keep data wires under 1 meter, or switch to an I2C sensor like the BME280 for long-distance runs.

2. RTOS Interrupts on the ESP32
Unlike the single-core, bare-metal Arduino Uno, the ESP32 runs FreeRTOS. Background tasks—specifically WiFi and Bluetooth stack interrupts—can pause the core executing your DHT11 read function for several milliseconds. If the core is paused while measuring a 26µs pulse, the timing is destroyed, and the library returns NaN. As noted in the Espressif FreeRTOS Documentation, you can mitigate this by disabling interrupts during the read sequence using noInterrupts() and interrupts(), or by pinning the sensor read task to Core 1 while leaving Core 0 to handle WiFi.

3. Electromagnetic Interference (EMI)
Routing the DHT11 data wire parallel to AC mains lines, or placing it near the coil of a mechanical relay or a switching DC-DC buck converter, will induce voltage spikes on the data line. These spikes mimic the HIGH state of the protocol, corrupting the bitstream. Fix: Route sensor wires away from inductive loads and use twisted-pair cable for the DATA and GND lines.

4. Self-Heating Errors
Mounting the DHT11 directly above a hot voltage regulator (like an LM7805 or the onboard LDO of an ESP32 DevKit) will cause the NTC thermistor to read ambient temperatures 2°C to 4°C higher than reality. Ensure adequate physical separation or thermal isolation from heat-generating components.

DHT11 Temp Sensor FAQ

Why is my DHT11 reading NaN or 0 on an ESP32?

A NaN (Not a Number) or constant 0 reading on an ESP32 is almost always caused by one of three issues: a missing 4.7kΩ pull-up resistor on the data line, FreeRTOS WiFi interrupts disrupting the microsecond timing of the 1-wire protocol, or a checksum mismatch due to wire capacitance. To debug, first verify the pull-up resistor is physically present. Second, wrap your read function in noInterrupts() and interrupts() to prevent the WiFi stack from stealing CPU cycles during the 40-bit read sequence. Finally, ensure your wires are shorter than 1 meter.

What is the exact difference between the DHT11 and DHT22 sensors?

While both use the exact same 40-bit single-wire protocol and identical wiring pinouts, their internal sensing elements and resolutions differ significantly. The DHT11 uses a basic NTC thermistor and has a temperature range of 0°C to 50°C with a ±2°C accuracy and 1°C resolution. The DHT22 (AM2302) uses a more advanced polymer capacitive sensor and a high-precision thermistor, offering a temperature range of -40°C to 80°C, ±0.5°C accuracy, and 0.1°C resolution. If your project requires sub-zero readings or decimal precision without software averaging, upgrade to the DHT22; the code requires only a single parameter change in the DHT library.

Can I connect multiple DHT11 sensors to the same data pin?

No, the DHT11 protocol does not support device addressing like I2C or 1-Wire (Dallas DS18B20) sensors do. When the microcontroller pulls the data line LOW to trigger a read, every DHT11 connected to that pin will attempt to respond simultaneously, causing a data collision and a guaranteed checksum failure. You must dedicate one unique GPIO pin on your microcontroller to each individual DHT11 sensor, complete with its own dedicated 4.7kΩ pull-up resistor per line.