Как очистить блоки nfc rfid rc522
Перейти к содержимому

Как очистить блоки nfc rfid rc522

  • автор:

Создание системы ограничения доступа в программе FLProg с применением RFID-RC522

Добрый день. Я — разработчик программы FLProg, и сегодня я расскажу Вам как с помощью программы FLProg создать устройство контроля доступа с применением сканера бесконтактных меток RFID RC522. Поскольку данный пост – обучающий, то рассматриваться будет не законченное изделие, а только тестовый макет.

Рассмотрим данный сканер бесконтактных меток RFID RC522.

Сканер бесконтактных меток RFID-RC522 без меток позволяет обнаружить и считать идентификаторы бесконтактных карт, меток, пропусков стандарта 13,56 МГц на расстоянии до 10 см. Благодаря данному сканеру можно сделать ряд интересных проектов: пропускные системы, электронные замки, складской учету и много другое.

Технические характеристики сканера.

Параметр Значение
Потребляемый ток в активном состоянии 13-26mA/DC 3.3V
Потребляемый ток в состоянии ожидания 10-13mA/DC 3.3V
Ток в режиме сна
Рабочая частота 13.56MHz
Поддержвиаемые типы карт MIFARE S50, MIFARE S70, MIFARE UltraLight, MIFARE Pro, MIFARE DESfire
Размер 40mm х 60mm
Температура, при которой работает модуль -20 до +80 С
Относительная влажность воздуха от 5% до 95%

Базовый принцип действия довольно прост для понимания. В карточке и в считывателе есть антенны, при этом сигнал считывающего устройства (суть электромагнитное поле) одновременно служит источником питания для карточки. Т.е. и в части энергетики, и в части передачи данных это очень похоже на ставшие сверхпопулярными беспроводные зарядки.

Сами же карточки, в зависимости от модификации, могут нести в себе от нескольких десятков байт до нескольких килобайт данных (в том числе — уникальный серийный номер). Также, в зависимости от модификации, карточка может быть укомплектована криптографической защитой информации.

В Китае подобные сканеры стоят от 200 рублей в комплекте с картой и брелком. Это очень привлекательно. Но всё-таки при заказе данного сканера советую брать, как говорится «с запасом». В моём случае из трёх имеющихся у меня сканеров, купленных в разное время у разных продавцов, нормально заработал только один. Второй видел карту, только поднесённую точно на определённое расстояние. Ближе или дальше – он её терял. Ну и третий вообще не видел поднесённых карт, хотя на запросы и тестирование по SPI отвечал нормально.

В программе FLProg реализовано два вида функциональных блоков для работы со сканером.

  • «Наличие новой карты»
  • «Информация о карте»
  • «Чтения бока данных на карту»
  • «Запись блока данных на карту»

В программе реализовано хранилище UUID карт, представляющее собой набор ячеек каждая из которых хранит непосредственно UUID карты, и статус ячейки. Три статуса зарезервировано программой.

0х00 – ячейка свободна
0Х01 – в ячейке хранится UUID но она заблокирована.
0х02 — в ячейке хранится UUID и она активна

Остальные коды статуса (3 … 255) пользователь может использовать по своему усмотрению.

Хранилище может располагаться в оперативной памяти контроллера (при снятии питания или перезагрузке оно очистится), или в EEPROM. Хранилищ может быть несколько, и они могут быть разных типов. При расположении хранилища в EEPROM размеры его ограниченны. Для Arduino Uno –это максимум 85 ячеек (во всех хранилищах EEPROM в сумме), для Arduino Mega – 341 ячейка.

  • «Сохранить UUID карты в хранилище»
  • «Прочитать UUID карты из хранилища»
  • «Статус ячейки в хранилище»
  • «Записать статус ячейки в хранилище»
  • «Блокировка/разблокировка ячейки»
  • «Поиск UUID в хранилище»
  • «Свободные ячейки хранилища»
  • «Очистка ячейки в хранилище»
  • «Очистка всего хранилища»

Разберём ТЗ для задуманного устройства.
В устройстве будут два хранилища расположенных EEPROM. В первом хранятся так называемые Master Card. С помощью них можно записывать обычные карты во второе хранилище. Для записи Master Card существует «Секретная кнопка». Так же есть дисплей для отображения необходимой информации, и обычная управляющая кнопка.

Схема устройства.

Видео урок с описанием результата разработки

Карты и брелки используемые вместе со сканером имеют «на борту» 1 кБ памяти которые можно использовать в собственных целях. Давайте расширим ТЗ и будем записывать, какую либо информацию. Для этого соберём еще одно устройство.

Так же доработаем проект созданный в предыдущем видео уроке.

До свидания, надеюсь Вам было интересно.

Как очистить блоки nfc rfid rc522

Найдите лучшие предложения для смарт-гаджетов в одном месте.

Простые и безопасные платежи

