#14 Эксперимент “Система контроля доступа”
Системы контроля доступа, которые используют в качестве идентификаторов бесконтактные карты, существуют и используются уже довольно давно. Тем не менее, только сейчас эти технологии начали прочно укоренятся и в других сферах. Например, бесконтактная оплата пластиковой картой пришла ещё не во все магазины, а оплатить проезд по бесконтактной карте до сих пор можно лишь в больших городах. А ведь эта та же технология, которой мы пользуемся уже очень давно, например когда открываем дверь нашего домофона с помощью чип-брелка.
Сегодня мы узнаем – как работает бесконтактная система передачи данных RFID и даже соберём и запрограммируем свою систему контроля доступа.
Перед выполнением эксперимента прочтите:
СБОРКА УСТРОЙСТВА НА МАКЕТНОЙ ПЛАТЕ
Нам понадобятся следующие компоненты:
- Arduino Uno;
- USB-кабель для подключения к компьютеру;
- Беспаечная макетная плата;
- Модуль RFID-RC522;
- Чип и карта для этого модуля;
- Сервопривод;
- 2 светодиода красного и зелёного цветов;
- 2 резистора номиналом 220 Ом;
- Пьезодинамик;
- 7 соединительных проводов типа “папа-мама” различных цветов;
- 9 соединительных проводов типа “папа-папа” различных цветов.
Соберите устройство по следующей схеме:
Схема устройства на макетной плате |
Обратите внимание:
- Для питания модуля RFID мы используем пин 3,3 В;
- Помните о порядке подключения проводов сервопривода к пинам Arduino (коричневый – GND, красный – 5V, оранжевый – pin 8).
ПРОГРАММИРОВАНИЕ
Для начала, давайте установим библиотеку, необходимую для работы с модулем:
- Запустите Arduino IDE, выберите [Скетч] → [Подключить библиотеку] → [Управлять библиотеками];
- В строке поиска введите “MFRC522” и нажмите [Enter];
- Установите библиотеку нажав кнопку [Установка].
Теперь, когда библиотека установлена, давайте попробуем прочитать данные, хранящиеся на наших карте и брелке. Для этого загрузим в Arduino базовый скетч, который можно найти в примерах установленной библиотеки:
#include <SPI.h> // подключаем библиотеку для работы по SPI протоколу #include <MFRC522.h> // подключаем библиотеку для работы с RFID-RC522 MFRC522 mfrc522(10, 9); // указываем пины, к которым подключены SDA и RST выходы void setup() { Serial.begin(9600); // инициализируем последовательный порт SPI.begin(); // инициализируем SPI протокол передачи данных mfrc522.PCD_Init(); // инициализируем приёмник RFID Serial.println("Готов к приёму"); // Выводим сообщение о готовности в последовательный порт } void loop() { if(!mfrc522.PICC_IsNewCardPresent()) // ждём пока рядом не будет обнаружен RFID-чип return; if(!mfrc522.PICC_ReadCardSerial()) // ждём пока приёмник не считает номер чипа return; mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); // посылаем в последовательный пор всю информацию с чипа }
После загрузки скетча, запустите монитор порта. Когда в монитор придёт сообщение о готовности, приложите к считывателю сначала брелок (не убирайте его сразу, приёмнику нужно время, чтоб прочитать все данные), а затем карту. В мониторе должна отобразится примерно следующая информация для брелка:
…
И для карты:
…
Обратите внимание на Card UID – они разные для брелка и карты. Этот идентификатор является уникальным для каждого RFID-устройства и самый простой способ реализации пропускной системы по карте – привязать открытие замка/турникета к этому UID.
Обратите внимание! UID разный для каждой карты и чипа, т.е. у ваших RFID-карт и брелков будет свой UID, поэтому в следующих примерах не забудьте заменить UID примера на свой!
Теперь, давайте попробуем открыть наш замок, который имитируется с помощью сервопривода, с помощью нашей карты. Для этого напишем скетч, который будет обеспечивать работу нашей системы:
- При запуске программы должен зажигаться красный светодиод, а сервопривод поворачиваться на угол 0º (имитируем закрытие замка);
- При считывании правильного UID будет поворачиваем сервопривод на угол в 180º, выключаем красный и включаем зелёный светодиод (замок открывается);
- Выжидаем 3 секунды (пауза для открытия двери);
- Выключаем зелёный светодиод и зажигаем красный, при этом поворачиваем сервопривод в 0º (замок закрывается);
- В случае, если к считывателю поднесена неправильная карта, то красный светодиод должен мигнуть 2 раза;
- В последовательный порт при этом, должны посылаться сообщения “Доступ разрешён!” или “Доступ запрещён” в зависимости от поднесённой карты.
Давайте попробуем реализовать такую программу:
#include <SPI.h> // подключаем библиотеку для работы по SPI протоколу #include <MFRC522.h> // подключаем библиотеку для работы с RFID-RC522 #include <Servo.h>; // подключаем библиотеку для управления сервоприводом MFRC522 mfrc522(10, 9); // указываем пины, к которым подключены SDA и RST выходы const uint8_t valid_uid[] = { 0x80, 0x2B, 0x82, 0x15 }; // массив, в котором мы храним правильный UID карты // замените на UID своего RFID-чипа Servo my_servo; // Объявляем переменную типа Servo void setup() { Serial.begin(9600); // инициализируем последовательный порт SPI.begin(); // инициализируем SPI протокол передачи данных mfrc522.PCD_Init(); // инициализируем приёмник RFID Serial.println("Поднесите карту к считывателю..."); // Выводим сообщение о готовности в последовательный порт my_servo.attach(8); // инициализируем сервопривод на 8-м пине my_servo.write(0); // поворачиваем вал сервопривода в положение 0 градусов (закрываем замок) delay(500); // пауза, чтобы дать сервоприводу время для поворота my_servo.detach(); // отключаем сервопривод, чтобы он не "жужжал" и не потреблял энергию в простое pinMode(6, OUTPUT); // назначаем пины со светодиодами на выход pinMode(7, OUTPUT); digitalWrite(6, HIGH); // включаем красный светодиод digitalWrite(7, LOW); // выключаем зелёный светодиод } void loop() { if(!mfrc522.PICC_IsNewCardPresent()) // ждём пока рядом не будет обнаружен RFID-чип return; if(!mfrc522.PICC_ReadCardSerial()) // ждём пока приёмник не считает номер чипа return; if((mfrc522.uid.size == sizeof(valid_uid)) && // если UID карты совпадает с правильным UID (memcmp(&mfrc522.uid.uidByte, &valid_uid, sizeof(valid_uid)) == 0)) { my_servo.attach(8); // инициализируем сервопривод на 8-м пине Serial.println("Доступ разрешён!"); // выводим сообщение в последовательный порт digitalWrite(6, LOW); // выключаем красный светодиод digitalWrite(7, HIGH); // включаем зелёный светодиод my_servo.write(180); // поворачиваем вал в положение 180 градусов (открываем замок) delay(3000); // ждём 3 секунды digitalWrite(6, HIGH); // включаем красный светодиод digitalWrite(7, LOW); // выключаем зелёный светодиод my_servo.write(0); // поворачиваем вал в положение 0 градусов (закрываем замок) delay(500); // пауза, чтобы сервопривод успел провернуться my_servo.detach(); // инициализируем сервопривод на 8-м пине } else // если UID не совпадает с правильным { Serial.println("Доступ запрещён!"); // выводим сообщение в последовательный порт digitalWrite(6, LOW); // выключаем красный светодиод delay(250); // ждём 1/4 секунды digitalWrite(6, HIGH); // включаем красный светодиод delay(250); // ждём 1/4 секунды digitalWrite(6, LOW); // выключаем красный светодиод delay(250); // ждём 1/4 секунды digitalWrite(6, HIGH); // включаем красный светодиод } }
Подробные комментарии приведены внутри кода. Загрузите скетч в Arduino и проверьте его работу, поднося к считывателю свой брелок и карту.
Обратите внимание! Для того, чтобы ваш замок открылся, в массив переменных [valid_uid] необходимо записать UID своего брелка!
ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОГО ВЫПОЛНЕНИЯ
Задание 1:
Дополните код программы такими образом, чтобы при открытии замка, пьезодинамик издавал высокий звук, длительностью в 0,5 секунды, а в случае “неправильной” карты или брелка, издавал 3 низких коротких звука, длительность по 0,2 секунды.
Задание 2:
Дополните код программы таким образом, чтобы замок открывался как с помощью вашего брелка, там и с помощью вашей карты. Протестируйте ваш код взяв карту или брелок у соседа по группе или используя для проверки чип от вашего домофона.
Задание 3*:
Добавьте в схему устройства кнопку и дополните программу таким образом, чтобы при нажатой и удерживаемой кнопке, мы могли поднести к считывателю другой чип и он был бы записан как правильный, и в последствии мог открывать наш замок.
Задание 4*:
Дополните код программы таким образом, чтобы мы могли “добавлять” UID новых чипов в память Arduino и таким образом использовать для открытия замка каждый из них (принцип работы современных домофонов с несколькими чипами).