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.
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.
*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.
Trên VS Code (PlatformIO):
1. Mở file
2. Thêm thư viện
(Lưu file lại và đợi nó tải thư viện về).
Chúng ta sẽ nâng cấp code bài trước.
Logic quan trọng: Không được dùng hàm
Copy đoạn code sau đè lên
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.
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ẽ.
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.
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 DHT11 | Chân ESP32 | Ghi chú |
|---|---|---|
| VCC (+) | 3V3 (hoặc 5V) | Nguồn điện. |
| GND (-) | GND | Nố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
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ả
- Nạp code vào ESP32.
- 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} - Mở phần mềm **MQTT Explorer** trên máy tính.
- Tìm topic
home/livingroom/sensor. - 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ẽ.
Bài viết liên quan