IoTLabs

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

Series ESP32 & Cảm biến: Bài 11 – Hướng dẫn đọc cảm biến BH1750: đo độ sáng (Lux) & theo dõi realtime

Trong bài này, chúng ta sử dụng cảm biến ánh sáng BH1750 để đo độ sáng môi trường theo đơn vị Lux, sau đó gửi dữ liệu realtime lên IoTLabs Cloud qua MQTT.
Đây là cảm biến I2C rất phổ biến, chính xác và ổn định, thường được dùng thay thế cho LDR trong các dự án IoT thực tế.

Bài viết gồm 2 phần chính:

  1. Đọc cảm biến BH1750 local (Serial)
  2. Gửi dữ liệu độ sáng (Lux) lên IoTLabs Cloud MQTT để theo dõi realtime

1. Vì sao nên dùng BH1750 thay cho LDR?

Level 1, bạn đã dùng LDR để làm quen với ánh sáng.
Sang Level 2, BH1750 mang lại nhiều lợi thế rõ rệt:

Tiêu chíLDRBH1750
Chuẩn đoTương đốiLux (chuẩn)
Giao tiếpAnalogI2C
Độ ổn địnhThấpCao
NhiễuNhiềuÍt
Phù hợp IoTDemoThực tế

👉 BH1750 là cảm biến ánh sáng “chuẩn IoT”.

2. Giới thiệu cảm biến BH1750

  • BH1750 là cảm biến đo độ sáng môi trường
  • Trả về giá trị Lux trực tiếp (không cần tự tính)
  • Giao tiếp I2C
  • Địa chỉ I2C phổ biến:
    • 0x23 (mặc định)
    • 0x5C (tuỳ module)

📌 Rất phù hợp cho:

  • Smart home
  • Trạm thời tiết
  • Điều khiển đèn tự động
  • Giám sát môi trường ánh sáng

3. Chuẩn bị

Phần cứng

  • ESP32-C3 SuperMini (Tenstar Robot)
  • Cảm biến BH1750 (GY-30)
  • Breadboard + dây nối

Chân kết nối (I2C)

BH1750ESP32-C3
VCC3.3V
GNDGND
SDAGPIO8
SCLGPIO9

📌 ESP32-C3 cho phép gán I2C linh hoạt
Ở series này, quy ước: SDA = GPIO8, SCL = GPIO9

4. Kiểm tra bus I2C (rất quan trọng)

Trước khi đọc cảm biến, luôn scan I2C để chắc chắn thiết bị hoạt động.

#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin(8, 9); // SDA, SCL
  Serial.println("I2C scan...");
}

void loop() {
  byte count = 0;
  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);
      count++;
    }
  }
  Serial.println("Scan done");
  delay(5000);
}

👉 Nếu thấy 0x23 hoặc 0x5C → OK.

5. Ví dụ 1 — Đọc BH1750 local (Serial)

Thư viện sử dụng

  • BH1750 (by Christopher Laws)

Code đọc Lux

#include <Wire.h>
#include <BH1750.h>

BH1750 lightMeter;

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

  if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
    Serial.println("BH1750 started");
  } else {
    Serial.println("BH1750 not found");
  }
}

void loop() {
  float lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx");

  delay(1000);
}

6. Chuẩn dữ liệu realtime

MQTT topic

iotlabs/<orgId>/devices/<deviceId>/telemetry

Payload JSON

{
  "ts": 1760000000,
  "metrics": {
    "lux": 320
  }
}

7. Ví dụ 2 — Gửi dữ liệu Lux lên IoTLabs Cloud MQTT

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

BH1750 lightMeter;

// ===== 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(400);
  }
}

void connectMQTT() {
  net.setInsecure();
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  while (!mqtt.connected()) {
    mqtt.connect("esp32c3-bh1750", MQTT_USER, MQTT_PASS);
    delay(1000);
  }
}

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

  connectWiFi();
  connectMQTT();
}

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

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

    float lux = lightMeter.readLightLevel();
    long ts = millis() / 1000;

    String payload = "{";
    payload += "\"ts\":" + String(ts) + ",";
    payload += "\"metrics\":{\"lux\":" + String(lux, 1) + "}";
    payload += "}";

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

8. Ứng dụng thực tế

  • Bật/tắt đèn theo ánh sáng
  • Smart home
  • Trạm thời tiết
  • Theo dõi môi trường làm việc

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

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

  • Làm chủ I2C cơ bản
  • Đọc sensor chuẩn Lux
  • Gửi dữ liệu multi-sensor friendly
  • Sẵn sàng đọc nhiều cảm biến chung bus