IoTLabs

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

Series ESP32 & Cảm biến: Bài 17 – Đọc cảm biến BME280: đo nhiệt độ/độ ẩm/áp suất & theo dõi realtime

Sau khi làm việc với BMP280, chúng ta nâng cấp lên BME280 – cảm biến 3-trong-1 đo nhiệt độ, độ ẩm và áp suất khí quyển, rất phổ biến trong các hệ IoT môi trường và trạm thời tiết.

Bài này giúp bạn:

  • Đọc 3 loại dữ liệu từ 1 cảm biến I2C
  • Chuẩn hoá payload multi-metric
  • Gửi dữ liệu realtime lên IoTLabs Cloud MQTT

1. Giới thiệu cảm biến BME280

BME280 là phiên bản mở rộng của BMP280 do Bosch phát triển.

Thông số chính:

  • Giao tiếp: I2C / SPI (bài này dùng I2C)
  • Nhiệt độ: -40 → 85 °C
  • Độ ẩm: 0 → 100 %
  • Áp suất: ~300 → 1100 hPa
  • Địa chỉ I2C: 0x76 hoặc 0x77

👉 BME280 = BMP280 + cảm biến độ ẩm.

2. Khi nào nên dùng BME280?

BME280 rất phù hợp cho:

  • Trạm thời tiết DIY
  • Giám sát môi trường phòng
  • Nhà kính, kho, nông nghiệp
  • Hệ IoT cần đầy đủ dữ liệu môi trường

Nếu bạn muốn 1 sensor – nhiều dữ liệu, BME280 là lựa chọn hợp lý.

3. Chuẩn bị phần cứng & nối dây

Thiết bị

  • ESP32-C3 SuperMini
  • BME280 (module I2C)

Kết nối I2C (chuẩn series)

BME280ESP32-C3
VCC3.3 V
GNDGND
SDAGPIO8
SCLGPIO9

4. Kiểm tra địa chỉ I2C

Luôn kiểm tra trước khi code.

#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin(8, 9);
}

void loop() {
  for (byte addr = 1; addr < 127; addr++) {
    Wire.beginTransmission(addr);
    if (Wire.endTransmission() == 0) {
      Serial.print("Found I2C device at 0x");
      Serial.println(addr, HEX);
    }
  }
  delay(5000);
}

👉 Thấy 0x76 hoặc 0x77 là OK.


5. Ví dụ 1: Đọc BME280 local (Serial)

Thư viện

  • Adafruit BME280 Library

Code mẫu

#include <Wire.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme;

void setup() {
  Serial.begin(115200);
  Wire.begin(8, 9);

  if (!bme.begin(0x76)) {
    Serial.println("BME280 not found");
    while (1) delay(10);
  }
  Serial.println("BME280 ready");
}

void loop() {
  float temp = bme.readTemperature();
  float hum  = bme.readHumidity();
  float pres = bme.readPressure() / 100.0; // hPa

  Serial.print("Temp: ");
  Serial.print(temp, 1);
  Serial.print(" °C | Humidity: ");
  Serial.print(hum, 1);
  Serial.print(" % | Pressure: ");
  Serial.print(pres, 1);
  Serial.println(" hPa");

  delay(2000);
}

6. Chuẩn payload gửi IoTLabs Cloud

{
  "ts": 1760000000,
  "metrics": {
    "temperature": 26.7,
    "humidity": 62.1,
    "pressure": 1007.9
  }
}

📌 Đây là payload multi-metric hoàn chỉnh cho IoT môi trường.

7. Ví dụ 2: Gửi dữ liệu BME280 realtime qua MQTT

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme;

// ===== 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-bme280", MQTT_USER, MQTT_PASS);
    delay(1000);
  }
}

void setup() {
  Serial.begin(115200);
  Wire.begin(8, 9);
  bme.begin(0x76);

  connectWiFi();
  connectMQTT();
}

void loop() {
  if (!mqtt.connected()) connectMQTT();
  mqtt.loop();

  if (millis() - lastSend > 5000) {
    lastSend = millis();

    float t = bme.readTemperature();
    float h = bme.readHumidity();
    float p = bme.readPressure() / 100.0;

    long ts = millis() / 1000;

    String payload = "{";
    payload += "\"ts\":" + String(ts) + ",";
    payload += "\"metrics\":{";
    payload += "\"temperature\":" + String(t, 1) + ",";
    payload += "\"humidity\":" + String(h, 1) + ",";
    payload += "\"pressure\":" + String(p, 1);
    payload += "}}";

    mqtt.publish(MQTT_TOPIC, payload.c_str());
    Serial.println(payload);
  }
}

8. Kinh nghiệm thực tế khi dùng BME280

  • Đặt cảm biến xa nguồn nhiệt
  • Không cần gửi quá nhanh (5–10 s là đủ)
  • Rất phù hợp cho dashboard realtime + biểu đồ lịch sử
  • Nếu không cần độ ẩm → dùng BMP280 sẽ tiết kiệm hơn

9. Tổng kết Bài 17

Sau bài này, bạn đã:

  • Đọc 3 chỉ số môi trường từ 1 cảm biến
  • Chuẩn hoá payload IoT hoàn chỉnh
  • Xây dựng nền tảng cho trạm thời tiết IoT

👉 Bài tiếp theo:

Bài 18 – Hướng dẫn đọc DS3231 (RTC) bằng ESP32: giữ thời gian chính xác & theo dõi realtime