Оплата напрямую через PayPal или Klarna среди других способов оплаты.

Местный склад и быстрая доставка

Купите на местном складе и отправьте в течение 48 часов.

Служба поддержки

Круглосуточная поддержка клиентов по всем вашим вопросам.

Документи Как отслеживать О нас Контакты Гарантия Часто задаваемые вопросы Статус заказа Карта сайта
Поддержка Руководство по доставке Информация об оплате Опт / корпоратив Доставка Филиалы Блог
Налоги и сборы Правила и условия Политика возврата Политика Декларация Таможня

Скачать приложение

Свяжитесь с нами:
Популярные запросы
Copyright © 2012-2024 Geekbuying.com. Все права защищены.
Онлайн Чат

Загрузите приложение, чтобы получить скидку до 70% на предложения только для приложений и купоны на сумму 50 долларов США.

Войти/Создать аккаунт Эл. адрес Продолжить в качестве гостя
Или продолжите другими способами
Google Apple
Продолжая, вы соглашаетесь с нашими Условия использования & Персональные данные
Вход Эл. адрес
Забыли пароль?
Регистрация
Создайте свою учетную запись Geekbuying

Регистрация простая, просто введите пароль

Зарегистрируйтесь, чтобы получить G-coins на сумму €1.84

Зарегистрируйтесь, чтобы получить купоны на 55.24 евро и G-монеты на сумму 4.60 евро.

Эл. адрес Пароль

Ваш пароль должен включать следующее:

минимум 8 символов

Хотя бы одно письмо

Хотя бы одна цифра или специальный символ

Я согласен с Geekbuying Условия использования & Персональные данные. Чтобы завершить регистрацию, вы должны согласиться с положениями и условиями сайта GeekBuying. Присылайте мне электронные письма о новых поступлениях, горячих позициях, ежедневных сбережениях и многом другом. Подпишитесь, чтобы получить скидку 55.24 евро (купоны * 5) и 3 G-монеты стоимостью 2.76 евро.

Вы успешно создали свой аккаунт!

Ссылка для активации была отправлена ​​на ваш адрес электронной почты. Активируйте свою учетную запись для доступа к следующему:

  • Скидка 2 на скидочный код
  • Просмотр информации о выставлении счетов и доставке
  • Создание и изменение вашей личной учетной записи
  • Проверка статуса вашего заказа, отзывов, корзины и списка пожеланий
  • После активации учетной записи вы получите G-coins на сумму 1.84 евро.
  • Спасибо за подписку. Вы получили награду. просмотреть это под МОЙ АККАУНТ

Если вы не получили электронное письмо с кодом активации, нажмите ниже, чтобы отправить электронное письмо с кодом активации.

Возмущаться успешно. Пожалуйста, проверьте ваш электронный ящик, чтобы получить скидку!

Работа с Arduino и RFID MFRC522

Технология RFID (Радиочастотная идентификация) позволяет при помощи радиосигнала быстро и безопасно передавать данные между специальными “считывателями” и “метками” – карточками, брелоками, браслетами и т.д. на небольшом расстоянии.
Одно из широко известных развитий технологии – NFC, при помощи которого можно оплачивать покупки или подключать устройства бесконтактно. Нам же доступны менее сложные, но не менее полезные и интересные применения, о которых будет сказано ниже.

Применение

Комплект RFID модуль + метки может быть использован:

  • Как часть самодельных охранных систем
  • При создании простых электронных замков (метка является ключом)
  • В системах контроля доступа (однократный, многократный пропуск)
  • В качестве электронного “кошелька” внутри собственного предприятия
  • В роли интерактивного предмета в квестах и т.д.

Железо

RFID работает в нескольких частотных диапазонах, в свою очередь RFID модули и метки можно поделить на низкочастотные “LF” (125 кгц) и высокочастотные “HF” (13,56 MHz), существуют так же и ультравысокочастотные “UHF”, но они нас не интересуют.

Наиболее распространенные RFID Arduino-модули основаны на микросхеме MFRC522, работающей с HF метками 13,56 МГц. Поиск модулей и библиотек производится по этому же имени.

Существует два типа модулей MFRC522, с которыми вы скорее всего столкнетесь:

Отвечая на главный вопрос – не смотря на значительную разницу в размере, ощутимой разницы в работе модулей нет, можно брать любой. В комплекте к модулю как правило уже идет несколько меток.

Библиотеки

Для работы с модулем MFRC522 понадобится библиотека https://github.com/miguelbalboa/rfid. Библиотека тяжелая, индусская и имеет немало проблем, но достойных альтернатив просто нет – несколько других “облегченных” библиотек значительно уступают в функциональности и удобстве использования.

Подключение

Модуль MFRC522 подключается по аппаратному интерфейсу SPI, выбранная библиотека предоставляет следующую таблицу подключения к Arduino:

