Trong bài này, chúng ta nâng cấp từ DHT11 lên DHT22 (AM2302) để đo nhiệt độ/độ ẩm chính xác hơn, sau đó gửi dữ liệu realtime lên IoTLabs Cloud qua MQTT.
DHT22 không phải I2C, nhưng rất đáng học vì là bước “nâng cấp hợp lý” trước khi chuyển sang các cảm biến I2C ổn định hơn như AHT20 và SHT31.
Bài viết gồm 2 ví dụ code:
- Đọc DHT22 local (Serial)
- Gửi dữ liệu nhiệt độ/độ ẩm realtime lên IoTLabs Cloud MQTT
1. DHT22 khác gì DHT11?
| Tiêu chí | DHT11 | DHT22 (AM2302) |
|---|---|---|
| Nhiệt độ | 0–50°C | -40–80°C |
| Độ ẩm | 20–90% | 0–100% |
| Độ chính xác | Thấp | Tốt hơn |
| Độ phân giải | Thấp | Cao hơn |
| Giá | Rẻ | Cao hơn chút |
👉 Nếu bạn muốn dự án “đo đàng hoàng” nhưng vẫn rẻ và dễ mua, DHT22 là lựa chọn hợp lý.
2. Chuẩn bị & nối dây
Phần cứng
- ESP32-C3 SuperMini
- DHT22 (AM2302) dạng module hoặc dạng rời
Kết nối (khuyến nghị)
| DHT22 | ESP32-C3 |
|---|---|
| VCC | 3.3V |
| DATA | GPIO4 |
| GND | GND |
Nếu dùng DHT22 dạng rời (4 chân), cần điện trở kéo lên 10kΩ từ DATA lên VCC.
3. Thư viện sử dụng
Giống Bài 12:
- DHT sensor library (Adafruit)
- Adafruit Unified Sensor
4. Ví dụ 1 — Đọc DHT22 local (Serial)
#include <DHT.h>
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
dht.begin();
}
void loop() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read DHT22");
delay(2000);
return;
}
Serial.print("Temp: ");
Serial.print(temperature, 1);
Serial.print(" °C | Humidity: ");
Serial.print(humidity, 1);
Serial.println(" %");
delay(2000); // DHT22 cũng nên đọc chậm
}
📌 Tip: DHT22 vẫn nên đọc 2 giây/lần để ổn định.
5. Chuẩn payload realtime (giống toàn series)
{
"ts": 1760000000,
"metrics": {
"temperature": 28.6,
"humidity": 64.3
}
}
6. Ví dụ 2 — Gửi dữ liệu DHT22 lên IoTLabs Cloud MQTT
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <DHT.h>
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// ===== CONFIG =====
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_PASS";
const char* MQTT_HOST = "mqtt.iotlabs.vn";
const int MQTT_PORT = 8883;
const char* MQTT_USER = "YOUR_MQTT_USER";
const char* MQTT_PASS = "YOUR_MQTT_PASS";
const char* MQTT_TOPIC =
"iotlabs/<orgId>/devices/<deviceId>/telemetry";
WiFiClientSecure net;
PubSubClient mqtt(net);
unsigned long lastSend = 0;
void connectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
}
void connectMQTT() {
net.setInsecure();
mqtt.setServer(MQTT_HOST, MQTT_PORT);
while (!mqtt.connected()) {
mqtt.connect("esp32c3-dht22", MQTT_USER, MQTT_PASS);
delay(1000);
}
}
void setup() {
Serial.begin(115200);
dht.begin();
connectWiFi();
connectMQTT();
}
void loop() {
if (!mqtt.connected()) connectMQTT();
mqtt.loop();
if (millis() - lastSend > 5000) {
lastSend = millis();
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) return;
long ts = millis() / 1000;
String payload = "{";
payload += "\"ts\":" + String(ts) + ",";
payload += "\"metrics\":{";
payload += "\"temperature\":" + String(t, 1) + ",";
payload += "\"humidity\":" + String(h, 1);
payload += "}}";
mqtt.publish(MQTT_TOPIC, payload.c_str());
Serial.println(payload);
}
}
7. Kinh nghiệm thực tế (để đo ổn định hơn)
- Tránh đặt sát nguồn nóng (board, regulator, USB)
- Đặt cảm biến thông thoáng
- Nếu số đo “nhảy”, hãy:
- Lấy trung bình 3 lần đọc
- Gửi MQTT chậm hơn (5–10s)
8. Khi nào nên bỏ DHT22 để lên I2C?
Nếu bạn muốn:
- Đo ổn định chạy lâu
- Ít lỗi đọc
- Dự án “production” hơn
👉 Chuyển sang:
- AHT20 (Bài 14): ổn định, I2C, đáng tiền
- SHT31 (Bài 15): chất lượng cao, đo rất mượt
9. Tổng kết Bài 13
Sau bài này, bạn đã:
- Nâng cấp cảm biến nhiệt/ẩm từ DHT11 → DHT22
- Đọc 2 metric chính xác hơn
- Gửi dữ liệu realtime lên IoTLabs Cloud MQTT
👉 Bài tiếp theo: Bài 14 – Hướng dẫn đọc cảm biến AHT20 bằng ESP32: đo nhiệt độ/độ ẩm ổn định & theo dõi realtime (I2C “đúng nghĩa”)


