IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

Series 37 Module Cảm Biến – Nguyên Lý Hoạt Động DHT22 (AM2302): Độ Chính Xác Cao, Dải Đo Rộng

DHT22 — còn gọi là AM2302 — dùng cùng giao thức với DHT11 nhưng có cải tiến đáng kể: dải đo rộng hơn (-40°C đến 80°C), độ chính xác cao hơn (±0.5°C), và độ phân giải 0.1°C thay vì 1°C. Bài này đi sâu vào từng điểm khác biệt từ datasheet AOSONG.

Nguyên Lý Hoạt Động

DHT22 cùng nguyên lý với DHT11: capacitive hygrometer đo độ ẩm + NTC thermistor đo nhiệt độ. Tuy nhiên có 2 cải tiến quan trọng về phần cứng:

1. Polymer Capacitor Chất Lượng Cao Hơn

DHT22 dùng lớp polymer hút ẩm có hằng số điện môi nhạy hơn, đặc biệt ở dải thấp (< 20% RH) và cao (> 80% RH). Đây là lý do DHT22 đo được 0–100% RH trong khi DHT11 giới hạn ở 20–80%.

Điện dung thay đổi theo công thức:

C(RH) = C₀ × (1 + α × RH)

Trong đó α là hệ số nhạy của polymer — DHT22 có α lớn hơn DHT11 → điện dung thay đổi nhiều hơn với cùng một thay đổi độ ẩm → dễ phân biệt giá trị hơn → độ phân giải 0.1% thay vì 1%.

2. Giao Thức 40-bit — Dữ Liệu Có Phần Thập Phân

Giao thức DHT22 tương tự DHT11 (cùng timing, cùng cấu trúc START/RESPONSE/DATA), nhưng định nghĩa 5 byte dữ liệu khác:

ByteNội dungVí dụ (Độ ẩm 65.5%RH)
Byte 1Phần cao độ ẩm × 10 (MSB)0x02 (= 2)
Byte 2Phần thấp độ ẩm × 10 (LSB)0x8B (= 139) → 2×256+139 = 655 → 65.5%
Byte 3Phần cao nhiệt độ × 10 (MSB)0x01 (= 1)
Byte 4Phần thấp nhiệt độ × 10 (LSB)0x15 (= 21) → 1×256+21 = 277 → 27.7°C
Byte 5Checksum = (B1+B2+B3+B4) & 0xFF0xA9

Nhiệt độ âm: Bit 15 (MSB của byte 3) = 1 → nhiệt độ âm. Ví dụ: 0x80 0x05 = 1000 0000 0000 0101 → bit 15 = 1 → -0.5°C.

Timing giao thức DHT22 (giống DHT11 nhưng khác DHT11 ở timing BIT):

START: MCU kéo LOW ≥ 500µs (DHT11 là ≥ 18ms)
       └→ DHT22 đáp: 80µs LOW + 80µs HIGH
       └→ 40 bits: "0" = 50µs L + 26–28µs H | "1" = 50µs L + 70µs H

Điểm khác biệt quan trọng: START signal của DHT22 chỉ cần 500µs (0.5ms), trong khi DHT11 cần ≥ 18ms. Thư viện DHTesp tự xử lý điều này — không cần lo thủ công.

Thông Số Kỹ Thuật

Thông sốDHT22 / AM2302DHT11 (so sánh)
Điện áp3.3V – 5.5V3.0V – 5.5V
Dòng tiêu thụ (đo)1.5mA0.5mA
Dòng tiêu thụ (standby)50µA100µA
Dải nhiệt độ-40°C – 80°C0°C – 50°C
Độ chính xác nhiệt độ±0.5°C (typ ±0.2°C)±2°C
Dải độ ẩm0% – 100% RH20% – 80% RH
Độ chính xác độ ẩm±2% RH (typ ±1%)±5% RH
Độ phân giải0.1°C / 0.1% RH1°C / 1% RH
Sampling period tối thiểu2 giây1 giây
Thời gian đáp ứng nhiệt độ≤ 30 giây (gió nhẹ 1m/s)≤ 30 giây
Thời gian đáp ứng độ ẩm≤ 5 giây≤ 5 giây
Kích thước (sensor dạng AM2302)25 × 15 × 7.7mm
Kích thước (module 3-pin)23 × 12mm23 × 12mm