Сигнал Модуль MFRC522 UNO/NANO Leonardo Pro micro Mega
Reset RST D9 RST/ISCP-5 RST D5
Chip select SDA (SS) D10 D10 D10 D53
MOSI MOSI D11 ISCP-4 D16 D51
MISO MISO D12 ISCP-1 D14 D50
SCK SCK D13 ISCP-3 D15 D52
  • Контакты модуля RST и SDA (SS) указываются в скетче – можно использовать любые.
  • У Leonardo подключение производится к 6-ти контактному ICSP разъему программатора.

Пример подключения модуля к Arduino Nano:

О RFID метках

Прежде всего самая сложная для понимания, но и самая важная часть – работа с RFID метками. В комплекте с модулем идут пара меток MIFARE Classic 1K, как понятно из названия – на 1 килобайт (на самом деле меньше, но об этом позже).

Чтобы изучить организацию памяти такой метки, можно воспользоваться примером из библиотеки, открыв Примеры > MFRC522 > DumpInfo. Однако для вашего удобства я подготовил вот такую карту:

Обратите внимание – память организована в виде 16-ти секторов, по 4 блока каждый. Итого – 64 блока по 16 Байт, как раз набегает 1 Килобайт. Деление по секторам носит скорее условный характер, так как адресация в памяти будет производиться по блокам.

Все сектора кроме нулевого имеют одинаковое строение – 3 блока данных + 1 блок безопасности, так называемый sector trailer. Каждый из этих блоков может быть прочитан и перезаписан (при соблюдении условий), исключение составляет нулевой блок (сектор 0).

Нулевой блок хранит в себе уникальный ID “UID”, тип метки и прочую информацию, записанную заводом-изготовителем. Нулевой сектор не может быть перезаписан, если речь идет о “классических” метках, к которым относятся комплектные с модулем. Таким образом UID позволяет отличить две с виду идентичные метки. UID как правило состоит из 4х байт, свободно считываемых из метки. Важно: китайский рынок может предложить вам “перезаписываемые” метки, UID в которых можно менять, путем перезаписи нулевого блока. Если в вашей системе используется только UID – учтите возможность очень простого копирования UID в метки-болванки (в том числе злоумышленниками).

Блоком безопасности является каждый 4й блок, каждый блок безопасности отвечает за свой сектор (предыдущие 3 блока данных) – он хранит 2 ключа доступа по 6 байт (ключи A и B), а также специальные “Access bits” (Биты доступа), грубо говоря настройки доступа. Ключи A и B могут быть использованы для аутентификации и последующего доступа к блокам данных в пределах сектора. То есть да, для того чтобы получить доступ к любому из блоков внутри сектора необходимо “разблокировать” этот сектор, при помощи одного из ключей.

Поэтому будьте уверены, если производитель позаботился о смене секретных ключей в своих RFID метках – скопировать или как-нибудь изменить содержимое штатными средствами вы уже не сможете, а ведь так хотелось? Идем дальше.

Биты доступа позволяют настроить условия доступа и возможности работы каждого блока в отдельности (каждого блока данных + блока безопасности). Наилучшим инструментом в работе с метками MIFARE Classic 1K является вот этот онлайн-калькулятор http://calc.gmss.ru/Mifare1k/. Если хотите разобраться чуть глубже – обязательно полистайте и опробуйте.

Я же хочу сэкономить ваше время, поэтому сразу уточню, что наиболее удачным решением в большинстве ситуаций будет оставить блоки данных в состоянии transport configuration, то есть по умолчанию.

blank

Однако есть возможность настроить блоки на некоторые интересные сценарии, например защитить от записи (конфигурация 1-0-1 или 0-1-0). Или же сделать так, что прочитать блок можно при помощи как ключа A, так и ключа B, а вот для записи обязательно понадобится ключ B (конфигурация 1-0-0), в таком случае можно ограничить права некоторого оборудования и сделать систему безопаснее. И да, конфигурация 1-1-1 превращает блок в кирпич (обратимо).

В примерах ниже мы будем использовать конфигурацию блоков данных по умолчанию (0-0-0) и следующие принципы:

  • Создаем ключ B, значение которого знаем только мы, длина ключа – 6 Байт.
  • Ключ A будет полностью аналогичен ключу B, однако он не будет использоваться.
  • Биты доступа для блоков безопасности будем использовать в конфигурации 0-1-1

blank

Таким образом для всех операций с меткой применяется только ключ B, который невозможно считать из метки (впрочем, как и ключ A), даже если сектор предварительно разблокирован. Если хотите намертво зашить ключи A и B в блок безопасности – подойдет конфигурация 1-0-1, поменять будет уже невозможно. Ну а последняя 1-1-1 конфигурация блока безопасности заблокирует еще и настройки доступа к блокам данных!

Некоторые варианты необратимы, но не переживайте – у вас есть целых 16 попыток! По одной на каждый сектор.

