Cảm biến độ ẩm: điện dung, điện trở, ẩm kế khô ướt – cấu tạo, nguyên lý, chế tạo và điểm sương
Cảm biến độ ẩm hoạt động thế nào: độ ẩm tương đối, tuyệt đối, điểm sương; cảm biến điện dung polyme, điện trở, ẩm kế tóc, khô ướt, gương lạnh; chế tạo và đọc SHT31 bằng ESP32.
Độ ẩm ảnh hưởng tới sức khỏe, chất lượng hàng hóa và độ bền thiết bị: kho thuốc, kho nông sản, phòng sạch, nhà kính trồng rau, tủ chống ẩm máy ảnh, máy lạnh, máy sấy đều cần đo độ ẩm. Cảm biến độ ẩm phổ biến nhất hiện nay là một con chip nhỏ có lớp polyme hút hơi nước, nhưng trước đó người ta đã đo độ ẩm bằng sợi tóc, bằng hai nhiệt kế khô ướt và bằng một tấm gương được làm lạnh. Bài viết giải thích các đại lượng độ ẩm, cấu tạo và nguyên lý của cảm biến điện dung, điện trở và các dụng cụ cổ điển, quy trình chế tạo cảm biến dạng chip, rồi hướng dẫn đọc SHT31 bằng ESP32, kiểm tra CRC và tính điểm sương.
1. Độ ẩm tương đối, độ ẩm tuyệt đối và điểm sương

- Độ ẩm tương đối (%RH): áp suất hơi nước đang có chia cho áp suất hơi nước bão hòa ở cùng nhiệt độ. Đây là con số trên đồng hồ đo ẩm và cũng là đại lượng các cảm biến điện tử đo trực tiếp.
- Độ ẩm tuyệt đối (g/m³): khối lượng hơi nước trong một mét khối không khí. Không khí 30 °C, 70 %RH chứa khoảng 21,2 g/m³.
- Điểm sương: nhiệt độ mà không khí phải được làm lạnh tới (giữ nguyên lượng hơi nước) để bắt đầu ngưng tụ. Với 30 °C, 70 %RH, điểm sương khoảng 23,9 °C: một lon nước lạnh hơn 23,9 °C sẽ "đổ mồ hôi".
Cùng một lượng hơi nước, khi nhiệt độ tăng thì độ ẩm tương đối giảm. Vì vậy cảm biến độ ẩm luôn đo cả nhiệt độ, và phải đặt sao cho nhiệt độ của nó bằng nhiệt độ không khí cần đo; chỉ chênh 1 °C ở khoảng 50 %RH đã làm số đọc lệch khoảng 3 %RH.
Công thức Magnus tính áp suất hơi nước bão hòa (hPa): es = 6,112 × exp(17,62 × T / (243,12 + T)). Từ đó: điểm sương Td = 243,12 × γ / (17,62 − γ) với γ = ln(RH/100) + 17,62 × T / (243,12 + T); độ ẩm tuyệt đối = 216,7 × e / (273,15 + T) với e = RH/100 × es.
2. Đo độ ẩm trước thời điện tử

- Ẩm kế tóc: tóc người (đã tẩy dầu) dài thêm khoảng 2 đến 3 % khi độ ẩm tăng từ 0 lên 100 %. Một bó tóc căng giữa giá đỡ và cần kim. Không cần điện, nhưng chậm, trễ và phải chỉnh lại định kỳ. Nhiều đồng hồ ẩm cơ khí treo tường ngày nay dùng dải vật liệu tổng hợp thay tóc.
- Ẩm kế khô ướt: hai nhiệt kế giống nhau, một bọc vải tẩm nước. Nước bốc hơi làm lạnh nhiệt kế ướt; không khí càng khô, bốc hơi càng mạnh, chênh lệch càng lớn. Tra bảng (hoặc dùng công thức) ra độ ẩm. Loại quay tay cho luồng gió đều qua bầu ướt.
- Ẩm kế gương lạnh: một tấm gương được làm lạnh bằng phần tử Peltier tới khi xuất hiện lớp sương (phát hiện bằng tia sáng phản xạ). Nhiệt độ gương lúc đó chính là điểm sương. Chính xác nhất, dùng làm chuẩn để hiệu chuẩn các cảm biến khác.
3. Cảm biến độ ẩm điện dung

Phần tử cảm biến là một tụ điện nhỏ: điện cực dưới, một lớp polyme mỏng (thường là polyimide dày vài micromet) và điện cực trên dạng xốp hoặc răng lược để hơi nước đi qua. Polyme hút và nhả hơi nước theo độ ẩm môi trường cho tới khi cân bằng. Vì nước có hằng số điện môi khoảng 80 còn polyme khô chỉ khoảng 3 đến 4, mỗi phần trăm độ ẩm làm điện dung tăng thêm một lượng nhỏ nhưng đều đặn. Trong các cảm biến số như SHT3x, HDC1080, BME280, tụ điện này được chế tạo ngay trên con chip có mạch đo điện dung, cảm biến nhiệt độ, bộ chuyển đổi số và bộ nhớ chứa hệ số hiệu chuẩn.

