Sensors Integration - Giác quan của Jarvis

AI Hunter

Member
Nhiệm vụ hôm nay:
1. Đọc dữ liệu nhiệt độ/độ ẩm từ cảm biến DHT11.
2. Gửi dữ liệu này lên MQTT Server mỗi 5 giây/lần.
3. Kiểm tra xem Server có nhận được không.

Sensors Integration - Giác quan của Jarvis.jpg

1. Đấu nối phần cứng (Wiring)​


Cảm biến DHT11 thường có 3 chân (hoặc 4 chân). Nếu là loại module (có mạch xanh nhỏ đi kèm) thì thường có 3 chân.

Chân DHT11Chân ESP32Ghi chú
VCC (+)3V3 (hoặc 5V)Nguồn điện.
GND (-)GNDNối đất.
DATA (OUT)D4 (GPIO 4)Chân truyền dữ liệu (Có thể chọn chân khác).

*Lưu ý:* Nếu bạn dùng DHT11 loại 4 chân (chưa hàn vào module), bạn cần mắc thêm một điện trở 10k Ohm giữa chân VCC và chân DATA (gọi là điện trở kéo lên/pull-up). Mua loại module 3 chân thì khỏe hơn, có sẵn rồi.

2. Cài đặt thư viện DHT​


Trên VS Code (PlatformIO):
1. Mở file platformio.ini.
2. Thêm thư viện Adafruit DHT Unified vào phần lib_deps.

INI:
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
monitor_speed = 115200
lib_deps =
    knolleary/PubSubClient @ ^2.8
    adafruit/DHT sensor library @ ^1.4.4
    adafruit/Adafruit Unified Sensor @ ^1.1.9
(Lưu file lại và đợi nó tải thư viện về).

3. Viết Code đọc cảm biến (src/main.cpp)​


Chúng ta sẽ nâng cấp code bài trước.
Logic quan trọng: Không được dùng hàm delay() trong vòng lặp chính quá lâu, vì nó sẽ chặn kết nối MQTT. Chúng ta sẽ dùng hàm millis() để gửi dữ liệu mỗi 5 giây mà không làm treo máy (Non-blocking code).

Copy đoạn code sau đè lên src/main.cpp (Nhớ sửa lại Wifi/IP):

C++:
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h> // <--- Thư viện mới

// --- CẤU HÌNH ---
const char* ssid = "TEN_WIFI_NHA_BAN";
const char* password = "MAT_KHAU_WIFI";
const char* mqtt_server = "192.168.1.X";
const int mqtt_port = 1883;

// --- CẤU HÌNH CẢM BIẾN ---
#define DHTPIN 4      // Chân nối DATA của DHT11
#define DHTTYPE DHT11 // Loại cảm biến (Nếu dùng DHT22 thì sửa thành DHT22)
DHT dht(DHTPIN, DHTTYPE);

// --- ĐỐI TƯỢNG ---
WiFiClient espClient;
PubSubClient client(espClient);

// --- BIẾN THỜI GIAN (TIMER) ---
unsigned long lastMsg = 0;
const long interval = 5000; // Gửi mỗi 5000ms (5 giây)

#define RELAY_PIN 23

void setup_wifi() {
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi Connected!");
}

void callback(char* topic, byte* payload, unsigned int length) {
  // ... (Giữ nguyên logic điều khiển Relay bài trước) ...
  // Để gọn code, tôi lược bỏ phần in ra Serial ở đây
  String message = "";
  for (int i = 0; i < length; i++) message += (char)payload[i];

  if (String(topic) == "home/livingroom/light") {
    if (message == "ON") digitalWrite(RELAY_PIN, LOW);
    else if (message == "OFF") digitalWrite(RELAY_PIN, HIGH);
  }
}

void reconnect() {
  while (!client.connected()) {
    String clientId = "ESP32-Sensor";
    if (client.connect(clientId.c_str())) {
      Serial.println("MQTT Connected");
      client.subscribe("home/livingroom/light"); // Vẫn nghe lệnh bật đèn
    } else {
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, HIGH);

  dht.begin(); // <--- Khởi động cảm biến

  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();

  // --- LOGIC GỬI CẢM BIẾN (NON-BLOCKING) ---
  unsigned long now = millis();
  if (now - lastMsg > interval) {
    lastMsg = now;

    // 1. Đọc dữ liệu
    float h = dht.readHumidity();    // Độ ẩm
    float t = dht.readTemperature(); // Nhiệt độ (C)

    // Kiểm tra lỗi
    if (isnan(h) || isnan(t)) {
      Serial.println("Lỗi đọc cảm biến DHT!");
      return;
    }

    // 2. Tạo bản tin JSON thủ công (cho đơn giản)
    // Format: {"temp": 30.5, "hum": 70}
    String jsonPayload = "{\"temp\": " + String(t) + ", \"hum\": " + String(h) + "}";
   
    // 3. Gửi lên MQTT Topic riêng
    // Convert String sang char array để gửi
    char msg[50];
    jsonPayload.toCharArray(msg, 50);
   
    client.publish("home/livingroom/sensor", msg); // <--- Topic mới
   
    Serial.print("Sent sensor data: ");
    Serial.println(msg);
  }
}

4. Kiểm tra kết quả​


  1. Nạp code vào ESP32.
  2. Mở Serial Monitor. Bạn sẽ thấy mỗi 5 giây nó in ra:
    Sent sensor data: {"temp": 28.00, "hum": 65.00}
  3. Mở phần mềm **MQTT Explorer** trên máy tính.
  4. Tìm topic home/livingroom/sensor.
  5. Bạn sẽ thấy dữ liệu nhảy múa theo thời gian thực. Hãy thử hà hơi vào cảm biến để thấy độ ẩm tăng lên.

Tổng kết​


Giờ đây, Jarvis không chỉ điều khiển được đèn (Relay) mà còn biết phòng bạn đang nóng hay lạnh.
Tuy nhiên, thông tin này đang "bay lơ lửng" trên mạng MQTT.
  • Trên App điện thoại chưa hiện nhiệt độ.
  • Server Python chưa biết thông tin này để xử lý tự động.

Chúng ta cần "bắt" lấy dữ liệu này và hiển thị nó đẹp đẽ lên cái Dashboard mà ta đã vẽ.
 
Back
Top