#include <WiFi.h> // Thư viện Wi-Fi cho ESP32
#include <HTTPClient.h> // Thư viện HTTPClient để gửi yêu cầu HTTP
// Firebase config
#define FIREBASE_HOST "https://test-771be-default-rtdb.firebaseio.com/" // URL Firebase của cơ sở dữ liệu Realtime Database
#define FIREBASE_AUTH "Gt1PPJbyJoih4GZC984lJqAtpZy8sZjqFTFBxbGX" // API Key để xác thực Firebase
// Wi-Fi config
#define WIFI_SSID "Wokwi-GUEST" // Tên mạng Wi-Fi
#define WIFI_PASSWORD "" // Mật khẩu Wi-Fi (trống vì sử dụng Wi-Fi công cộng của Wokwi)
// DHT sensor config
#define DHTPIN 15 // Chân GPIO của ESP32 được kết nối với cảm biến DHT22
float temperature = 0.0; // Biến lưu trữ nhiệt độ
float humidity = 0.0; // Biến lưu trữ độ ẩm
void connectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // Bắt đầu kết nối với mạng Wi-Fi
Serial.print("Connecting to Wi-Fi...");
while (WiFi.status() != WL_CONNECTED) { // Chờ cho đến khi kết nối thành công
Serial.print("."); // In dấu "." để báo trạng thái kết nối
delay(500); // Đợi 500ms
}
Serial.println(" Connected to Wi-Fi!"); // In thông báo kết nối thành công
}
bool readDHT22(float &temp, float &hum) {
uint8_t data[5] = {0, 0, 0, 0, 0}; // Mảng lưu trữ dữ liệu từ cảm biến
uint8_t checksum; // Biến lưu trữ giá trị kiểm tra checksum
// Gửi tín hiệu khởi tạo đến cảm biến DHT22
pinMode(DHTPIN, OUTPUT); // Đặt chân DHT thành OUTPUT
digitalWrite(DHTPIN, LOW); // Kéo chân DHT xuống LOW để bắt đầu
delay(20); // Giữ tín hiệu trong ít nhất 18ms
digitalWrite(DHTPIN, HIGH); // Kéo chân DHT lên HIGH
delayMicroseconds(30); // Chờ thêm 30 micro giây
pinMode(DHTPIN, INPUT_PULLUP); // Đặt chân DHT thành INPUT
// Đợi tín hiệu phản hồi từ cảm biến
unsigned long start = micros(); // Lấy thời gian bắt đầu
while (digitalRead(DHTPIN) == HIGH) { // Chờ tín hiệu LOW từ cảm biến
if (micros() - start > 40) return false; // Nếu thời gian chờ vượt quá 40µs, trả về lỗi
}
// Đọc dữ liệu từ cảm biến
for (int i = 0; i < 40; i++) { // Lặp qua 40 bit dữ liệu
while (digitalRead(DHTPIN) == LOW); // Đợi tín hiệu HIGH
start = micros(); // Lấy thời gian bắt đầu
while (digitalRead(DHTPIN) == HIGH); // Đợi tín hiệu LOW
unsigned long duration = micros() - start; // Đo thời gian tín hiệu HIGH
// Nếu thời gian HIGH > 50us thì bit là 1, ngược lại là 0
data[i / 8] <<= 1; // Dịch trái 1 bit trong byte hiện tại
if (duration > 50) { // Nếu thời gian HIGH lớn hơn 50µs
data[i / 8] |= 1; // Ghi giá trị 1 vào bit thấp nhất
}
}
// Kiểm tra checksum
checksum = data[0] + data[1] + data[2] + data[3]; // Tổng các byte dữ liệu
if (checksum != data[4]) return false; // Nếu checksum không khớp, trả về lỗi
// Chuyển đổi dữ liệu từ cảm biến
hum = ((data[0] << 8) | data[1]) * 0.1; // Tính độ ẩm
temp = ((data[2] & 0x7F) << 8 | data[3]) * 0.1; // Tính nhiệt độ
if (data[2] & 0x80) temp = -temp; // Nếu bit dấu được bật, đổi thành nhiệt độ âm
return true; // Đọc dữ liệu thành công
}
void sendDataToFirebase(float temp, float hum) {
if (WiFi.status() == WL_CONNECTED) { // Kiểm tra xem đã kết nối Wi-Fi chưa
HTTPClient http;
// Gửi dữ liệu nhiệt độ
String url = String(FIREBASE_HOST) + "/Temperature.json?auth=" + FIREBASE_AUTH; // URL nhiệt độ
http.begin(url); // Bắt đầu kết nối HTTP
http.addHeader("Content-Type", "application/json"); // Đặt kiểu dữ liệu là JSON
String payload = "{\"temperature\": " + String(temp) + "}"; // Dữ liệu nhiệt độ dưới dạng JSON
int httpCode = http.POST(payload); // Gửi POST request
Serial.print("HTTP Response Code for Temperature: ");
Serial.println(httpCode); // In mã phản hồi từ server
http.end(); // Kết thúc kết nối HTTP
// Gửi dữ liệu độ ẩm
url = String(FIREBASE_HOST) + "/Humidity.json?auth=" + FIREBASE_AUTH; // URL độ ẩm
http.begin(url); // Bắt đầu kết nối HTTP
payload = "{\"humidity\": " + String(hum) + "}"; // Dữ liệu độ ẩm dưới dạng JSON
httpCode = http.POST(payload); // Gửi POST request
Serial.print("HTTP Response Code for Humidity: ");
Serial.println(httpCode); // In mã phản hồi từ server
http.end(); // Kết thúc kết nối HTTP
} else {
Serial.println("Wi-Fi not connected!"); // Thông báo nếu không kết nối Wi-Fi
}
}
void setup() {
Serial.begin(115200); // Khởi động Serial Monitor
connectWiFi(); // Kết nối Wi-Fi
}
void loop() {
if (readDHT22(temperature, humidity)) { // Đọc dữ liệu từ DHT22
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print(" °C, Humidity: ");
Serial.print(humidity);
Serial.println(" %");
sendDataToFirebase(temperature, humidity); // Gửi dữ liệu lên Firebase
} else {
Serial.println("Failed to read from DHT sensor!"); // Báo lỗi khi đọc dữ liệu
}
delay(5000); // Chờ 5 giây trước khi đọc lại
}