#include <SPI.h>
#include <Servo.h> // Подключаем библиотеку для работы с сервоприводом
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
#include <math.h>
#define PIN_TRIG 3
#define PIN_ECHO 2
#define SS_PIN 10
#define RST_PIN 9
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
MFRC522 mfrc522(SS_PIN, RST_PIN); // Создаем экземпляр MFRC522.
Servo myServo; // Создаем объект для работы с сервоприводом
const int relayPin = 8;
const int ledPin1 = 13; // Пин светодиода
const int ledPin2 = 12; // Пин светодиода
// Переменная для хранения введенного UID
String enteredUID = "";
bool uidEntered = false; // Флаг, показывающий, был ли введен UID
bool uidProcessed = false; // Флаг, показывающий, был ли UID обработан
bool inputAllowed = false; // Флаг, разрешающий или запрещающий ввод через Serial
void setup() {
Serial.begin(9600);
// Init
lcd.init();
lcd.backlight();
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
pinMode(relayPin, OUTPUT); // Реле на выход
myServo.attach(9); // Подключаем сервопривод к пину 9
digitalWrite(ledPin1, HIGH); // Включаем светодиод
digitalWrite(relayPin, LOW); // Выключить реле
myServo.write(90); // Установить начальную позицию сервопривода
// Инициализация флагов и переменных для сброса состояния
resetState();
}
void loop() {
// Измеряем расстояние
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
// Читаем результат
int duration = pulseIn(PIN_ECHO, HIGH);
int totalres = duration / 58;
Serial.print("Distance: ");
Serial.print(totalres);
Serial.println(" cm");
// Если расстояние больше 250 см, запрещаем ввод через Serial
if (totalres > 250) {
Serial.println("Distance is more than 250 cm, input blocked.");
resetState();
lcd.setCursor(4, 1);
lcd.print("Gate System");
if (Serial.available() > 0) {
// Читаем UID
enteredUID = Serial.readStringUntil('\n');
enteredUID.trim();
lcd.setCursor(4, 1);
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.print("No signal");
}
} else {
// Если расстояние в допустимом диапазоне, разрешаем ввод
inputAllowed = true;
lcd.setCursor(4, 1);
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.print("Scanning...");
// Запрашиваем ввод UID, если расстояние допустимо
if (!uidEntered && !uidProcessed) {
Serial.println("Enter UID of the card:");
if (Serial.available() > 0) {
// Читаем UID
enteredUID = Serial.readStringUntil('\n');
enteredUID.trim();
if (enteredUID.length() > 0) {
uidEntered = true; // Устанавливаем флаг, что UID был введен
}
}
}
// Если UID был введен, проверяем его
if (uidEntered && !uidProcessed) {
Serial.print("Received UID: ");
Serial.println(enteredUID);
if (inputAllowed = true){
// Проверяем, соответствует ли UID разрешенному UID
if (enteredUID == "BD31152B") {
Serial.println("Authorized access");
lcd.setCursor(5, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print("WELCOME!");
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH); // Включаем светодиод
digitalWrite(relayPin, HIGH); // Включить реле
myServo.write(20); // Повернуть сервопривод на 20 градусов
delay(5000); // Задержка 5 секунд
lcd.setCursor(5, 1);
lcd.print(" ");
digitalWrite(ledPin2, LOW); // Выключаем светодиод
digitalWrite(relayPin, LOW); // Выключить реле
myServo.write(90); // Вернуть сервопривод в начальное положение (90 градусов)
digitalWrite(ledPin1, HIGH); // Включаем светодиод
uidProcessed = true; // UID был обработан
resetState();
} else {
Serial.println("Access denied");
lcd.setCursor(3, 1);
lcd.print("Access denied");
delay(1000); // Задержка 1 сек
lcd.setCursor(3, 1);
lcd.print(" ");
resetState();
}
}
}
}
// Дополнительная проверка: если расстояние стало недопустимым после ввода UID, сбрасываем состояние
if (uidEntered && totalres >= 250) {
enteredUID = "";
uidEntered = false;
uidProcessed = false;
inputAllowed = false; // Сбрасываем флаг разрешения ввода
if (Serial.available() > 0) {
// Читаем UID
enteredUID = Serial.readStringUntil('\n');
enteredUID.trim();
if (enteredUID.length() > 0) {
uidEntered = false; // Устанавливаем флаг, что UID был введен
}
}
}
delay(1100); // Задержка для уменьшения нагрузки на процессор
}
// Функция для сброса всех флагов и переменных состояния
void resetState() {
enteredUID = "";
uidEntered = false;
uidProcessed = false;
inputAllowed = true; // Сбрасываем флаг разрешения ввода
}