В итоге 3 байта настроек доступа приняли следующие значения: 0x7F 0x07 0x88, байт USER может быть любой.

blank

Важно: изначально ключи A и B от всех секторов метки содержат значение 0xFFFFFFFFFFFF, так что если хотите защитить данные в ваших метках, не забывайте сменить оба ключа! Кстати, нулевой блок и соответственно UID свободно читаются из метки, даже если нулевой сектор был заблокирован секретными ключами.

Ну и последнее, что касается меток – реальный объем пользовательской памяти. Если не создавать костыли, а использовать только блоки для хранения данных – (по 3 блока в 15-ти секторах, и 2 блока в нулевом секторе) получаем 47 доступных блоков по 16 байт или 752 байта, что тоже неплохо.

Начало работы

Подключили модуль, распаковали свежие метки – начинаем работать!

Прежде всего создаем необходимые объекты, инициализируем интерфейс SPI и MFRC522, не забываем про ключ доступа. Изначально все ключи состоят из FF-ок, так что “наполняем” ключ.

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xFF; // Ключ по умолчанию 0xFFFFFFFFFFFF >> void loop() <>

Работу с RFID модулем удобнее всего производить в конце главного цикла программы, сейчас поймете почему. Для отслеживания поднесенной метки библиотека предлагает использовать пару методов с замысловатыми названиями:

if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop

Если поднесенная метка успешно считана – программа идет дальше, в противном случае происходит возврат в начало главного цикла, а весь блок кода связанный с RFID пропускается.

В итоге наш скетч имеет следующую структуру:

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xFF; // Ключ по умолчанию 0xFFFFFFFFFFFF >> void loop() < // Занимаемся чем угодно if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop // Работаем с RFID >

Теперь давайте идти по порядку, осваивая основные методы для работы с RFID.

Обратите внимание: примеры ниже содержат специальные блоки кода, повышающие стабильность работы, о них подробно сказано в конце статьи.

Чтение UID

Самое простое, что можно сделать с RFID меткой – прочитать UID, в некоторых системах уже этого функционала вполне достаточно, например – в простых электронных замках. Как уже сказано ранее, некоторые метки позволяют сменить UID, в свою очередь запретить считать UID из ваших меток не получится – учтите это при разработке.

Так или иначе пример чтения UID и вывод в порт приведен ниже:

Чтение UID

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля rfid.PCD_SetAntennaGain(rfid.RxGain_max); // Установка усиления антенны rfid.PCD_AntennaOff(); // Перезагружаем антенну rfid.PCD_AntennaOn(); // Включаем антенну for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xFF; // Ключ по умолчанию 0xFFFFFFFFFFFF >> void loop() < // Занимаемся чем угодно static uint32_t rebootTimer = millis(); // Важный костыль против зависания модуля! if (millis() - rebootTimer >= 1000) < // Таймер с периодом 1000 мс rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(2); // Ждем 2 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем заного >if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop Serial.print("UID: "); for (uint8_t i = 0; i < 4; i++) < // Цикл на 4 итерации Serial.print("0x"); // В формате HEX Serial.print(rfid.uid.uidByte[i], HEX); // Выводим UID по байтам Serial.print(", "); >Serial.println(""); >

После успешного чтения метки, ее UID появляется в массиве rfid.uid.uidByte[] который можно прочитать и использовать.

Чтение блока

Если чтением UID ваш интерес не ограничился – давайте узнаем, как читать блок данных из метки. Прежде чем что-либо читать или писать, необходимо аутентифицировать (разблокировать) сектор, в котором находится интересующий нас блок.

В примерах ниже будем работать с блоком под номером 6 (сектор 1), за первый сектор и соответственно блоки 4, 5 и 6 отвечает блок безопасности под номером 7. То есть запомнили – блок данных 6, блок безопасности 7.

Аутентификацию сектора производит метод PCD_Authenticate() , по умолчанию все манипуляции с меткой возможны при помощи ключа A, а сам процесс аутентификации выглядит следующим образом:

status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >

Обратите внимание на …KEY_A в первом аргументе и цифру 7 вторым аргументом – это и есть номер блока безопасности. Отслеживать статус не обязательно, но крайне желательно.

После успешной аутентификации можно свободно манипулировать разблокированным сектором, в нашем случае будем читать содержимое методом MIFARE_Read() . Читать нужно в байтовый массив, размером 18 (!) байт, чтение происходит из блока 6 (первый аргумент) и выглядит так:

uint8_t dataBlock[18]; // Буфер для чтения uint8_t size = sizeof(dataBlock); // Размер буфера status = rfid.MIFARE_Read(6, dataBlock, &size); // Читаем 6 блок в буфер if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Read error"); // Выводим ошибку return; >

Важно: Не смотря на то, что блоки имеют размер 16 байт, буферный массив создается на 18 байт, а количество байт на чтение передается именно в виде указателя на переменную. В противном случае чтение закончится ошибкой, примите это как факт.

В случае успешного чтения, выведем содержимое блока 6 в монитор порта, все как обычно:

Serial.print("Data:"); // Выводим 16 байт в формате HEX for (uint8_t i = 0; i < 16; i++) < Serial.print("0x"); Serial.print(dataBlock[i], HEX); Serial.print(", "); >Serial.println("");

А завершать работу с меткой нужно при помощи еще двух замысловатых методов:

rfid.PICC_HaltA(); // Завершаем работу с меткой rfid.PCD_StopCrypto1();

В итоге полный скетч для чтения блока 6 из новой метки со стандартными ключами выглядит так:

Чтение блока

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля rfid.PCD_SetAntennaGain(rfid.RxGain_max); // Установка усиления антенны rfid.PCD_AntennaOff(); // Перезагружаем антенну rfid.PCD_AntennaOn(); // Включаем антенну for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xFF; // Ключ по умолчанию 0xFFFFFFFFFFFF >> void loop() < // Занимаемся чем угодно static uint32_t rebootTimer = millis(); // Важный костыль против зависания модуля! if (millis() - rebootTimer >= 1000) < // Таймер с периодом 1000 мс rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(2); // Ждем 2 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем заного >if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop /* Аутентификация сектора, указываем блок безопасности #7 и ключ A */ status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >/* Чтение блока, указываем блок данных #6 */ uint8_t dataBlock[18]; // Буфер для чтения uint8_t size = sizeof(dataBlock); // Размер буфера status = rfid.MIFARE_Read(6, dataBlock, &size); // Читаем 6 блок в буфер if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Read error"); // Выводим ошибку return; >/* Выводим содержимое блока в Serial */ Serial.print("Data:"); // Выводим 16 байт в формате HEX for (uint8_t i = 0; i < 16; i++) < Serial.print("0x"); Serial.print(dataBlock[i], HEX); Serial.print(", "); >Serial.println(""); rfid.PICC_HaltA(); // Завершаем работу с меткой rfid.PCD_StopCrypto1(); >

После поднесения метки в мониторе порта должны отобразиться 16 байт – содержимое прочитанного блока.

Запись блока

При записи все 16 байт записываются в блок единовременно, для чего должен быть заранее подготовлен байтовый массив на 16 Байт, например такой:

uint8_t dataToWrite[16] = < 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x00, 0x00, 0x00 >;

Как в случае и с чтением, сектор в котором находится нужный блок 6 нужно предварительно аутентифицировать, об этом уже сказано выше, так что переходим непосредственно к записи. Запись производится методом MIFARE_Write() , в отличии от MIFARE_Read() тут все несколько проще – указываем записываемый блок, массив и число 16 (количество байт на запись):

status = rfid.MIFARE_Write(6, dataToWrite, 16); // Пишем массив в блок 6 if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Write error"); // Выводим ошибку return; >

Итоговый скетч записи массива в блок 6 выглядит так:

Запись блока

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля rfid.PCD_SetAntennaGain(rfid.RxGain_max); // Установка усиления антенны rfid.PCD_AntennaOff(); // Перезагружаем антенну rfid.PCD_AntennaOn(); // Включаем антенну for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xFF; // Ключ по умолчанию 0xFFFFFFFFFFFF >> void loop() < // Занимаемся чем угодно static uint32_t rebootTimer = millis(); // Важный костыль против зависания модуля! if (millis() - rebootTimer >= 1000) < // Таймер с периодом 1000 мс rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(2); // Ждем 2 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем заного >if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop /* Аутентификация сектора, указываем блок безопасности #7 и ключ A */ status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >/* Запись блока, указываем блок данных #6 */ uint8_t dataToWrite[16] = < // Массив на запись в блок 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x00, 0x00, 0x00 >; status = rfid.MIFARE_Write(6, dataToWrite, 16); // Пишем массив в блок 6 if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Write error"); // Выводим ошибку return; >Serial.println("Write OK"); // Завершаем работу с меткой rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); >

После поднесения метки в мониторе порта должно отобразиться сообщение “Write OK“.

К слову ничто не мешает нам объеденить запись и чтение в одном скетче:

Запись + чтение блока

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля rfid.PCD_SetAntennaGain(rfid.RxGain_max); // Установка усиления антенны rfid.PCD_AntennaOff(); // Перезагружаем антенну rfid.PCD_AntennaOn(); // Включаем антенну for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xFF; // Ключ по умолчанию 0xFFFFFFFFFFFF >> void loop() < // Занимаемся чем угодно static uint32_t rebootTimer = millis(); // Важный костыль против зависания модуля! if (millis() - rebootTimer >= 1000) < // Таймер с периодом 1000 мс rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(2); // Ждем 2 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем заного >if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop /* Аутентификация сектора, указываем блок безопасности #7 и ключ A */ status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >/* Запись блока, указываем блок данных #6 */ uint8_t dataToWrite[16] = < // Массив на запись в блок 0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x00, 0x00, 0x00 >; status = rfid.MIFARE_Write(6, dataToWrite, 16); // Пишем массив в блок 6 if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Write error"); // Выводим ошибку return; >/* Чтение блока, указываем блок данных #6 */ uint8_t dataBlock[18]; // Буфер для чтения uint8_t size = sizeof(dataBlock); // Размер буфера status = rfid.MIFARE_Read(6, dataBlock, &size); // Читаем 6 блок в буфер if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Read error"); // Выводим ошибку return; >Serial.print("Data:"); // Выводим 16 байт в формате HEX for (uint8_t i = 0; i < 16; i++) < Serial.print("0x"); Serial.print(dataBlock[i], HEX); Serial.print(", "); >Serial.println(""); rfid.PICC_HaltA(); // Завершаем работу с меткой rfid.PCD_StopCrypto1(); >

Смена ключей безопасности и настройка блоков

Если вы хотите не только уметь читать и писать данные в метки, но и защить хранящуюся там информацию от стороннего вмешательства – необходимо сменить ключи доступа как минимум от тех секторов, в которых вы собираетесь хранить данные, однако в идеале установить новые ключи для всех секторов, чтобы усложнить задачу потенциальным взломащикам.

Для того, чтобы изменить ключи доступа к сектору, необходимо перезаписать блок безопасности, ответственный за данный сектор. В наших примерах фигурировал блок данных под номером 6 и соответственно блок безопасности под номером 7. Задача по смене ключей безопасности сводится к следующим шагам:

  1. Создать байтовый массив на 16 ячеек, включающий:
    • Ключ A
    • Байты настроек доступа
    • Ключ B
  2. Провести аутентификацию выбранного сектора, пока что используя стандартный ключ 0xFFFFFFFFFFFF
  3. Произвести запись подготовленного массива в блок безопасности, в точности так же, как в случае с обычным блоком.

После этого ключи безопасности будут изменены, а мы сможем безопасно хранить данные в одном или нескольких блоках выбранного сектора! Сейчас покажу по шагам.

  1. Для создания образа блока безопасности (содержимого массива) придется вернуться вверх по тексту и вспомнить, что при выбранных нами настройках сектора, байты доступа получили значения 0x7F 0x07 0x88. Осталось придумать ключи доступа, имеющие длину 6 байт. Я буду использовать ключ 0xABABABABABAB, данный ключ не является безопасным и подходит исключительно для демонстрации! Так же напоминаю, что ключи A и B будут идентичны, однако использоваться будет только ключ B.

blank

    1 После того, как мы определились с настройками сектора (“Access Bits“) и ключами безопасности – создаем нужный байтовый массив:

uint8_t secBlockDump[16] = < // Дамп блока безопасности 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, // < Ключ A 0x7F, 0x07, 0x88, // < Access Bits 0xFF, // < User байт (любой) 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB // < Ключ B >;
status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >
status = rfid.MIFARE_Write(7, secBlockDump, 16); // Пишем массив в блок 6 if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Write error"); // Выводим ошибку return; >

Итоговый скетч записи новых ключей и настроек доступа:

Запись блока безопасности

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля rfid.PCD_SetAntennaGain(rfid.RxGain_max); // Установка усиления антенны rfid.PCD_AntennaOff(); // Перезагружаем антенну rfid.PCD_AntennaOn(); // Включаем антенну for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xFF; // Ключ по умолчанию 0xFFFFFFFFFFFF >> void loop() < // Занимаемся чем угодно static uint32_t rebootTimer = millis(); // Важный костыль против зависания модуля! if (millis() - rebootTimer >= 1000) < // Таймер с периодом 1000 мс rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(2); // Ждем 2 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем заного >if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop /* Аутентификация сектора, указываем блок безопасности #7 и ключ A */ status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >/* Запись блока, указываем блок безопасности #7 */ uint8_t secBlockDump[16] = < // Дамп блока безопасности 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, // < Ключ A 0x7F, 0x07, 0x88, // < Access Bits 0xFF, // < User байт (любой) 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB // < Ключ B >; status = rfid.MIFARE_Write(7, secBlockDump, 16); // Пишем массив в блок 7 if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Write error"); // Выводим ошибку return; >Serial.println("Write OK"); // Завершаем работу с меткой rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); >

Важно: при повторном поднесении метки мы неизбежно получим ошибку аутентификации, это связано с тем, что стандартный ключ больше не подходит к перенастроенному сектору!

Не забываем сменить “наполнение” ключа в void setup()<> :

for (byte i = 0; i < 6; i++) < // Наполняем ключ key.keyByte[i] = 0xAB; // Пишем свой ключ >

Так же напоминаю, что отныне для сектора 1 (блоков 4…7) мы используем только ключ B, соответственно и команда аутентификации отныне выглядит чуть иначе:

