Thư viện DHT: đọc nhiệt độ & độ ẩm DHT11/DHT22 trên Arduino
DHT11 và DHT22 (AM2302) là cặp cảm biến nhiệt độ + độ ẩm rẻ nhất và phổ biến nhất ở Việt Nam — gần như tutorial Arduino nào cũng dùng. Bài này hướng dẫn thư viện DHT (Adafruit) và DHT_nonblocking để đọc đúng, tránh các lỗi giá trị NaN thường gặp.
1. So sánh DHT11 vs DHT22
| Thông số | DHT11 | DHT22 / AM2302 |
|---|---|---|
| Dải nhiệt | 0–50°C (±2°C) | -40 đến 80°C (±0.5°C) |
| Dải ẩm | 20–80% (±5%) | 0–100% (±2–5%) |
| Tần suất đọc | 1 Hz (1s/lần) | 0.5 Hz (2s/lần) |
| Giá tại VN | ~15.000đ | ~50.000–80.000đ |
| Độ phân giải | 1°C, 1% | 0.1°C, 0.1% |
Cho dự án nghiêm túc (datalogger, weather station), luôn chọn DHT22. DHT11 chỉ đủ cho demo.
2. Đấu nối
Cả hai loại có 3 chân (4 chân nếu bare-IC):
- VCC → 3.3V hoặc 5V.
- DATA → bất kỳ chân digital, kèm điện trở pull-up 4.7–10kΩ lên VCC (module bán sẵn đã có sẵn).
- GND → GND.
Dây DATA không quá 20cm để giảm nhiễu, càng ngắn càng tốt.
3. Cài thư viện
Library Manager → tìm "DHT sensor library" by Adafruit. Khi cài sẽ hỏi cài kèm Adafruit Unified Sensor — chọn Install All.
4. Code đọc cơ bản
#include
#define PIN_DHT 2
#define DHT_TYPE DHT22 // DHT11, DHT21, DHT22
DHT dht(PIN_DHT, DHT_TYPE);
void setup() {
Serial.begin(115200);
dht.begin();
}
void loop() {
delay(2000); // DHT22 cần >2s giữa các lần đọc
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Loi doc DHT!");
return;
}
Serial.print("H="); Serial.print(h);
Serial.print("% T="); Serial.print(t); Serial.println("C");
}
Luôn kiểm tra isnan() — DHT trả NaN khi đọc lỗi (gần đầy bộ đệm, nhiễu, chưa đủ 2s).
5. Các hàm có sẵn
| Hàm | Trả về |
|---|---|
readTemperature() | °C (float) |
readTemperature(true) | °F (Fahrenheit) |
readHumidity() | % RH |
computeHeatIndex(t, h) | Chỉ số cảm nhận nhiệt (°C) |
6. Vấn đề blocking — DHT_nonblocking
Hàm readTemperature() blocking ~25 ms vì giao thức DHT là bit-banging 1-Wire single-pin. Trong các dự án cần response nhanh (motor, LED chasing), 25 ms gây giật.
Thư viện DHT_nonblocking giải quyết:
#include
DHT_nonblocking dht(2, DHT_SENSOR_DHT22);
void loop() {
float t, h;
if (dht.measure(&t, &h)) {
// Có data mới — xử lý
}
// Code khác chạy bình thường
}
7. Heat index — cảm giác nóng thực tế
Nhiệt độ kèm độ ẩm cao cho cảm giác nóng hơn nhiệt độ đo:
float t = dht.readTemperature();
float h = dht.readHumidity();
float heatIdx = dht.computeHeatIndex(t, h, false); // °C
Serial.print("Cam giac "); Serial.println(heatIdx);
8. Lỗi thường gặp và cách khắc phục
| Triệu chứng | Khắc phục |
|---|---|
| Luôn ra NaN | Sai chân, không có pull-up, hoặc đọc cách nhau < 2s |
| Giá trị nhảy loạn | Dây quá dài, nhiễu nguồn — thêm tụ 100nF gần VCC-GND |
| Độ ẩm "đứng yên 99%" | Cảm biến bị hơi nước ngưng tụ — sấy nhẹ bằng máy sấy ở chế độ mát, đặt ngoài trời 1 ngày |
| Nhiệt độ luôn cao hơn thực tế 2–3°C | DHT22 nóng do tự tỏa nhiệt khi cấp 5V liên tục — dùng 3.3V hoặc tắt cảm biến giữa các lần đọc |
| Module nóng | Module có LED chỉ thị mà không ngắt được — gỡ LED hoặc bóc nguồn cảm biến qua MOSFET |
9. Hơn DHT — BME280 và SHT3x
Nếu DHT22 chưa đủ tốt:
- BME280: nhiệt + ẩm + áp suất, I2C, ±1% RH, ±0.5°C. Giá ~60k.
- SHT31 / SHT35: I2C, ±0.2°C, ±2% RH, phản hồi nhanh < 1s. Giá ~120k.
- AHT20: rẻ (~30k), I2C, độ chính xác trung bình.
Bộ đôi BME280 + ESP32 là chuẩn vàng cho weather station nghiệp dư.
Liên quan
Xem dự án Đo nhiệt độ & độ ẩm DHT22 + OLED hoặc Trạm khí tượng BMP280 + DHT22 + OLED.