Lưu ý về “AM2302”: AM2302 là phiên bản wire version — cùng chip DHT22 nhưng đóng gói có sẵn 3 dây (~50cm) và resistor pull-up tích hợp bên trong vỏ. Module DHT22 3-pin là dạng PCB. Hoàn toàn tương thích code.

Sơ Đồ Chân (Pinout)

DHT22 Bare Sensor (4 chân)

      ┌─────────┐
      │  DHT22  │  ← Lỗ thông gió (không bịt lại)
      │         │
  1 ─ │ VCC     │
  2 ─ │ DATA    │  ← Cần pull-up 4.7kΩ – 10kΩ lên VCC
  3 ─ │ NC      │  ← Bỏ trống
  4 ─ │ GND     │
      └─────────┘
  Nhìn từ phía trước (mặt có lỗ)
ChânTênChức năng
1VCCNguồn 3.3V – 5.5V
2DATADữ liệu single-wire, cần pull-up 4.7kΩ lên VCC
3NCKhông kết nối
4GNDĐất

Module DHT22 3-pin (phổ biến)

      ┌────────────────────┐
      │  ┌──────────────┐  │
      │  │     DHT22    │  │
      │  └──────────────┘  │
      │     [R 4.7kΩ]      │  ← Đã tích hợp pull-up
      └────────────────────┘
       "+"   "DATA"   "-"
       VCC     S      GND

AM2302 (wire version)

3 dây màu: đỏ = VCC, vàng = DATA, đen = GND. Đã có pull-up bên trong.

Các Biến Thể Cùng Dòng

ModelDạngGiao thứcĐặc điểm
DHT22PCB module 3-pinSingle-wire AOSONGPhổ biến nhất
AM2302Vỏ nhựa + dây 50cmSingle-wire AOSONGDễ gắn vào vỏ thiết bị
AM2320PCB moduleI2C hoặc Single-wireHỗ trợ cả 2 giao thức
AM2321PCB moduleI2CI2C-only, địa chỉ 0x5C
DHT21PCB moduleSingle-wire AOSONGSpecs giữa DHT11 và DHT22

Lưu ý AM2320: Cùng vỏ vật lý với DHT22 nhưng có thể dùng I2C. Nếu mua “DHT22” mà có địa chỉ I2C → thực ra là AM2320.

Kết Nối Phần Cứng

Kết Nối với ESP32 DevKit V1

ESP32 DevKit V1          DHT22 / AM2302
─────────────────────    ──────────────
3V3  ─────────────────→  VCC (+)
GND  ─────────────────────→  GND (-)
GPIO4 ────────────────→  DATA (S)

Cùng sơ đồ với DHT11. Bắt buộc dùng 3V3 cho DHT22 khi kết nối với ESP32 để bảo vệ GPIO (logic 3.3V, max 3.6V).

Thêm tụ bypass: Nếu nguồn 3V3 từ ESP32 DevKit V1 dao động (nhiều thiết bị cùng lúc), thêm tụ 100nF giữa VCC và GND gần chân module DHT22 để ổn định nguồn.

Kết Nối với Arduino Uno

Arduino Uno              DHT22 / AM2302
─────────────────────    ──────────────
5V   ─────────────────→  VCC (+)
GND  ─────────────────→  GND (-)
Pin 4 ────────────────→  DATA (S)

Arduino Uno 5V/5V logic — kết nối trực tiếp, không cần level shifter.

Nếu không dùng module (bare sensor 4-pin): Thêm R 4.7kΩ từ chân DATA lên VCC.

Code Arduino IDE

Cài Library

Dùng chung library với DHT11:

  • Arduino Uno: DHT sensor library by Adafruit
  • ESP32: DHTesp by beegee-tokyo

