// #include <LiquidCrystal_I2C.h>
// #include <IRremote.h>
// #define RELAY1_PIN 2 // Relay phòng 1
// #define RELAY2_PIN 4 // Relay phòng 2
// #define PUMP_PIN 17 // Relay bơm nước
// #define BUTTON2_PIN 33 // Nút nhấn bật/tắt đèn phòng 1
// #define BUTTON3_PIN 12 // Nút nhấn bật/tắt đèn phòng 2
// #define TRIG_PIN 14 // Chân trig cảm biến siêu âm
// #define ECHO_PIN 27 // Chân echo cảm biến siêu âm
// #define IR_PIN 35 // Chân nhận tín hiệu IR
// #define PIR_PIN 34 // Chân OUT của cảm biến chuyển động
// #define LED_PIN 32 // Đèn LED cho phòng vệ sinh
// LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ LCD I2C
// IRrecv irrecv(IR_PIN); // Khởi tạo IR receiver
// bool roomStatus[2] = {false, false}; // Trạng thái đèn các phòng
// bool pumpStatus = false; // Trạng thái bơm nước
// bool bathroomLight = false; // Trạng thái đèn phòng vệ sinh
// int countStudent = 0;
// // Biến lưu thời gian chuyển động gần nhất
// unsigned long lastMotionTime = 0;
// const unsigned long motionDelay = 1000; // Thời gian tắt đèn sau 10 giây nếu không có chuyển động
// void setup() {
// Serial.begin(115200);
// // Cấu hình các pin
// pinMode(RELAY1_PIN, OUTPUT);
// pinMode(RELAY2_PIN, OUTPUT);
// pinMode(PUMP_PIN, OUTPUT);
// pinMode(BUTTON2_PIN, INPUT_PULLUP); // Nút nhấn bật/tắt đèn phòng 1
// pinMode(BUTTON3_PIN, INPUT_PULLUP); // Nút nhấn bật/tắt đèn phòng 2
// pinMode(TRIG_PIN, OUTPUT); // Cảm biến siêu âm
// pinMode(ECHO_PIN, INPUT);
// pinMode(PIR_PIN, INPUT); // Cảm biến chuyển động
// pinMode(LED_PIN, OUTPUT); // Đèn LED phòng vệ sinh
// lcd.init(); // Khởi tạo LCD
// lcd.backlight();
// lcd.setCursor(0, 0);
// lcd.print("System Starting");
// delay(1000);
// lcd.clear();
// irrecv.enableIRIn(); // Bắt đầu nhận tín hiệu IR
// }
// void loop() {
// // Kiểm tra tín hiệu từ IR remote
// if (irrecv.decode()) {
// int command = irrecv.decodedIRData.command;
// if (command == 48) { // Mã IR cho đèn phòng 1 (số 1)
// toggleRoom(0, RELAY1_PIN);
// } else if (command == 24) { // Mã IR cho đèn phòng 2 (số 2)
// toggleRoom(1, RELAY2_PIN);
// } else if (command == 122) { // Mã IR cho bơm nước (số 3)
// togglePump();
// } else if (command == 74) { // Mã IR cho điểm danh
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("Da diem danh");
// delay(100);
// lcd.clear();
// countStudent++;
// Serial.print("Si so hien tai la: ");
// Serial.println(countStudent);
// }
// irrecv.resume(); // Nhận tín hiệu IR tiếp theo
// }
// // Kiểm tra nút nhấn bật/tắt đèn phòng 1
// if (digitalRead(BUTTON2_PIN) == LOW) {
// delay(50); // Debounce cho nút nhấn
// toggleRoom(0, RELAY1_PIN); // Bật/tắt phòng 1
// }
// // Kiểm tra nút nhấn bật/tắt đèn phòng 2
// if (digitalRead(BUTTON3_PIN) == LOW) {
// delay(50); // Debounce cho nút nhấn
// toggleRoom(1, RELAY2_PIN); // Bật/tắt phòng 2
// }
// // Kiểm tra mức nước và điều khiển bơm
// long waterLevel = getWaterLevel();
// if (waterLevel < 10) pumpStatus = false; // Nếu cách cảm biến 10cm thì ngắt
// else if (waterLevel > 100) pumpStatus = true; // Nếu cách cảm biến 100cm thì bơm
// digitalWrite(PUMP_PIN, pumpStatus);
// // Kiểm tra chuyển động
// if (digitalRead(PIR_PIN) == HIGH) {
// // Phát hiện chuyển động
// if (!bathroomLight) { // Chỉ xử lý khi đèn đang tắt
// Serial.println("Chuyen dong phat hien o phong ve sinh!");
// bathroomLight = true; // Bật đèn phòng vệ sinh
// digitalWrite(LED_PIN, HIGH);
// // Hiển thị thông báo lên LCD
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("WC: Chuyen dong");
// lcd.clear();
// }
// // Cập nhật thời gian chuyển động gần nhất
// lastMotionTime = millis();
// } else {
// // Kiểm tra nếu đã hết thời gian chờ và không có chuyển động
// if (bathroomLight && (millis() - lastMotionTime > motionDelay)) {
// bathroomLight = false; // Tắt đèn phòng vệ sinh
// digitalWrite(LED_PIN, LOW);
// Serial.println("Tat den phong ve sinh!");
// // Xóa thông báo trên LCD
// lcd.clear();
// lcd.setCursor(0, 0);
// lcd.print("WC: Khong chuyen dong");
// lcd.clear();
// }
// }
// // Cập nhật LCD
// updateLCD();
// delay(100);
// }
// void toggleRoom(int room, int relayPin) {
// roomStatus[room] = !roomStatus[room];
// digitalWrite(relayPin, roomStatus[room]);
// Serial.print("Room ");
// Serial.print(room + 1);
// Serial.println(roomStatus[room] ? " ON" : " OFF");
// }
// void togglePump() {
// pumpStatus = !pumpStatus;
// digitalWrite(PUMP_PIN, pumpStatus);
// Serial.println(pumpStatus ? "Pump ON" : "Pump OFF");
// }
// void updateLCD() {
// lcd.setCursor(0, 0);
// lcd.print("P1:");
// lcd.print(roomStatus[0] ? "ON " : "OFF ");
// lcd.print("P2:");
// lcd.print(roomStatus[1] ? "ON " : "OFF ");
// lcd.setCursor(0, 1);
// lcd.print("Bom nuoc:");
// lcd.print(pumpStatus ? "ON " : "OFF ");
// }
// long getWaterLevel() {
// digitalWrite(TRIG_PIN, LOW);
// delayMicroseconds(2);
// digitalWrite(TRIG_PIN, HIGH);
// delayMicroseconds(10);
// digitalWrite(TRIG_PIN, LOW);
// long duration = pulseIn(ECHO_PIN, HIGH);
// long distance = (duration / 2) * 0.0343;
// return distance;
// }
// #define BLYNK_TEMPLATE_ID "TMPL6m-rP22p-"
// #define BLYNK_TEMPLATE_NAME "meeting room"
// #define BLYNK_AUTH_TOKEN "YSWGKVwrnGaFLi1iZf5S3PPoRH_gd1q-"
// Cấu hình WiFi và Blynk
#define BLYNK_TEMPLATE_NAME "lab2"
//#define BLYNK_AUTH_TOKEN "UB4u4h_zIytlRJtFb5baHxVwjL-Jz0oh"
#define BLYNK_TEMPLATE_ID "TMPL6A76K4YD7"
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
char auth[] = "UB4u4h_zIytlRJtFb5baHxVwjL-Jz0oh";
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
#define RELAY1_PIN 2 // Relay phòng 1
#define RELAY2_PIN 4 // Relay phòng 2
#define PUMP_PIN 17 // Relay bơm nước
#define BUTTON2_PIN 33 // Nút nhấn bật/tắt đèn phòng 1
#define BUTTON3_PIN 12 // Nút nhấn bật/tắt đèn phòng 2
#define TRIG_PIN 14 // Chân trig cảm biến siêu âm
#define ECHO_PIN 27 // Chân echo cảm biến siêu âm
#define IR_PIN 35 // Chân nhận tín hiệu IR
#define PIR_PIN 34 // Chân OUT của cảm biến chuyển động
#define LED_PIN 32 // Đèn LED cho phòng vệ sinh
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ LCD I2C
IRrecv irrecv(IR_PIN); // Khởi tạo IR receiver
bool roomStatus[2] = {false, false}; // Trạng thái đèn các phòng
bool pumpStatus = false; // Trạng thái bơm nước
bool bathroomLight = false; // Trạng thái đèn phòng vệ sinh
int countStudent = 0;
// Biến lưu thời gian chuyển động gần nhất
unsigned long lastMotionTime = 0;
const unsigned long motionDelay = 10000; // Thời gian tắt đèn sau 10 giây nếu không có chuyển động
// Virtual Pins
#define VIRTUAL_PUMP V6
#define VIRTUAL_ROOM1 V7
#define VIRTUAL_ROOM2 V8
void setup() {
Serial.begin(115200);
// Kết nối WiFi và Blynk
Blynk.begin(auth, ssid, pass);
// Cấu hình các pin
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(PUMP_PIN, OUTPUT);
pinMode(BUTTON2_PIN, INPUT_PULLUP); // Nút nhấn bật/tắt đèn phòng 1
pinMode(BUTTON3_PIN, INPUT_PULLUP); // Nút nhấn bật/tắt đèn phòng 2
pinMode(TRIG_PIN, OUTPUT); // Cảm biến siêu âm
pinMode(ECHO_PIN, INPUT);
pinMode(PIR_PIN, INPUT); // Cảm biến chuyển động
pinMode(LED_PIN, OUTPUT); // Đèn LED phòng vệ sinh
lcd.init(); // Khởi tạo LCD
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("System Starting");
delay(1000);
lcd.clear();
irrecv.enableIRIn(); // Bắt đầu nhận tín hiệu IR
}
void loop() {
Blynk.run(); // Blynk loop
// Kiểm tra tín hiệu từ IR remote
if (irrecv.decode()) {
int command = irrecv.decodedIRData.command;
if (command == 48) { // Mã IR cho đèn phòng 1 (số 1)
toggleRoom(0, RELAY1_PIN);
} else if (command == 24) { // Mã IR cho đèn phòng 2 (số 2)
toggleRoom(1, RELAY2_PIN);
} else if (command == 122) { // Mã IR cho bơm nước (số 3)
togglePump();
} else if (command == 74) { // Mã IR cho điểm danh
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Da diem danh");
delay(100);
lcd.clear();
countStudent++;
Serial.print("Si so hien tai la: ");
Serial.println(countStudent);
}
irrecv.resume(); // Nhận tín hiệu IR tiếp theo
}
// Kiểm tra nút nhấn bật/tắt đèn phòng 1
if (digitalRead(BUTTON2_PIN) == LOW) {
delay(50); // Debounce cho nút nhấn
toggleRoom(0, RELAY1_PIN); // Bật/tắt phòng 1
}
// Kiểm tra nút nhấn bật/tắt đèn phòng 2
if (digitalRead(BUTTON3_PIN) == LOW) {
delay(50); // Debounce cho nút nhấn
toggleRoom(1, RELAY2_PIN); // Bật/tắt phòng 2
}
// Kiểm tra mức nước và điều khiển bơm
long waterLevel = getWaterLevel();
if (waterLevel < 10) pumpStatus = false; // Nếu cách cảm biến 10cm thì ngắt
else if (waterLevel > 100) pumpStatus = true; // Nếu cách cảm biến 100cm thì bơm
digitalWrite(PUMP_PIN, pumpStatus);
// Kiểm tra chuyển động
if (digitalRead(PIR_PIN) == HIGH) {
if (!bathroomLight) {
Serial.println("Chuyen dong phat hien o phong ve sinh!");
bathroomLight = true;
digitalWrite(LED_PIN, HIGH);
lastMotionTime = millis();
}
} else if (bathroomLight && (millis() - lastMotionTime > motionDelay)) {
bathroomLight = false;
digitalWrite(LED_PIN, LOW);
}
updateLCD();
}
// Điều khiển relay đèn phòng
BLYNK_WRITE(VIRTUAL_ROOM1) {
toggleRoom(0, RELAY1_PIN);
}
BLYNK_WRITE(VIRTUAL_ROOM2) {
toggleRoom(1, RELAY2_PIN);
}
void toggleRoom(int room, int relayPin) {
roomStatus[room] = !roomStatus[room];
digitalWrite(relayPin, roomStatus[room]);
Serial.print("Room ");
Serial.print(room + 1);
Serial.println(roomStatus[room] ? " ON" : " OFF");
Blynk.virtualWrite(room == 0 ? VIRTUAL_ROOM1 : VIRTUAL_ROOM2, roomStatus[room]);
}
void togglePump() {
pumpStatus = !pumpStatus;
digitalWrite(PUMP_PIN, pumpStatus);
Serial.println(pumpStatus ? "Pump ON" : "Pump OFF");
Blynk.virtualWrite(VIRTUAL_PUMP, pumpStatus);
}
void updateLCD() {
lcd.setCursor(0, 0);
lcd.print("P1:");
lcd.print(roomStatus[0] ? "ON " : "OFF ");
lcd.print("P2:");
lcd.print(roomStatus[1] ? "ON " : "OFF ");
lcd.setCursor(0, 1);
lcd.print("Bom nuoc:");
lcd.print(pumpStatus ? "ON " : "OFF ");
}
long getWaterLevel() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
long distance = (duration / 2) * 0.0343;
return distance;
}