Cảm biếnMQTT

Trạm thời tiết ESP32 + BME280 gửi MQTT

Độ khó: dễ · Thời gian: ~1 giờ · Chi phí: ~150–200k VNĐ

Dự án đo nhiệt độ, độ ẩm và áp suất khí quyển, định kỳ gửi lên MQTT broker (ví dụ Mosquitto trong Home Assistant). Giữa các lần đo ESP32 ngủ sâu để tiết kiệm pin.

Linh kiện

Sơ đồ nối dây

BME280ESP32
VIN / VCC3V3
GNDGND
SDAGPIO21
SCLGPIO22

Địa chỉ I2C thường là 0x76 (hoặc 0x77 tùy module). Nếu cảm biến không được nhận, hãy chạy thử sketch I2C scanner.

Thư viện cần cài (Arduino IDE)

Mã nguồn

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

const char* WIFI_SSID = "ten_wifi";
const char* WIFI_PASS = "mat_khau";
const char* MQTT_HOST = "192.168.1.10";
const uint16_t MQTT_PORT = 1883;
const char* TOPIC = "esp32diy/tram1";

const uint64_t SLEEP_US = 5ULL * 60ULL * 1000000ULL;  // 5 phút

Adafruit_BME280 bme;
WiFiClient net;
PubSubClient mqtt(net);

void goSleep() {
  WiFi.disconnect(true);
  esp_sleep_enable_timer_wakeup(SLEEP_US);
  esp_deep_sleep_start();
}

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  if (!bme.begin(0x76)) {
    Serial.println("Khong thay BME280!");
    goSleep();
  }

  // Chế độ "forced": đo 1 lần rồi tự về sleep, ít tốn điện
  bme.setSampling(Adafruit_BME280::MODE_FORCED);
  bme.takeForcedMeasurement();
  float t = bme.readTemperature();
  float h = bme.readHumidity();
  float p = bme.readPressure() / 100.0F;

  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  uint32_t t0 = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - t0 < 15000) delay(100);
  if (WiFi.status() != WL_CONNECTED) goSleep();

  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  if (mqtt.connect("esp32diy-tram1")) {   // thêm user/pass nếu broker yêu cầu
    char buf[32];
    snprintf(buf, sizeof buf, "%.2f", t); mqtt.publish("esp32diy/tram1/nhiet_do", buf, true);
    snprintf(buf, sizeof buf, "%.2f", h); mqtt.publish("esp32diy/tram1/do_am", buf, true);
    snprintf(buf, sizeof buf, "%.1f", p); mqtt.publish("esp32diy/tram1/ap_suat", buf, true);
    mqtt.loop();
    delay(100);  // cho gói tin kịp gửi đi
  }
  goSleep();
}

void loop() {}   // không bao giờ chạy tới đây

Khai báo trong Home Assistant

Thêm vào configuration.yaml (cần đã cài tích hợp MQTT):

mqtt:
  sensor:
    - name: "Nhiệt độ ngoài trời"
      state_topic: "esp32diy/tram1/nhiet_do"
      unit_of_measurement: "°C"
      device_class: temperature
    - name: "Độ ẩm ngoài trời"
      state_topic: "esp32diy/tram1/do_am"
      unit_of_measurement: "%"
      device_class: humidity
    - name: "Áp suất"
      state_topic: "esp32diy/tram1/ap_suat"
      unit_of_measurement: "hPa"
      device_class: atmospheric_pressure
Mẹo: publish với cờ retain = true để Home Assistant luôn có giá trị gần nhất khi khởi động lại, không phải đợi 5 phút.

Cải tiến tiếp theo