Code cho Arduino Uno

/*
 * DHT22 (AM2302) - Đọc nhiệt độ và độ ẩm độ chính xác cao
 * Board: Arduino Uno
 * Library: DHT sensor library by Adafruit
 * Kết nối: DATA → Pin 4, VCC → 5V, GND → GND
 *
 * DHT22 khác DHT11: độ phân giải 0.1°C, dải -40~80°C, 0~100%RH
 */

#include <DHT.h>

#define DHT_PIN   4       // Chân DATA
#define DHT_TYPE  DHT22   // Quan trọng: dùng DHT22, không phải DHT11

DHT dht(DHT_PIN, DHT_TYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();

  Serial.println("=== DHT22 (AM2302) Test - Arduino Uno ===");
  // DHT22 cần tối thiểu 2 giây sampling period (khác DHT11 là 1 giây)
  delay(2000);
}

void loop() {
  delay(2000); // DHT22 minimum sampling period: 2 giây

  float humidity    = dht.readHumidity();
  float temperature = dht.readTemperature(); // Celsius

  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("LỖI: Không đọc được DHT22!");
    Serial.println("  → Kiểm tra: dây kết nối, R pull-up 4.7kΩ, delay >= 2s");
    return;
  }

  // DHT22 có độ phân giải 0.1 → hiển thị 1 chữ số thập phân có ý nghĩa
  Serial.print("Nhiệt độ : ");
  Serial.print(temperature, 1); // "28.3 °C" thay vì "28.0 °C" như DHT11
  Serial.println(" °C");

  Serial.print("Độ ẩm    : ");
  Serial.print(humidity, 1);
  Serial.println(" %RH");

  // DHT22 đo được nhiệt độ âm — kiểm tra riêng
  if (temperature < 0) {
    Serial.print("  → Nhiệt độ âm: ");
    Serial.print(temperature, 1);
    Serial.println(" °C (DHT11 không đo được vùng này)");
  }

  // Tính điểm sương (dew point) theo công thức Magnus
  // Điểm sương: nhiệt độ mà hơi nước bắt đầu ngưng tụ thành sương
  // Hữu ích cho: nông nghiệp, bảo quản, phòng tránh nấm mốc
  float a = 17.27;
  float b = 237.7;
  float alpha = ((a * temperature) / (b + temperature)) + log(humidity / 100.0);
  float dewPoint = (b * alpha) / (a - alpha);

  Serial.print("Điểm sương: ");
  Serial.print(dewPoint, 1);
  Serial.println(" °C");
  
  Serial.println("---");
}

Code cho ESP32

/*
 * DHT22 (AM2302) - Đọc nhiệt độ và độ ẩm
 * Board: ESP32 DevKit V1
 * Library: DHTesp by beegee-tokyo
 * Kết nối: DATA → GPIO4, VCC → 3V3, GND → GND
 *
 * QUAN TRỌNG: Dùng 3V3 (không phải 5V) cho ESP32
 */

#include <DHTesp.h>

#define DHT_PIN  4  // GPIO4 — an toàn trên ESP32, không phải strapping pin

DHTesp dht;

// Biến lưu thời gian đọc cuối để tránh blocking delay
unsigned long lastReadTime = 0;

void setup() {
  Serial.begin(115200);
  dht.setup(DHT_PIN, DHTesp::DHT22); // Chỉ định DHT22, không phải DHT11
  
  Serial.println("=== DHT22 (AM2302) Test - ESP32 ===");
  Serial.println("Chờ 2 giây ổn định...");
  delay(2000);
}