status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >

Работа с защищенным сектором

Теперь, после того как мы сменили ключи безопасности от сектора 1, в качестве примера будем выводить количество поднесений метки к считывателю в последовательный порт. Количество поднесений хранится в нулевом байте защищенного блока 6 и увеличивается при каждом поднесении:

Инкремент при поднесении

#include #include #define RST_PIN 9 // Пин rfid модуля RST #define SS_PIN 10 // Пин rfid модуля SS MFRC522 rfid(SS_PIN, RST_PIN); // Объект rfid модуля MFRC522::MIFARE_Key key; // Объект ключа MFRC522::StatusCode status; // Объект статуса void setup() < Serial.begin(9600); // Инициализация Serial SPI.begin(); // Инициализация SPI rfid.PCD_Init(); // Инициализация модуля rfid.PCD_SetAntennaGain(rfid.RxGain_max); // Установка усиления антенны rfid.PCD_AntennaOff(); // Перезагружаем антенну rfid.PCD_AntennaOn(); // Включаем антенну for (byte i = 0; i < 6; i++) < // Наполняем ключ B key.keyByte[i] = 0xAB; // Пишем свой ключ >> void loop() < // Занимаемся чем угодно static uint32_t rebootTimer = millis(); // Важный костыль против зависания модуля! if (millis() - rebootTimer >= 1000) < // Таймер с периодом 1000 мс rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(2); // Ждем 2 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем заного >if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop /* Аутентификация сектора, указываем блок безопасности #7 и ключ B */ status = rfid.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, 7, &key, &(rfid.uid)); if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Auth error"); // Выводим ошибку return; >/* Чтение блока, указываем блок данных #6 */ uint8_t dataBlock[18]; // Буфер uint8_t size = sizeof(dataBlock); // Размер буфера status = rfid.MIFARE_Read(6, dataBlock, &size); // Читаем блок 6 if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Read error"); // Выводим ошибку return; >/* Выводим количество поднесений метки */ Serial.print("Count: "); // Выводим количество Serial.println(dataBlock[0]); // Хранится в нулевом байте массива dataBlock[0]++; // Инкремент /* Запись блока, указываем блок данных #6 */ status = rfid.MIFARE_Write(6, dataBlock, 16); // Пишем массив в блок 6 if (status != MFRC522::STATUS_OK) < // Если не окэй Serial.println("Write error"); // Выводим ошибку return; >rfid.PICC_HaltA(); // Завершаем работу с меткой rfid.PCD_StopCrypto1(); >

Количество поднесений ограничено 255, потому что используется лишь 1 Байт, но для примера это и не важно.

Инкремент и декремент

Наболее продвинутые могут обратить внимание на то, что пример выше не имеет смысла, поскольку метки уже имеют функционал инкремента и декремента, позволяющего использовать защищенный блок в качестве электронного кошелька.

Для реализации данного функционала библиотека имеет методы MIFARE_Increment() и MIFARE_Decrement() , однако независимо от установленных байтов доступа данный функционал не показал работоспособность на десятке меток и нескольких модулях. Возможно всему виной поддельные чипы MFRC522, установленные в модули. В любом случае перечисленные методы возвращают ошибку при поднесении метки, а потому и пример для работы не привожу.

Особенности и костыли

Несмотря на то, что данные модули выпускаются много лет, в течение которых дорабатывалась и библиотека, пара модуль + библиотека имеют критическую проблему зависания (!). Через случайный промежуток времени система просто перестает считывать поднесенные метки – помогает только перезагрузка микроконтроллера. Этот критический баг может сыграть злую шутку, при использовании данного комплекта в электронных замках. Что является причиной? На данный момент достоверного ответа нет… однако есть кое-какие решения!

  • Периодическая перезагрузка и повторная инициализация. В главный цикл программы добавляется таймер на millis() с периодом 500…3000 мс, внутри которого производится принудительный сброс и инициализация модуля. Данный код располагается в начале главного цикла программы. Данный костыль является наиболее эффективным в борьбе с зависанием модуля.
static uint32_t rebootTimer = millis(); // Важный костыль против зависания модуля! if (millis() - rebootTimer >= 1000) < // Таймер с периодом 1000 мс rebootTimer = millis(); // Обновляем таймер digitalWrite(RST_PIN, HIGH); // Сбрасываем модуль delayMicroseconds(2); // Ждем 2 мкс digitalWrite(RST_PIN, LOW); // Отпускаем сброс rfid.PCD_Init(); // Инициализируем заного >
rfid.PCD_SetAntennaGain(rfid.RxGain_max); // Установка усиления антенны rfid.PCD_AntennaOff(); // Перезагружаем антенну rfid.PCD_AntennaOn(); // Включаем антенну
if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) return; // Если метка не читается - вернуться в начало loop

