The DHT11 sensor outputs a proprietary digital single-bus signal, not an analog voltage. To extract physical units, your microcontroller must read a 40-bit serial data stream and apply checksum math to yield integer temperature (°C) and relative humidity (%). It requires a 3.3V to 5.5V supply and a 4.7kΩ to 10kΩ pull-up resistor on the data line. Unlike analog sensors that require ADC scaling, the DHT11 handles internal analog-to-digital conversion and outputs pre-calibrated digital bytes.

Sensing Principle: How the DHT11 Measures Air

Inside the blue plastic housing, the DHT11 uses two distinct physical sensing elements. Humidity is measured via a capacitive polymer sensor; as water vapor is absorbed by the dielectric material between two electrodes, the capacitance changes proportionally to the relative humidity. Temperature is measured using a surface-mount NTC (Negative Temperature Coefficient) thermistor, whose electrical resistance drops predictably as ambient heat increases.

These raw analog changes are fed into an internal 8-bit microcontroller embedded on the sensor's PCB. This internal MCU samples the analog signals, applies factory-programmed calibration coefficients stored in its OTP (One-Time Programmable) memory, and formats the result into a 40-bit digital data packet. Because the math happens on the sensor itself, the host microcontroller only needs a single GPIO pin to read the final digital output.

Wiring the DHT11 Sensor to ESP32 and Arduino

The DHT11 is available in two physical form factors: a bare 4-pin component and a 3-pin PCB module. The 3-pin module includes the required pull-up resistor and a filter capacitor, making it breadboard-friendly. If you are using the bare 4-pin sensor, you must add an external 4.7kΩ to 10kΩ pull-up resistor between VCC and the DATA pin.

Pin (Bare 4-Pin)Pin (3-Pin Module)FunctionConnection / Supply Range
1VCC / +Power Supply3.3V to 5.5V DC
2DATA / OUTSerial Data OutputGPIO Pin (with 4.7kΩ-10kΩ pull-up to VCC)
3N/ANo ConnectionLeave floating (do not connect)
4GND / -GroundSystem GND
Callout Tip: ESP32 GPIO Selection
When wiring to an ESP32, avoid using GPIO 0, 2, 5, 12, or 15 for the DHT11 data line. These pins have boot-strapping requirements that can cause the ESP32 to fail to enter flash mode if pulled high or low during startup. Use GPIO 4, 16, 17, 21, or 22 for reliable sensor interfacing.

Numbered Wiring Steps

  1. De-energize the board: Disconnect USB power from your Arduino or ESP32 before making connections to prevent shorting the 5V rail to a 3.3V logic pin.
  2. Connect Power: Wire the sensor VCC to the 5V pin (or 3.3V if your specific module datasheet confirms 3.3V operation). Wire GND to the microcontroller GND.
  3. Install Pull-up (Bare sensors only): Insert a 10kΩ resistor between the VCC and DATA pins on the breadboard.
  4. Connect Data: Run a jumper from the sensor DATA pin to your chosen microcontroller GPIO (e.g., ESP32 GPIO 4 or Arduino Uno Pin 2).
  5. Verify: Use a multimeter in continuity mode to verify there is no short between VCC and GND before applying power.

Output Signal Math: Decoding the 40-Bit Data Stream

A common beginner mistake is attempting to read the DHT11 with an analogRead() function. The output is strictly digital, utilizing a single-bus time-division protocol. The host microcontroller pulls the line LOW for at least 18ms to request data. The sensor responds by pulling the line LOW for 80µs, then HIGH for 80µs, before transmitting 40 bits of data.

Each bit starts with a 50µs LOW voltage. A logic 0 is represented by 26-28µs of HIGH voltage, while a logic 1 is represented by 70µs of HIGH voltage. The 40 bits are divided into five 8-bit bytes:

  • Byte 1: Relative Humidity Integer part
  • Byte 2: Relative Humidity Decimal part (Always 0 on DHT11)
  • Byte 3: Temperature Integer part (°C)
  • Byte 4: Temperature Decimal part (Always 0 on DHT11)
  • Byte 5: Checksum

Raw-to-Unit Math and Checksum Validation

