Sensing Principle and Output Architecture
The DHT22 (often sold in its wired, through-hole variant as the AM2302) measures ambient conditions using two distinct physical transducers housed in a single plastic shell. Humidity is measured via a capacitive sensing element consisting of a moisture-holding polymer substrate sandwiched between two electrodes; as ambient water vapor increases, the dielectric constant of the polymer changes, altering its capacitance. Temperature is measured using a discrete NTC (Negative Temperature Coefficient) thermistor, whose electrical resistance drops predictably as ambient heat rises. An internal 8-bit microcontroller samples both transducers, digitizes the readings, and stores the factory calibration coefficients in one-time programmable (OTP) memory.
Crucially, the DHT22 output is not an analog voltage, a 4-20mA current loop, or a standard I2C/SPI digital stream. It uses a proprietary, single-bus digital protocol. The microcontroller pulls the data line low to initiate communication, then clocks out exactly 40 bits of serial data by modulating the high/low pulse widths of the single data pin. Because it relies on precise microsecond-level timing rather than a hardware clock line, reading this sensor requires either strict interrupt disabling on your microcontroller or a dedicated hardware timer to capture the pulse edges.
Wiring Pinout, Pull-Ups, and Signal Integrity
The bare DHT22 has four pins, but only three are used. The wired AM2302 module typically includes the necessary 4.7kΩ pull-up resistor on the PCB, but if you are using the bare 4-pin component, you must add it externally. The supply range is forgiving, but noise on the VCC rail will directly corrupt the internal ADC readings.
| Pin | Function | Specifications & Notes |
|---|---|---|
| 1 | VCC | 3.3V to 5.5V DC. Ensure < 50mV ripple. |
| 2 | DATA | Serial I/O. Requires 4.7kΩ pull-up to VCC. |
| 3 | NC | No Connection. Leave floating. |
| 4 | GND | System Ground. |
The two biggest killers of DHT22 accuracy are parasitic capacitance and MCU thermal bleed. If your data wire exceeds 1 meter, the cable capacitance will round off the sharp microsecond pulse edges, causing checksum failures. For runs over 1m, use shielded twisted pair or switch to an I2C sensor. Second, mounting the sensor directly above a voltage regulator or an ESP32 Wi-Fi antenna will skew the temperature reading by 2°C to 4°C due to convective heat rise.
Decoding the 40-Bit Stream: Raw-to-Unit Math
When the microcontroller successfully reads the DHT22, it receives a 40-bit payload. This payload consists of five 8-bit bytes: two bytes for humidity, two bytes for temperature, and one byte for a checksum. Because the sensor is factory-calibrated in OTP memory, no user calibration or complex polynomial scaling is required. You only need to apply basic bit-shifting and division.
Humidity Math:
The first two bytes form a 16-bit unsigned integer representing relative humidity in tenths of a percent.
Humidity_RAW = (Byte1 << 8) | Byte2
Humidity_%RH = Humidity_RAW / 10.0
Example: A raw value of 0x0226 (550 decimal) equals 55.0% RH.
Temperature Math:
Bytes 3 and 4 form a 16-bit signed integer. Bit 15 (the MSB of Byte 3) is the sign bit (0 = positive, 1 = negative). The lower 15 bits represent the magnitude in tenths of a degree Celsius.
Temp_RAW = (Byte3 << 8) | Byte4
Sign = (Temp_RAW & 0x8000) ? -1 : 1
Temp_°C = Sign * ((Temp_RAW & 0x7FFF) / 10.0)
Example: A raw value of 0x00FA (250 decimal) equals 25.0°C. A raw value of 0x8032 (-50 decimal) equals -5.0°C.
Checksum Validation:
Checksum = (Byte1 + Byte2 + Byte3 + Byte4) & 0xFF
If the calculated checksum does not match Byte 5, discard the entire 40-bit frame and retry after a 2-second delay.
Sensor Selection Decision Tree: DHT22 vs. Modern Alternatives
While the DHT22 is a staple of DIY IoT, modern environmental sensors have largely surpassed it in speed, accuracy, and bus reliability. Use this decision path to select the right part for your PCB or breadboard.
| Condition / Requirement | If True, Choose... | Why? |
|---|---|---|
| Budget is strictly under $4.00 per unit and I2C pins are exhausted. | DHT22 (AM2302) | Cheapest viable digital temp/humidity sensor; uses only 1 GPIO. |
| You need sub-second sampling (e.g., drone PID loops or fast HVAC control). | Sensirion SHT31 | DHT22 requires a 2-second blocking wait between reads. SHT31 I2C responds in milliseconds. |
| You need barometric pressure for altitude or weather station forecasting. | Bosch BME280 | Adds a high-resolution piezoresistive pressure sensor on the same I2C bus. |
| The environment has high condensation risk or requires IP67 waterproofing. | Sensirion SHT35 (with PTFE membrane) | DHT22 polymer degrades and drifts permanently if liquid water pools inside the shell. |
For 90% of new embedded designs in 2026, choose the Bosch BME280 (Adafruit Part # 2651 or SparkFun Part # SEN-13676). At roughly $6 to $9, it costs only marginally more than a DHT22 but eliminates the single-bus timing nightmares, draws significantly less average current, and provides pressure data. Reserve the DHT22 strictly for legacy replacements, extreme budget constraints, or educational exercises in bit-banging protocols.
Step-by-Step ESP32 Integration and Error Handling
If your design constraints mandate the DHT22, follow these steps to integrate it with an ESP32 using the Arduino core. The ESP32's FreeRTOS environment can sometimes interrupt the microsecond timing required for the DHT protocol, so library choice matters.
- Hardware Wiring: Connect AM2302 Pin 1 to ESP32 3V3. Connect Pin 4 to GND. Connect Pin 2 to GPIO 4. If using a bare DHT22, solder a 4.7kΩ resistor between GPIO 4 and 3V3.
- Library Selection: Install the DHT sensor library by Adafruit via the Arduino Library Manager. Avoid generic 'DHT' libraries that lack ESP32-specific port yielding.
- Initialization: In your
setup(), initialize the sensor object and set the GPIO pin mode to INPUT. Do not attempt a read insetup()immediately; the DHT22 requires a 2-second power-on stabilization delay. - Polling Loop: In your
loop(), use a non-blockingmillis()timer to read the sensor exactly every 2,500ms. Reading faster than the sensor's internal refresh rate will return cached data or checksum errors. - Error Handling: Always check for
isnan()returns. The Adafruit library returns NaN (Not a Number) if the checksum fails or the timing edge is missed. Implement a retry counter; if three consecutive reads fail, power-cycle the sensor via a MOSFET or trigger a hardware watchdog reset.
For deeper technical specifications on the single-bus timing diagrams, refer to the Adafruit DHTxx Guide. If you decide to pivot to the recommended BME280 alternative, the BME280 Breakout Documentation provides the exact I2C address configurations and oversampling registers needed for optimal noise rejection.