- Ưu điểm: đo được 0 đến 100 %RH, sai số khoảng ±2 %RH ở loại tốt, đáp ứng vài giây, ít tiêu thụ điện.
- Độ trễ: số đọc khi độ ẩm đang tăng và đang giảm lệch nhau khoảng 1 %RH.
- Nhiễm bẩn: hơi dung môi, keo, sơn, cồn có thể ngấm vào polyme và làm lệch số đọc; nhiều hãng hướng dẫn sấy chip ở nhiệt độ cao rồi để hồi ẩm để phục hồi.
- Ngưng tụ: nước đọng trên chip làm số đọc kẹt ở 100 % cho tới khi khô; nơi hay đọng sương nên dùng loại có bộ sưởi trong chip hoặc màng lọc PTFE.
4. Các loại khác

- Điện trở: lớp muối hút ẩm hoặc polyme dẫn điện giữa hai điện cực răng lược; điện trở giảm theo hàm mũ khi độ ẩm tăng. Rẻ nhưng sai số lớn (khoảng ±5 %RH), dải đo hẹp; cảm biến DHT11 thuộc loại này. Phải đo bằng điện xoay chiều để không phân cực lớp muối.
- Độ ẩm đất: các que cắm đất đo điện trở (dễ bị ăn mòn) hoặc điện dung (bền hơn) giữa hai bản cực; kết quả phụ thuộc loại đất, chỉ nên dùng để so sánh "khô hơn, ướt hơn" và đặt ngưỡng tưới.

5. Chế tạo cảm biến độ ẩm điện dung dạng chip

- Tấm silic CMOS: chế tạo mạch đo điện dung, cảm biến nhiệt độ bán dẫn, bộ chuyển đổi số, bộ nhớ và giao tiếp I2C như một vi mạch thông thường.
- Điện cực và polyme: phủ điện cực dưới, quay phủ lớp polyimide và nung đóng rắn, rồi phủ điện cực trên dạng xốp hoặc răng lược.
- Đóng vỏ: vỏ nhựa nhỏ (vài milimét) chừa cửa sổ hở ngay trên lớp polyme; loại dùng ngoài trời có thêm màng PTFE chống bụi và nước nhưng cho hơi nước đi qua.
- Hiệu chuẩn: đưa hàng nghìn chip vào buồng khí hậu, giữ ở nhiều mức độ ẩm và nhiệt độ chuẩn, đo từng chip rồi ghi hệ số bù vào bộ nhớ của chính chip đó. Nhờ vậy người dùng không phải hiệu chuẩn.
- Ổn định: lớp polyme mới có độ trôi ban đầu; chip được sấy và để ổn định trước khi xuất xưởng.
- Kiểm tra: lấy mẫu so với ẩm kế gương lạnh, đo độ trễ và thời gian đáp ứng.
6. Thực hành: đọc SHT31 bằng ESP32 và tính điểm sương
Linh kiện
- ESP32 DevKit V1 30 chân.
- Một module cảm biến nhiệt độ, độ ẩm SHT31 (giao tiếp I2C, chạy 3,3 V).
- Dây cắm.
Sơ đồ nối và các byte trao đổi