To ensure data integrity, you must calculate the checksum before accepting the reading. The checksum is the sum of the first four bytes, masked to 8 bits.

Formula: Checksum = (Byte1 + Byte2 + Byte3 + Byte4) & 0xFF

Worked Example: Assume the microcontroller reads the following raw hex bytes: 0x41, 0x00, 0x19, 0x00, 0x5A.

  1. Byte 1 (0x41) = 65 in decimal. Humidity Integer = 65%.
  2. Byte 2 (0x00) = 0. Humidity Decimal = 0. Total RH = 65.0%.
  3. Byte 3 (0x19) = 25 in decimal. Temp Integer = 25°C.
  4. Byte 4 (0x00) = 0. Temp Decimal = 0. Total Temp = 25.0°C.
  5. Checksum Math: (0x41 + 0x00 + 0x19 + 0x00) = 0x5A. This matches Byte 5 (0x5A). The data is valid.

If the calculated checksum does not match Byte 5, the library will discard the packet and return a NaN (Not a Number) error. For deeper protocol timing details and library implementation, refer to the Adafruit DHT Sensor Guide.

Calibration, Interference, and Real-World Limits

The DHT11 is factory-calibrated in its OTP memory. No user calibration or scaling math is required to convert the raw bytes into physical units. However, the sensor has strict physical limits: it samples at a maximum rate of 1Hz (one reading per second), and polling it faster will cause the internal MCU to lock up and return corrupted data.

Common Interference Sources:

  • Wire Capacitance: The single-bus protocol relies on microsecond timing. If your data wire exceeds 1 meter, the parasitic capacitance of the copper slows the rise time of the pull-up resistor, causing the microcontroller to misread 70µs HIGH bits as 28µs HIGH bits. Keep wire runs under 20 meters, and use a stronger 1kΩ pull-up for longer runs.
  • Electromagnetic Interference (EMI): Routing the data cable parallel to 120V/240V AC mains wiring will induce voltage spikes that corrupt the 40-bit packet. Always cross AC lines at 90-degree angles and use shielded cable if running through walls.
  • Thermal Self-Heating: If mounted inside a sealed, unventilated enclosure, the ESP32 or Arduino's onboard voltage regulator will raise the local ambient temperature, causing the DHT11's NTC thermistor to read 2°C to 4°C higher than the actual room temperature.

For applications requiring higher precision or faster sampling, consider upgrading to the DHT22 (AM2302), which offers 0.1°C resolution and a wider temperature range, though it uses the exact same 40-bit single-bus math.

DHT11 Sensor FAQ

Why is my DHT11 sensor reading 0 or NaN in the Serial Monitor?

A NaN or 0 reading almost always indicates a failed checksum or a timeout during the 18ms start signal. First, verify your pull-up resistor; a missing or incorrectly placed pull-up leaves the data line floating, resulting in random noise that fails the checksum. Second, ensure your code enforces a minimum 2-second delay between dht.read() calls. Polling the sensor at 100ms intervals starves the internal MCU, causing it to drop off the bus entirely.

Can I power the DHT11 sensor directly from an ESP32 3.3V pin?

Yes, but with caveats. The bare DHT11 component specifies an operating range of 3.3V to 5.5V. However, many cheap 3-pin breakout modules include an onboard 3.3V LDO voltage regulator or a specific LED that drops the voltage below the sensor's minimum threshold when fed only 3.3V. If your 3-pin module fails to initialize on 3.3V, power it from the ESP32's 5V (VIN) pin, but remember to use a logic level shifter or a voltage divider on the DATA line to avoid feeding 5V logic back into the ESP32's 3.3V-tolerant GPIO.

How do I calibrate the DHT11 sensor for better accuracy?

You cannot recalibrate the internal OTP memory of the DHT11, and its baseline accuracy is limited to ±2°C and ±5% RH. Instead of hardware calibration, apply a software offset in your code. Place the DHT11 next to a known-accurate reference thermometer (like a Fluke NIST-traceable meter) for 15 minutes in a stable room. If the reference reads 22.5°C and the DHT11 reads 24.0°C, hardcode a -1.5 offset in your firmware: float correctedTemp = rawTemp - 1.5;.