#include <WiFi.h> // Thư viện kết nối Wi-Fi cho ESP32
#include <FirebaseESP32.h> // Thư viện Firebase cho ESP32
#include <DHT.h> // Thư viện DHT cho cảm biến DHT11/DHT22
#include <Adafruit_GFX.h> // Thư viện cung cấp các hàm vẽ đồ họa cơ bản
#include <Adafruit_SSD1306.h> // Thư viện điều khiển màn hình OLED SSD1306
#include <ThingSpeak.h> // Thư viện giao tiếp với ThingSpeak
// Khai báo thông tin Firebase
#define FIREBASE_HOST "https://lab3-iot-bai7-default-rtdb.firebaseio.com/" // URL Firebase Realtime Database
#define FIREBASE_AUTH "bebL4RCf3JvBmYfTPW4Y5WVWFbeoiwDz2invRQak" // Firebase Secret
// Khai báo thông tin ThingSpeak
const int myChannelNumber = 2783540; // ID của kênh ThingSpeak
const char* myApiKey = "O4TF8DFXO8GER0MX"; // API Key để xác thực gửi dữ liệu
const char* server = "api.thingspeak.com"; // Máy chủ ThingSpeak
WiFiClient client;
// Khai báo thông tin Wi-Fi
#define WIFI_SSID "Wokwi-GUEST" // Thay đổi tên wifi của bạn
#define WIFI_PASSWORD "" // Thay đổi password wifi của bạn
// Cấu hình DHT
#define DHTPIN 32 // Chân dữ liệu của DHT22
#define DHTTYPE DHT22 // DHT22
DHT dht(DHTPIN, DHTTYPE);
// Khởi tạo màn hình OLED
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
// Cấu hình LED, PIR, BUZZER, SWITCH
#define LED_pin 19
#define PIR_pin 14
#define BUZZER_pin 23
#define SWITCH_pin 4
int chophepbaodong = 0; // Đặt mặc định là báo động tắt
// Firebase
FirebaseData fbdo;
FirebaseAuth auth; // Đối tượng xác thực Firebase
FirebaseConfig config; // Đối tượng cấu hình Firebase
// Hàm gửi dữ liệu cảm biến DHT22
void sendSensorData() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Lỗi: Không thể đọc dữ liệu từ cảm biến DHT22");
return;
}
Serial.print("Nhiệt độ: ");
Serial.print(temperature);
Serial.print("°C Độ ẩm: ");
Serial.print(humidity);
Serial.println("%");
// Hiển thị nhiệt độ và độ ẩm lên màn hình OLED
oled.setCursor(0, 0);
oled.fillRect(0, 0, 128, 20, BLACK); // Xóa vùng hiển thị dữ liệu
oled.print("Temp: ");
oled.print(temperature);
oled.println("*C");
oled.print("Humid: ");
oled.print(humidity);
oled.println("%");
oled.display(); // Cập nhật màn hình OLED
// Gửi dữ liệu lên Firebase
if (Firebase.setFloat(fbdo, "/Nhiet_Do", temperature)) { // Cập nhật nhiệt độ
Serial.println("Gửi nhiệt độ thành công!");
} else {
Serial.println("Lỗi gửi nhiệt độ: ");
Serial.println(fbdo.errorReason().c_str());
}
if (Firebase.setFloat(fbdo, "/Do_Am", humidity)) { // Cập nhật độ ẩm
Serial.println("Gửi độ ẩm thành công!");
} else {
Serial.println("Lỗi gửi độ ẩm: ");
Serial.println(fbdo.errorReason().c_str());
}
// Gửi dữ liệu lên ThingSpeak
ThingSpeak.setField(1, temperature); // Gửi nhiệt độ vào trường 1
ThingSpeak.setField(2, humidity); // Gửi độ ẩm vào trường 2
// Gửi dữ liệu
int responseCode = ThingSpeak.writeFields(myChannelNumber, myApiKey);
if (responseCode == 200) {
Serial.println("Data pushed successfully"); // Thông báo nếu gửi thành công
} else {
Serial.println("Push error"); // Thông báo lỗi nếu gửi thất bại
}
Serial.println("-------------------------");
}
// Hàm kiểm tra trạng thái của cảm biến PIR và kích hoạt báo động
void checkPIRSensor() {
int pirState = digitalRead(PIR_pin); // Đọc trạng thái của cảm biến PIR
static String prevMessage = ""; // Lưu trạng thái trước đó
String message = (chophepbaodong && pirState == HIGH) ? "Moving detecting..." : "";
if (message != prevMessage) {
prevMessage = message;
oled.setCursor(0, 40);
oled.fillRect(0, 40, 128, 10, BLACK); // Xóa vùng hiển thị chỗ di chuyển
oled.println(message);
oled.display();
if (!message.isEmpty()) Serial.println("Phát hiện có chuyển động");
}
// Nếu báo động được bật và có chuyển động
if (chophepbaodong && pirState == HIGH) {
digitalWrite(LED_pin, HIGH); // Bật LED để biểu thị báo động
tone(BUZZER_pin, 1000); // Buzzer kêu
}
// Không có chuyển động hoặc báo động tắt
else {
digitalWrite(LED_pin, LOW); // Tắt LED
noTone(BUZZER_pin); // Buzzer tắt
}
}
void setup() {
pinMode(SWITCH_pin, INPUT);
pinMode(LED_pin, OUTPUT);
digitalWrite(LED_pin, LOW);
pinMode(PIR_pin, INPUT); // Thiết lập chân PIR là INPUT
pinMode(BUZZER_pin, OUTPUT); // Thiết lập chân Buzzer là OUTPUT
Serial.begin(115200);
// Kết nối WiFi
Serial.println("Dang ket noi WiFi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi da ket noi!");
// Cài đặt chế độ Wi-Fi và khởi tạo ThingSpeak
WiFi.mode(WIFI_STA);
ThingSpeak.begin(client);
// Cấu hình Firebase
config.host = FIREBASE_HOST;
config.signer.tokens.legacy_token = FIREBASE_AUTH;
// Bắt đầu Firebase với cấu hình
Firebase.begin(&config, &auth);
// Khởi động cảm biến DHT
dht.begin();
// Khởi tạo màn hình OLED
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
//Nếu khởi tạo thất bại, in thông báo lỗi và dừng chương trình bằng while(1).
Serial.println("SSD1306 allocation failed");
while (1);
}
oled.clearDisplay(); //Xóa nội dung màn hình OLED.
oled.setTextSize(1); //Cài đặt kích thước chữ.
oled.setTextColor(WHITE); //Cài đặt màu chữ.
oled.setCursor(0, 0); //Đặt vị trí con trỏ tại tọa độ (x,y) (pixel).
}
void loop() {
static int prevChophepbaodong = -1;
chophepbaodong = digitalRead(SWITCH_pin);
if (chophepbaodong != prevChophepbaodong) {
prevChophepbaodong = chophepbaodong;
oled.setCursor(0, 30);
oled.fillRect(0, 30, 128, 10, BLACK); // Xóa vùng hiển thị báo động
if (chophepbaodong) {
Serial.println("Báo động bật");
oled.println("Alert ON");
} else {
Serial.println("Báo động tắt");
oled.println("Alert OFF");
}
oled.display();
}
sendSensorData();
checkPIRSensor();
delay(1000); // Đợi 1 giây trước khi lặp lại
}