Фокус заключается в добавлении еще одной попытке чтения метки, в случае неудачи. Таким образом наша конструкция принимает следующий вид:

if (!rfid.PICC_IsNewCardPresent()) return; // Если новая метка не поднесена - вернуться в начало loop if (!rfid.PICC_ReadCardSerial()) < // Если метка не читается - пробуем еще раз if (!rfid.PICC_ReadCardSerial()) return; // Все равно не читается - вернуться в начало loop >

Наиболее эффективным и важным является первый костыль, располагайте его перед работой с модулем, желательно в начале цикла void loop()<> , но ни в коем случае не в прерывании таймера. Однако несмотря на то, что приведенные выше хитрости действительно работают и многократно повышают стабильность работы RFID модуля – в случае с электронными замками и прочими системами контроля доступа рекомендуется иметь резервные способы входа, помимо RFID.

RFID-модуль RC522: полное руководство по описанию, подключению и первым шагам в разработке

RFID модуль RC522 – устройство для чтения и записи данных с помощью технологии радиочастотной идентификации (RFID). Этот метод широко применяется в различных областях, где требуется бесконтактная идентификация, контроль доступа, управление запасами и другие подобные задачи. Модули RC522 – популярные узлы, поддерживающие стандарт ISO/IEC 14443 A/MIFARE.

Особенности технологии

По сути, модуль RFID RC522 – считыватель RFID, работающий на частоте 13,56 МГц. Оснащен антенной для обмена данными с метками и микросхемой для обработки информации, в его состав также входит:

  1. RFID-чип. Обрабатывает сигналы от антенны, декодирует их и взаимодействует с метками. Является основным компонентом.
  2. Контроллер SPI. Нужен для обмена данными между RFID-чипом и другими устройствами. Использует протокол последовательной связи SPI (Serial Peripheral Interface).
  3. Сигнальные светодиоды. Узел чаще всего содержит светодиоды, которые индицируют взаимодействие с микроконтроллерами или другими устройствами. Использует радиоволны модуля (например, подключение к питанию).

Для работы с модулем RC522 обычно используют микроконтроллеры (например, RFID модуль Arduino ), которые взаимодействуют с ним через интерфейс. Модуль предоставляет средства для чтения и записи данных на RFID-карты, а также обеспечивает безопасность с помощью методов шифрования и аутентификации, поддерживаемых стандартом ISO/IEC 14443 A/MIFARE.

Принцип работы

Микроконтроллер модуля (узла) инициализирует антенну для генерации радиочастотного поля и обнаружения метки. Когда метка находится в радиусе действия поля, она получает энергию от него и начинает отвечать, передавая свои данные.

Работая, RFID модуль получает данные от метки и декодирует их. При успешном чтении модуль может передать эту информацию другим устройствам. При необходимости он отправляет данные на метку, записывая информацию на нее.

Первые шаги в разработке

Перед началом работы с модулем RC522 необходимо установить библиотеку. При RFID модуль «Ардуино» – это библиотека, предоставляющая удобный интерфейс для дальнейшей работы с модулем. После подключения и инициализации узла вы можете выполнять такие задачи, как чтение уникального идентификатора метки, запись и чтение данных.

Подключение RC522

Для подключения модуля RC522 к платформе, такой как Arduino или Raspberry Pi, вам потребуются следующие соединения:

  • VCC – подключение к источнику питания (обычно 3,3 V);
  • RST – к пину, который используется для сброса модуля;
  • GND – к земле;
  • IRQ – необязательное подключение к пину прерывания;
  • MISO, MOSI, SCK – к соответствующим пинам для обмена данными по SPI;
  • SDA (SS) – к пину выбора рабочего устройства.

Область применения модуля многогранна. Он позволяет управлять доступом через бесконтактные карты или браслеты, что облегчает пользование, усиливает безопасность. Используется в таких сферах:

  1. В общественном транспорте при бесконтактной оплате – быстрая и удобная оплата проезда.
  2. В системе умного дома – управление дверными замками, освещением, системами безопасности.
  3. Аутентификация – обеспечение безопасности данных и доступа к системам.
  4. Логистика и транспорт – отслеживание грузов и контроль доступа на транспортных узлах, что способствует оптимизации логистических процессов.
  5. Медицинская идентификация – учет пациентов и медицинского оборудования.
  6. Образование – отслеживание посещаемости студентов и упрощение процесса регистрации.
  7. Промышленность – дополнительный компонент системы автоматизации и контроля доступа персонала в опасные зоны.

RFID модуль, купить который вы можете в нашей компании, позволяет реализовать функциональность бесконтактного чтения и записи данных. Оно находит широкое применение в различных системах автоматизации и идентификации, интегрируя соответствующие технологии в ваши проекты.

Независимо от того, нужен вам контроль доступа или управление инвентарем, RFID-считыватель RC522 может быть надежным решением для ваших потребностей.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *