#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 họp
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 meetingroomLight = false; // Trạng thái đèn phòng họp
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
bool led_room_1 = false;
bool led_room_2 = false;
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 họp
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
toggleRoom(0, RELAY1_PIN);
} else if (command == 24) { // Mã IR cho đèn phòng 2
toggleRoom(1, RELAY2_PIN);
} 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 (!meetingroomLight) { // Chỉ xử lý khi đèn đang tắt
Serial.println("Chuyen dong phat hien o phong hop!");
meetingroomLight = true; // Bật đèn phòng họp
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 (meetingroomLight && (millis() - lastMotionTime > motionDelay)) {
meetingroomLight = false; // Tắt đèn phòng vệ sinh
digitalWrite(LED_PIN, LOW);
Serial.println("Tat den phong hop!");
// Xóa thông báo trên LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("MR: 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 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;
}