| SHT31 | ESP32 |
|---|---|
| VIN, GND | 3V3, GND |
| SDA, SCL | GPIO21, GPIO22 |
| ADDR | GND (địa chỉ 0x44); nối VIN thì địa chỉ là 0x45 |
Chương trình
Chương trình chỉ dùng thư viện Wire: gửi lệnh đo một lần 0x2400, chờ 16 ms, đọc 6 byte, kiểm tra CRC của từng giá trị rồi đổi ra nhiệt độ, độ ẩm.
/*
PYWORLD.VN - Cảm biến độ ẩm điện dung SHT31 với ESP32: đọc qua I2C bằng Wire, kiểm tra CRC-8, tính điểm sương
SHT31: VIN = 3V3, GND = GND, SDA = GPIO21, SCL = GPIO22, chân ADDR nối GND (địa chỉ 0x44)
In nhiệt độ, độ ẩm tương đối, điểm sương (công thức Magnus) và độ ẩm tuyệt đối (g/m³)
*/
#include <Wire.h>
#include <math.h>
#define CHAN_SDA 21
#define CHAN_SCL 22
const uint8_t DIA_CHI_SHT31 = 0x44;
const uint16_t LENH_DO_MOT_LAN = 0x2400; // Đo một lần, độ lặp lại cao, không kéo dài xung SCL
const float MAGNUS_B = 17.62;
const float MAGNUS_C = 243.12; // °C
// CRC-8 của SHT3x: đa thức 0x31, giá trị đầu 0xFF
uint8_t tinhCrc(const uint8_t *duLieu, int n) {
uint8_t crc = 0xFF;
for (int i = 0; i < n; i++) {
crc ^= duLieu[i];
for (int b = 0; b < 8; b++) {
crc = (crc & 0x80) ? (uint8_t)((crc << 1) ^ 0x31) : (uint8_t)(crc << 1);
}
}
return crc;
}
bool docSht31(float *nhietDo, float *doAm) {
Wire.beginTransmission(DIA_CHI_SHT31);
Wire.write(LENH_DO_MOT_LAN >> 8);
Wire.write(LENH_DO_MOT_LAN & 0xFF);
if (Wire.endTransmission() != 0) {
return false;
}
delay(16); // Thời gian đo tối đa khoảng 15 ms
if (Wire.requestFrom(DIA_CHI_SHT31, (uint8_t)6) != 6) {
return false;
}
uint8_t b[6];
for (int i = 0; i < 6; i++) {
b[i] = Wire.read();
}
// Mỗi giá trị 16 bit đi kèm 1 byte CRC
if (tinhCrc(b, 2) != b[2] || tinhCrc(b + 3, 2) != b[5]) {
return false;
}
uint16_t thoT = (b[0] << 8) | b[1];
uint16_t thoRh = (b[3] << 8) | b[4];
*nhietDo = -45.0f + 175.0f * thoT / 65535.0f;
*doAm = 100.0f * thoRh / 65535.0f;
return true;
}
void setup() {
Serial.begin(115200);
Wire.begin(CHAN_SDA, CHAN_SCL, 100000);
Serial.println("\nSHT31: nhiet do, do am, diem suong");
}
void loop() {
float t, rh;
if (!docSht31(&t, &rh)) {
Serial.println("Khong doc duoc SHT31 hoac sai CRC: kiem tra day va dia chi 0x44");
delay(2000);
return;
}
// Điểm sương theo công thức Magnus: gamma = ln(RH/100) + b·T/(c+T); Td = c·gamma / (b - gamma)
float gamma = logf(rh / 100.0f) + MAGNUS_B * t / (MAGNUS_C + t);
float diemSuong = MAGNUS_C * gamma / (MAGNUS_B - gamma);
// Độ ẩm tuyệt đối từ áp suất hơi nước (hPa): e = RH/100 × 6,112 × exp(b·T/(c+T))
float apHoi = rh / 100.0f * 6.112f * expf(MAGNUS_B * t / (MAGNUS_C + t));
float doAmTuyetDoi = 216.7f * apHoi / (273.15f + t);
Serial.printf("Nhiet do %.2f C | Do am %.1f %%RH | Diem suong %.1f C | %.1f g/m3\n", t, rh, diemSuong, doAmTuyetDoi);
delay(2000);
}
Giải thích
- Mỗi giá trị 16 bit đi kèm một byte CRC-8 (đa thức 0x31, giá trị đầu 0xFF). Sai CRC nghĩa là dữ liệu bị nhiễu trên đường truyền; chương trình bỏ lần đọc đó.
- Nhiệt độ = −45 + 175 × giá trị thô / 65535; độ ẩm = 100 × giá trị thô / 65535 (theo datasheet SHT3x).
- Điểm sương và độ ẩm tuyệt đối tính theo công thức Magnus ở mục 1.
- Đọc mỗi 2 giây. Đo quá dày làm chip tự nóng lên một chút và độ ẩm đọc thấp đi.
Kết quả mong đợi

Đặt module xa ESP32 và bộ nguồn (các linh kiện này ấm lên), tránh nắng chiếu trực tiếp. Muốn đo ngoài trời, đặt cảm biến trong hộp chắn bức xạ có khe thông gió.
7. Xử lý lỗi thường gặp
| Hiện tượng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| "Khong doc duoc SHT31" | Sai địa chỉ (ADDR nối VIN), sai chân SDA, SCL | Chạy chương trình quét I2C; đổi địa chỉ thành 0x45 nếu cần |
| Thỉnh thoảng sai CRC | Dây I2C dài, nhiễu | Rút ngắn dây, giảm tốc độ I2C, thêm điện trở kéo lên 4,7 kΩ |
| Độ ẩm thấp hơn đồng hồ khác vài % | Cảm biến bị ấm do đặt gần ESP32, nguồn | Đưa cảm biến ra xa, để thoáng gió |
| Độ ẩm kẹt ở 100 % | Nước đọng trên chip | Để khô; nơi hay đọng sương dùng loại có màng lọc hoặc bộ sưởi |
| Số đọc trôi dần sau khi sơn, dán keo gần đó | Hơi dung môi ngấm vào polyme | Thông gió, sấy theo hướng dẫn của hãng, tránh dung môi |
8. Xem thêm
- I2C là gì: địa chỉ, ACK và cách đọc ghi trên ESP32.
- Kiểm tra lỗi truyền dữ liệu: bit chẵn lẻ, checksum và CRC.
- Đồng hồ đo nhiệt độ và độ ẩm mini của shop, tiện để so sánh số đọc.
- Các bài khác trong loạt: cảm biến nhiệt độ, cảm biến tiệm cận điện dung.
Xem thêm