#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <MFRC522.h>
#include <ESP32Servo.h> // Thư viện Servo cho ESP32
#define SS_PIN 5
#define RST_PIN 4
MFRC522 rfid(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set LCD I2C address to 0x27, with 16 columns and 2 rows
Servo servoIn, servoOut;
const int buzzer = 15;
const int sensors[] = {12, 14, 27, 25}; // Các cảm biến khác trong bãi
const int entrySensor = 33; // Cảm biến phát hiện xe đi vào
const int servoInPin = 32; // Servo mở cửa vào
const int servoOutPin = 13; // Servo mở cửa ra
int totalSpots = 4; // Tổng số chỗ trong bãi xe
int occupiedSpots = 0; // Số xe hiện tại trong bãi
void setup() {
Serial.begin(115200);
Serial.println("Bắt đầu khởi tạo");
// Khởi tạo giao tiếp I2C và LCD
Wire.begin();
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the LCD backlight
lcd.setCursor(0, 0);
lcd.print("Khoi tao OK");
// Khởi tạo RFID
SPI.begin();
rfid.PCD_Init();
Serial.println("RFID được khởi tạo");
// Khởi tạo Servo
servoIn.attach(servoInPin);
servoOut.attach(servoOutPin);
servoIn.write(0); // Đóng cửa vào ban đầu
servoOut.write(0); // Đóng cửa ra ban đầu
Serial.println("Servo đã được khởi tạo");
// Khởi tạo Buzzer
pinMode(buzzer, OUTPUT);
// Khởi tạo các cảm biến hồng ngoại trong bãi
for (int i = 0; i < 4; i++) {
pinMode(sensors[i], INPUT);
}
// Khởi tạo cảm biến phát hiện xe đi vào
pinMode(entrySensor, INPUT);
Serial.println("Cảm biến đã được khởi tạo");
updateDisplay(); // Hiển thị thông tin ban đầu
}
void loop() {
// Kiểm tra nếu có xe đi vào (cảm biến chân 33)
if (digitalRead(entrySensor) == LOW) { // Phát hiện xe
Serial.println("Phát hiện xe vào");
handleEntry();
}
// Cập nhật số xe trong bãi dựa trên các cảm biến khác
int newOccupiedSpots = checkSensors();
if (newOccupiedSpots != occupiedSpots) {
occupiedSpots = newOccupiedSpots;
updateDisplay();
}
// Kiểm tra nếu có thẻ RFID được quẹt
if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
Serial.println("Phát hiện thẻ");
if (checkCard()) {
beep(); // Bật âm báo Buzzer
handleExit(); // Xử lý xe ra
}
rfid.PICC_HaltA(); // Dừng đọc thẻ
}
}
// Hàm kiểm tra trạng thái của các cảm biến khác trong bãi
int checkSensors() {
int count = 0;
for (int i = 0; i < 4; i++) {
if (digitalRead(sensors[i]) == LOW) { // LOW nghĩa là có vật cản (xe)
count++;
}
}
Serial.print("Số xe hiện tại: ");
Serial.println(count);
return count;
}
// Hàm cập nhật hiển thị trên LCD
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Xe trong bai:");
lcd.print(occupiedSpots);
lcd.print("/");
lcd.print(totalSpots);
Serial.print("Cập nhật LCD: ");
Serial.print(occupiedSpots);
Serial.print("/");
Serial.println(totalSpots);
}
// Hàm kiểm tra thẻ RFID (giả lập)
bool checkCard() {
Serial.println("Thẻ hợp lệ");
return true;
}
// Xử lý khi xe đi vào
void handleEntry() {
if (occupiedSpots < totalSpots) {
// Mở cửa vào bằng servo trên chân 32
servoIn.write(90);
lcd.setCursor(0, 1);
lcd.print("Dang mo cua vao");
Serial.println("Mở cửa vào");
delay(2000);
servoIn.write(0); // Đóng lại sau 2 giây
Serial.println("Đóng cửa vào");
// Tăng số xe trong bãi
occupiedSpots++;
updateDisplay();
} else {
// Thông báo bãi đầy
lcd.setCursor(0, 1);
lcd.print("Bai da day ");
Serial.println("Bãi đã đầy");
}
}
// Xử lý khi xe đi ra
void handleExit() {
if (occupiedSpots > 0) {
// Mở cửa ra bằng servo trên chân 13
servoOut.write(90);
lcd.setCursor(0, 1);
lcd.print("Dang mo cua ra ");
Serial.println("Mở cửa ra");
delay(4000); // Đợi 3 giây để xe đi qua
servoOut.write(0); // Đóng lại sau 3 giây
Serial.println("Đóng cửa ra");
// Giảm số xe trong bãi
occupiedSpots--;
updateDisplay();
} else {
// Thông báo không có xe để ra
lcd.setCursor(0, 1);
lcd.print("Khong co xe ra ");
Serial.println("Không có xe để ra");
}
}
// Hàm phát âm báo bằng Buzzer
void beep() {
digitalWrite(buzzer, HIGH);
delay(100);
digitalWrite(buzzer, LOW);
Serial.println("Buzzer kêu");
}