Đọc nhiệt độ và độ ẩm
Bài 3 trong khóa Robot Thế hệ 2 — Cảm nhận môi trường và kết nối IoT

G2 02 - Đọc nhiệt độ và độ ẩm
Linh kiện cần chuẩn bị
- 1 ESP32-S3 DevKit.
- 1 robot base Gen 1 dùng làm nền gắn cảm biến; bài này chưa cần chạy motor.
- 1 cảm biến SHT31 I2C, địa chỉ mặc định thường là
0x44. - 1 LED trạng thái và 1 điện trở 220 ohm nếu không dùng LED có sẵn trên board.
- 1 buzzer chủ động để báo lỗi đọc cảm biến.
- Dây jumper, breadboard nhỏ hoặc shield nối dây.
- Nguồn USB ổn định hoặc pin đã sạc.
- Máy tính có Arduino IDE hoặc Arduino CLI, cáp USB data, Serial Monitor.
- Bảng ghi dữ liệu gồm: thời gian, nhiệt độ, độ ẩm, trạng thái đọc, ghi chú điều kiện đo.
Code của bài chỉ dùng ESP32-S3, SHT31, LED, buzzer và Serial Monitor. Không dùng WiFi, OLED/TFT hay cảm biến khác trong bài này.
Bài này giúp bạn làm được gì?
Bạn sẽ đọc nhiệt độ và độ ẩm bằng SHT31, kiểm tra dữ liệu có hợp lệ hay không, rồi in log để nhóm có thể ghi bảng đo thật.
Kết quả cuối bài:
- ESP32-S3 đọc được nhiệt độ theo độ C.
- ESP32-S3 đọc được độ ẩm theo phần trăm.
- Code phát hiện được lỗi I2C hoặc lỗi CRC.
- Serial Monitor có hai chế độ log: dễ đọc và CSV.
- Nhóm có ít nhất 20 dòng dữ liệu nhiệt độ/độ ẩm thật.
Mục tiêu bài học
Sau bài này, bạn có thể:
- Nối SHT31 đúng chân SDA/SCL.
- Giải thích vì sao cảm biến I2C cần địa chỉ.
- Đọc dữ liệu SHT31 bằng
Wire.hmà không cần thư viện ngoài. - Kiểm tra lỗi dữ liệu trước khi tin vào con số.
- Tạo bảng dữ liệu nhiệt độ/độ ẩm để dùng trong G2 05.
Kiến thức rất ngắn
SHT31 gửi dữ liệu theo 2 phần: nhiệt độ và độ ẩm. Mỗi phần có thêm CRC để kiểm tra dữ liệu có bị lỗi trong lúc truyền không.
Nếu code không kiểm tra lỗi, robot có thể lấy một con số sai rồi đưa ra cảnh báo sai. Vì vậy bài này không chỉ đọc dữ liệu, mà còn học cách hỏi: dữ liệu này có đáng tin không?
Sơ đồ khối hệ thống
SHT31
-> I2C SDA/SCL
-> ESP32-S3 đọc raw bytes
-> kiểm CRC
-> đổi sang độ C và %
-> Serial Monitor / CSV
-> LED, buzzer báo trạng thái
Pin map đề xuất
| Chức năng | Chân ESP32-S3 | Ghi chú |
|---|---|---|
| SHT31 VIN | 3V3 | Không dùng 5V nếu breakout không hỗ trợ |
| SHT31 GND | GND | Phải chung GND với ESP32 |
| SHT31 SDA | GPIO8 | Dữ liệu I2C |
| SHT31 SCL | GPIO9 | Xung clock I2C |
| LED trạng thái | GPIO2 | Nháy khi đọc OK |
| Buzzer | GPIO15 | Kêu 2 nhịp khi đọc lỗi |
Thực hành từng bước
Bước 1: Kiểm tra dây I2C
Tắt nguồn trước khi cắm dây. Nối VIN -> 3V3, GND -> GND, SDA -> GPIO8, SCL -> GPIO9. Không để dây SCL/SDA vắt qua bánh xe hoặc motor vì sau này robot sẽ chạy.
Bước 2: Upload code đọc SHT31
Mở Serial Monitor 115200 baud. Log bình thường sẽ giống:
sht31 t_ms=3000 ok=YES temp_c=29.4 humidity_pct=68.2 mode=KEY_VALUE
Nếu thấy ok=NO, chưa vội sửa thuật toán. Hãy kiểm tra dây và nguồn trước.
Bước 3: Tác động nhẹ để thấy dữ liệu đổi
- Đặt cảm biến cách tay 5-10 cm, quan sát dữ liệu.
- Thổi nhẹ gần cảm biến trong 1-2 giây, độ ẩm thường tăng.
- Không chạm tay trực tiếp vào chip cảm biến vì nhiệt từ tay làm dữ liệu nhảy mạnh.
Bước 4: Bật CSV để ghi bảng
Gửi trong Serial Monitor:
CSV ON
Robot in header:
t_ms,temp_c,humidity_pct,ok,error_count
Copy 20 dòng vào bảng. Khi muốn quay lại log dễ đọc, gửi:
CSV OFF
Code mẫu hoàn chỉnh
Code đầy đủ nằm trong file:
code/g2-02-doc-nhiet-do-va-do-am/g2-02-doc-nhiet-do-va-do-am.ino
Phần chuyển đổi dữ liệu SHT31:
uint16_t rawT = ((uint16_t)buffer[0] << 8) | buffer[1];
uint16_t rawH = ((uint16_t)buffer[3] << 8) | buffer[4];
temperatureC = -45.0 + 175.0 * rawT / 65535.0;
humidityPct = 100.0 * rawH / 65535.0;
Giải thích code theo từng khối
| Khối code | Vai trò | Dấu hiệu đúng |
|---|---|---|
Wire.begin() | Mở bus I2C trên GPIO8/GPIO9 | SHT31 trả lời ở địa chỉ 0x44 |
crc8() | Kiểm tra dữ liệu nhận được | Lỗi dây thường làm ok=NO |
readSht31() | Gửi lệnh đo và đọc 6 byte | Có nhiệt độ/độ ẩm hợp lý |
csvMode | Chuyển giữa log dễ đọc và CSV | CSV ON, CSV OFF hoạt động |
errorCount | Đếm số lần đọc lỗi | Tăng khi rút cảm biến hoặc sai dây |
Kiểm thử robot thật
| Test | Thao tác | Kết quả mong đợi | Pass? |
|---|---|---|---|
| 1 | Boot với SHT31 đã nối | ok=YES trong 5 giây đầu | |
| 2 | Thổi nhẹ gần cảm biến | Độ ẩm tăng rồi giảm dần | |
| 3 | Che cảm biến bằng tay ở khoảng cách gần | Nhiệt độ thay đổi nhẹ | |
| 4 | Gửi CSV ON | Có header CSV và dòng dữ liệu | |
| 5 | Rút SDA rồi reset | ok=NO, buzzer báo lỗi | |
| 6 | Cắm lại dây đúng | ok=YES trở lại |
Bảng dữ liệu mẫu cần ghi
| Lần đo | Thời gian ms | Nhiệt độ C | Độ ẩm % | Điều kiện đo | Nhận xét |
|---|---|---|---|---|---|
| 1 | Bình thường | ||||
| 2 | Thổi nhẹ | ||||
| 3 | Để yên 30 giây |
Lỗi thường gặp và cách sửa
| Lỗi | Nguyên nhân hay gặp | Cách sửa |
|---|---|---|
ok=NO liên tục | Sai SDA/SCL, thiếu nguồn hoặc sai địa chỉ | Kiểm tra pin map, đo 3.3V, thử địa chỉ 0x44 |
| Dữ liệu nhảy mạnh | Cầm tay vào cảm biến hoặc đặt gần hơi nóng | Gắn cảm biến thoáng, không chạm chip |
| Độ ẩm luôn 0 hoặc 100 | Dữ liệu raw lỗi hoặc CRC fail bị bỏ qua | Chỉ dùng dữ liệu khi ok=YES |
| Serial không hiện gì | Sai baud hoặc cáp không phải data | Chọn 115200 baud, đổi cáp |
| Buzzer kêu khi vẫn có số | Code đang phát hiện CRC/I2C lỗi ngắt quãng | Rút ngắn dây I2C, cắm chắc jumper |
Checklist debug
- SHT31 dùng 3.3V và GND chung.
- SDA/SCL đúng GPIO8/GPIO9.
- Serial có
ok=YES. - Có ít nhất 20 dòng dữ liệu thật.
- Biết giải thích khi nào không nên tin dữ liệu.
Thử thách nhỏ
Thêm cảnh báo Serial khi humidity_pct > 80. Chỉ in cảnh báo khi ok=YES, không cảnh báo khi cảm biến lỗi.
Checklist hoàn thành
- Đọc được nhiệt độ và độ ẩm từ SHT31.
- Có xử lý lỗi I2C/CRC.
- Có log dạng dễ đọc và CSV.
- Có bảng dữ liệu thật.
- Sẵn sàng chuyển sang cảm biến ánh sáng ở G2 03.
Bài tiếp theo
G2 03 sẽ dùng mạch LDR đơn giản để đo ánh sáng, sau đó phân vùng dữ liệu thành DARK, NORMAL, BRIGHT.
Điều hướng bài học
Bài tiếp theo: G2 03 - Đọc ánh sáng và phân vùng dữ liệu
Bài trước: G2 01 - Robot cảm nhận môi trường là gì