void loop() {
  // Dùng millis() thay vì delay() để code không bị blocking
  // Cho phép thêm code khác chạy song song trong loop()
  unsigned long now = millis();
  
  // DHTesp::getMinimumSamplingPeriod() trả về 2000ms cho DHT22
  if (now - lastReadTime < (unsigned long)dht.getMinimumSamplingPeriod()) {
    return; // Chưa đến lúc đọc, thoát sớm để làm việc khác
  }
  lastReadTime = now;

  // Đọc dữ liệu — DHTesp trả về struct TempAndHumidity
  TempAndHumidity data = dht.getTempAndHumidity();

  // Kiểm tra trạng thái đọc
  if (dht.getStatus() != DHTesp::ERROR_NONE) {
    Serial.printf("LỖI: %s\n", dht.getStatusString());
    return;
  }

  // In kết quả — DHT22 có 0.1°C resolution nên hiển thị 1 decimal
  Serial.printf("Nhiệt độ : %.1f °C\n", data.temperature);
  Serial.printf("Độ ẩm    : %.1f %%RH\n", data.humidity);

  // Điểm sương — hữu ích cho ứng dụng nông nghiệp, HVAC
  float dewPoint = dht.computeDewPoint(data.temperature, data.humidity);
  Serial.printf("Điểm sương: %.1f °C\n", dewPoint);

  // Comfort level — DHTesp tự tính dựa trên temp + humidity
  Serial.printf("Cảm giác  : %s\n", dht.getComfortRatioString(
    dht.computeComfortRatio(data.temperature, data.humidity)
  ));
  // Kết quả có thể là: "OK", "Too Hot", "Too Cold", "Too Humid", v.v.

  Serial.println("---");
}

Kết Quả Mong Đợi

=== DHT22 (AM2302) Test - ESP32 ===
Chờ 2 giây ổn định...
Nhiệt độ : 27.3 °C      ← 0.1°C resolution (DHT11 chỉ cho 27.0)
Độ ẩm    : 63.8 %RH
Điểm sương: 20.4 °C
Cảm giác  : OK
---
Nhiệt độ : 27.4 °C
Độ ẩm    : 63.7 %RH
...

Ứng Dụng Thực Tế

Ứng dụngTại sao DHT22 phù hợp hơn DHT11
Smart farm nhiệt đới0–100% RH — không giới hạn ở 80%
Kho lạnh (0–10°C)DHT11 chỉ đo từ 0°C, margin không đủ
Trạm thời tiết ngoài trờiDải -40–80°C, chính xác hơn
Hệ thống sưởi / điều hòa0.5°C accuracy cho control loop
Phòng server (< 25°C, 40–60% RH)Accuracy quan trọng để cảnh báo sớm
Vườn ươm có sương mùCần đo > 80% RH

Lưu Ý Khi Sử Dụng

1. Sampling period bắt buộc 2 giây

DHT22 có minimum sampling period 2 giây (gấp đôi DHT11). Đọc nhanh hơn → sensor không kịp reset → nhận dữ liệu cũ hoặc lỗi. Dùng millis() thay vì delay() nếu code cần làm việc khác trong khoảng chờ.

2. Không đặt gần nguồn nhiệt hoặc hơi nước

DHT22 nhạy hơn DHT11 → lỗi do môi trường đo sai cũng phóng đại hơn. Đặt sensor trong luồng không khí tự do, cách xa bóng đèn, điện trở, IC nóng.

3. Sai số tăng ở độ ẩm cực cao (> 90%)

Ở độ ẩm > 90% RH (trong môi trường có sương), polymer sensor bão hòa tạm thời. Sau khi độ ẩm giảm, sensor cần 5–10 giây để phục hồi. Không tin kết quả đọc ngay sau khi sensor vừa tiếp xúc hơi nước đặc.

4. Lỗi bit checksum

DHT22 truyền thêm dữ liệu (10-bit thay vì 8-bit mỗi giá trị) → timing nhạy hơn. Nếu checksum fail thường xuyên: dây DATA dài (> 1m) cần R pull-up nhỏ hơn (1–2kΩ), hoặc kiểm tra nguồn có nhiễu.

5. DHT22 vs DHT11 về giá và ứng dụng

DHT22 giá khoảng 3–4× DHT11. Nếu dự án chỉ cần đo trong nhà, 20–80% RH, không yêu cầu 0.1°C precision → DHT11 đủ dùng và tiết kiệm chi phí.

Bài tiếp theo: