Что такое RFID? Как это работает? Взаимодействие RFID модуля RC522 с Arduino

Добавлено 27 февраля 2020 в 21:46

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

Что такое RFID? Как это работает? Взаимодействие RFID модуля RC522 с Arduino
Что такое RFID? Как это работает? Взаимодействие RFID модуля RC522 с Arduino

Для большинства наших проектов на Arduino отличным выбором будет RFID модуль чтения/записи RF522. Он обладает низким энергопотреблением, низкой стоимостью, он довольно прочный, прост для взаимодействия и безумно популярен среди любителей.

Что такое технология RFID и как она работает?

RFID или система радиочастотной идентификации состоит из двух основных компонентов: транспондера или метки, прикрепленной к идентифицируемому объекту, и приемопередатчика, также известного как интеррогатор (interrogator) или считыватель.

Рисунок 1 Как работает технология RFID
Рисунок 1 – Как работает технология RFID

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

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

Рисунок 2 Как работает технология RFID
Рисунок 2 – Как работает технология RFID

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

Обзор аппаратного обеспечения - Модуль чтения / записи RF522 RFID

RFID модуль RC522 на основе микросхемы MFRC522 от NXP – это один из самых недорогих вариантов RFID, который вы можете найти в интернете менее чем за четыре доллара. Обычно он поставляется с картой RFID метки и брелоком с объемом памяти 1 КБ. И что лучше всего, он может записать метку, чтобы вы могли хранить в ней свое секретное сообщение.

Рисунок 3 Модуль RFID считывателя RC522 с меткой-картой и меткой-ключом
Рисунок 3 – Модуль RFID считывателя RC522 с меткой-картой и меткой-ключом

Модуль считывателя RFID RC522 предназначен для создания электромагнитного поля на частоте 13,56 МГц, которое он использует для связи с метками RFID (стандартные метки ISO 14443A). Считыватель может взаимодействовать с микроконтроллером через 4-контактный последовательный периферийный интерфейс (SPI) с максимальной скоростью передачи данных 10 Мбит/с. Он также поддерживает связь по протоколам I2C и UART.

У модуля имеется вывод прерывания. Это удобно потому, что вместо того, чтобы постоянно опрашивать RFID модуль «есть ли карта в поле зрения?», модуль сам предупредит нас, когда метка окажется рядом.

Рабочее напряжение модуля составляет от 2,5 до 3,3 В, но хорошая новость заключается в том, что логические выводы допускают напряжение 5 вольт, поэтому мы можем легко подключить его к Arduino или любому микроконтроллеру с 5-вольтовой логикой без использования какого-либо преобразователя логических уровней.

Характеристики RFID модуля RC522
Частотный диапазон13,56 МГц, ISM диапазон
ИнтерфейсSPI / I2C / UART
Рабочее напряжение питанияот 2,5 В до 3,3 В
Максимальный рабочий ток13-26 мА
Минимальный ток (отключение питания)10 мкА
Логические входыдопускают 5 В
Расстояние считывания5 см

Распиновка RFID модуля RC522

Модуль RC522 имеет всего 8 контактов, соединяющих его с внешним миром.

Рисунок 4 Распиновка RFID модуля считывателя RC522
Рисунок 4 – Распиновка RFID модуля считывателя RC522

VCC обеспечивает питание для модуля. Напряжение питания может быть в диапазоне от 2,5 до 3,3 вольт. Вы можете подключить его к выходу 3.3V вашей платы Arduino. Помните, что подключение его к выводу 5V, скорее всего, выведет модуль из строя!

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

GND вывод земли, должен быть подключен к выводу GND на Arduino.

IRQ – вывод прерывания, который может предупредить микроконтроллер, когда поблизости будет RFID метка.

Вывод MISO / SCL / Tx действует либо как Master-In-Slave-Out (вход ведущего – выход ведомого) при включенном интерфейсе SPI, либо как последовательный тактовый сигнал при включенном интерфейсе I2C, либо как выход последовательных данных при включенном интерфейсе UART.

MOSI (Master Out Slave In) – вход SPI для модуля RC522.

SCK (Serial Clock) принимает тактовые импульсы, предоставляемые мастером на шине SPI, то есть Arduino.

Вывод SS / SDA / Rx действует либо как вход, когда включен интерфейс SPI, либо как линия последовательных данных, когда включен интерфейс I2C, либо как вход последовательных данных, когда включен интерфейс UART. Этот вывод обычно помечается заключением в квадрат, чтобы его можно было использовать в качестве опорной точки для идентификации других выводов.

Подключение RFID модуля RC522 к Arduino UNO

Теперь, когда мы знаем всё о модуле, мы можем подключить его к нашей плате Arduino!

Для начала подключите вывод VCC на модуле к выводу 3,3V на Arduino, а вывод GND - к земле Arduino. Вывод RST может быть подключен к любому цифровому выводу на Arduino. В нашем случае он подключен к цифровому выводу 5. Вывод IRQ не подключен, так как библиотека Arduino, которую мы собираемся использовать, не поддерживает его.

Теперь у нас остаются выводы, которые используются для связи по SPI. Поскольку модуль RC522 требует передачи больших данных, то наилучшая производительность будет обеспечена при использовании аппаратного модуля SPI в микроконтроллере. Использование выводов аппаратного SPI модуля намного быстрее, чем «дергание битов» в коде при взаимодействии через другой набор выводов.

Обратите внимание, что у плат Arduino выводы SPI различаются. Для плат Arduino, таких как UNO/Nano V3.0, это цифровые выводы 13 (SCK), 12 (MISO), 11 (MOSI) и 10 (SS).

Если у вас Arduino Mega, выводы отличаются! Вы должны использовать цифровые выводы 50 (MISO), 51 (MOSI), 52 (SCK) и 53 (SS). В таблице ниже приведен список выводов для связи по SPI для разных плат Arduino.

Список выводов для связи по SPI для разных плат Arduino
 MOSIMISOSCKCS
Arduino Uno11121310
Arduino Nano11121310
Arduino Mega51505253

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

Рисунок 5 Подключение модуля RFIDсчитывателя RC522 к Arduino UNO
Рисунок 5 – Подключение модуля RFIDсчитывателя RC522 к Arduino UNO

Как только вы всё подключите, вы готовы к работе!

Код Arduino. Считывание RFID метки

Связь с RFID модулем RC522 – это сложная работа, но, к счастью для нас, есть библиотека MFRC522, которая упрощает чтение и запись в RFID меток. Спасибо Мигелю Бальбоа. Сначала скачайте библиотеку, посетив репозиторий GitHub, или просто нажмите на кнопку ниже, чтобы скачать архив:

Чтобы установить библиотеку, откройте Arduino IDE, перейдите в Скетч → Подключить библиотеку → Добавить .ZIP библиотеку и выберите только что загруженный файл rfid-master.zip.

После установки библиотеки откройте меню Файл → Примеры → MFRC522 → DumpInfo.

Рисунок 6 Скетч DumpInfo библиотеки MFRC522
Рисунок 6 – Скетч DumpInfo библиотеки MFRC522

Этот скетч не будет записывать какие-либо данные в метку. Он просто сообщает вам, удалось ли ему прочитать метку, и отображает некоторую информацию о ней. Это может быть очень полезно, прежде чем опробовать любую новую метку!

Перейдите к началу скетча и убедитесь, что RST_PIN инициализирован правильно, в нашем случае мы используем цифровой вывод 5, поэтому измените его на 5!

Рисунок 7 Изменение вывода RST в примере скетча
Рисунок 7 – Изменение вывода RST в примере скетча

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

Рисунок 8 Вывод скетча DumpInfo
Рисунок 8 – Вывод скетча DumpInfo

Он отображает всю полезную информацию о метке, включая уникальный идентификатор (UID) метки, объем памяти и содержание всей памяти в 1 КБ.

Распределение памяти MIFARE Classic 1K

Память метки 1 КБ организована в 16 секторов (от 0 до 15). Каждый сектор дополнительно делится на 4 блока (блоки 0–3). Каждый блок может хранить 16 байтов данных (от 0 до 15).

Это говорит нам, что у нас точно

16 секторов x 4 блока x 16 байтов данных = 1024 байта = 1 КБ памяти

Весь 1 килобайт памяти с секторами, блоками и данными показан ниже.

Рисунок 9 Вывод скетча DumpInfo. Структура памяти
Рисунок 9 – Вывод скетча DumpInfo. Структура памяти
Рисунок 10 Трехмерное представление структуры памяти MIFARE Classic 1K
Рисунок 10 – Трехмерное представление структуры памяти MIFARE Classic 1K

Блок 3 каждого сектора называется Sector Trailer и содержит информацию, называемую Access Bits (биты доступа), для предоставления доступа на чтение и запись к остальным блокам в секторе. Это означает, что в каждом секторе на самом деле для хранения данных доступны только 3 нижних блока (блоки 0, 1 и 2), а это означает, что в 64 байтовом секторе у нас есть только 48 байтов, доступных для нашего собственного использования.

Блок 0 сектора 0 также известен как Manufacturer Block / Manufacturer Data содержит данные производителя микросхемы и уникальный идентификатор (UID). Блок производителя выделен ниже красным цветом.

Рисунок 11 Вывод скетча DumpInfo. Блок производителя
Рисунок 11 – Вывод скетча DumpInfo. Блок производителя

Предупреждение: перезаписывать блок производителя очень рискованно, и это может навсегда заблокировать карту.

Код Arduino. Запись в RFID метку

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

#include <SPI.h>      // включить библиотеку шины SPI
#include <MFRC522.h>  // включить библиотеку считывателя RFID

#define SS_PIN 10  //slave select pin
#define RST_PIN 5  //reset pin

MFRC522 mfrc522(SS_PIN, RST_PIN);  // создание объекта считывателя MFRC522
MFRC522::MIFARE_Key key;           // создать структуру MIFARE_Key с именем 'key', которая будет хранить информацию о карте

// номер блока, который мы запишем и считаем
int block=2;  

byte blockcontent[16] = {"Last-Minute-Engg"};  //массив с 16 байтами для записи в один из 64 блоков 
// Все нули, может использоваться, чтобы удалить блок
//byte blockcontent[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  

// Этот массив используется для считывания блока.
byte readbackblock[18];

void setup() 
{
  // Инициализация последовательной связи с ПК
  Serial.begin(9600);
  // Инициализация шины SPI
  SPI.begin();
  // Инициализация карты MFRC522 (PCD означает "proximity coupling device", "устройство бесконтактной связи")
  mfrc522.PCD_Init();
  Serial.println("Scan a MIFARE Classic card");
  
  // Подготовка ключа безопасности для функций чтения и записи.
  for (byte i = 0; i < 6; i++) 
  {
    key.keyByte[i] = 0xFF;  //keyByte определен в определении структуры MIFARE_Key в .h файле библиотеки
  }
}

void loop()
{  
  // Ищем новые карты
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  
  // Выбрать одну из карт
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  Serial.println("card selected");
         
  // массив blockcontent записывается в блок карты
  writeBlock(block, blockcontent);
  
  // прочитать блок
  readBlock(block, readbackblock);
  // раскомментируйте строку ниже, если хотите увидеть весь 1 килобайт памяти с записанным в нее блоком.
  //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
  
  // вывести в печать контент блока
  Serial.print("read block: ");
  for (int j=0 ; j<16 ; j++)
  {
    Serial.write (readbackblock[j]);
  }
  Serial.println("");
}



// Запись заданного блока
int writeBlock(int blockNumber, byte arrayAddress[]) 
{
  // Убеждаемся, что записываем только в блоки данных. Каждый 4-ый блок - это trailer блок для информации о доступе/безопасности.
  int largestModulo4Number=blockNumber/4*4;
  int trailerBlock=largestModulo4Number+3; // определяем trailer блок для сектора
  if (blockNumber > 2 && (blockNumber+1)%4 == 0)
  {
    Serial.print(blockNumber);
    Serial.println(" is a trailer block:");
    return 2;
  }
  Serial.print(blockNumber);
  Serial.println(" is a data block:");
  
  // аутентификация необходимого блока для доступа
  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) 
  {
    Serial.print("PCD_Authenticate() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 3; // возвращаем "3" как сообщение об ошибке
  }
  
  // запись блока
  status = mfrc522.MIFARE_Write(blockNumber, arrayAddress, 16);
  //status = mfrc522.MIFARE_Write(9, value1Block, 16);
  if (status != MFRC522::STATUS_OK) 
  {
    Serial.print("MIFARE_Write() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 4; // возвращаем "4" как сообщение об ошибке
  }
  Serial.println("block was written");
}



// Чтение заданного блока
int readBlock(int blockNumber, byte arrayAddress[]) 
{
  int largestModulo4Number=blockNumber/4*4;
  int trailerBlock=largestModulo4Number+3; // определяем trailer блок для сектора

  // аутентификация необходимого блока для доступа
  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));

  if (status != MFRC522::STATUS_OK) 
  {
    Serial.print("PCD_Authenticate() failed (read): ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 3; // возвращаем "3" как сообщение об ошибке
  }

  // чтение блока
  // нам необходимо определить переменную с размером буфера чтения,
  // поскольку метод MIFARE_Read ниже требует указатель на переменную, которая содержит размер...
  byte buffersize = 18;
  //&buffersize - это указатель на переменную buffersize; MIFARE_Read требует указатель, вместо самого значения
  status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, &buffersize);
  if (status != MFRC522::STATUS_OK) 
  {
    Serial.print("MIFARE_read() failed: ");
    Serial.println(mfrc522.GetStatusCodeName(status));
    return 4; // возвращаем "4" как сообщение об ошибке
  }
  Serial.println("block was read");
}

Вывод в мониторе последовательного порта будет выглядеть следующим образом.

Рисунок 12 Вывод скетча записи RFID метки с помощью RC522
Рисунок 12 – Вывод скетча записи RFID метки с помощью RC522

Объяснение кода:

Скетч начинается с включения библиотек MFRC522 и SPI, определения выводов Arduino, к которым подключен RC522, и создания объекта считывателя MFRC522.

#include <SPI.h>      // включить библиотеку шины SPI
#include <MFRC522.h>  // включить библиотеку считывателя RFID

#define SS_PIN 10  //slave select pin
#define RST_PIN 5  //reset pin

MFRC522 mfrc522(SS_PIN, RST_PIN);  // создание объекта считывателя MFRC522
MFRC522::MIFARE_Key key;           // создать структуру MIFARE_Key с именем 'key', которая будет хранить информацию о карте

Далее нам нужно определить блок, в котором мы собираемся хранить наши данные. Здесь выбран сектор 0, блок 2. Помните, никогда не выбирайте блок 3 в любом секторе. Запись в блок Sector Trailer может сделать блок непригодным для использования.

// номер блока, который мы запишем и считаем
int block=2;  

Далее мы определяем массив из 16 байтов с именем blockcontent[16], который содержит сообщение, которое мы хотим записать в блок. Вы можете удалить любой блок, написав в него нули.

byte blockcontent[16] = {"Last-Minute-Engg"};  //массив с 16 байтами для записи в один из 64 блоков 
// Все нули, может использоваться, чтобы удалить блок
//byte blockcontent[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  

Далее нам нужно определить массив из 18 байтов с именем readbackblock[18]. Он может быть использован для чтения контента обратно. Подождите ... 18 байт? Разве не должно быть 16 байтов? Ответ - нет. Метод MIFARE_Read в библиотеке MFRC522 для хранения 16 байтов блока требует буфер размером не менее 18 байтов.

// Этот массив используется для считывания блока.
byte readbackblock[18];

В функции setup() мы инициализируем последовательную связь с ПК, библиотеку SPI и объект MFRC522. Нам также необходимо подготовить ключ безопасности для функций чтения и записи. Здесь все шесть байтов ключа установлены в 0xFF. Поскольку карты в наборе новые, и их ключи никогда не менялись, они равны 0xFF. Если бы у нас была карта, которая была запрограммирована кем-то другим, нам нужно было бы знать ключ, чтобы получить к ней доступ. Затем этот ключ необходимо будет хранить в переменной key.

// Инициализация последовательной связи с ПК
Serial.begin(9600);
// Инициализация шины SPI
SPI.begin();
// Инициализация карты MFRC522 (PCD означает "proximity coupling device", "устройство бесконтактной связи")
mfrc522.PCD_Init();
Serial.println("Scan a MIFARE Classic card");
  
// Подготовка ключа безопасности для функций чтения и записи.
for (byte i = 0; i < 6; i++) 
{
  key.keyByte[i] = 0xFF;  //keyByte определен в определении структуры MIFARE_Key в .h файле библиотеки
}

В функции loop() мы сначала сканируем, есть ли поблизости карта, если да, эта карта выбирается для записи и чтения.

// Ищем новые карты
if ( ! mfrc522.PICC_IsNewCardPresent()) 
{
  return;
}
  
// Выбрать одну из карт
if ( ! mfrc522.PICC_ReadCardSerial()) 
{
  return;
}
Serial.println("card selected");

Записать блок теперь очень просто, нам просто нужно вызвать пользовательскую функцию writeBlock(), которая принимает два параметра: номер блока, в который мы хотим записать данные, и сами данные.

// массив blockcontent записывается в блок карты
writeBlock(block, blockcontent);

Чтобы проверить, была ли операция записи успешной, нам нужно прочитать содержимое блока обратно. Это можно сделать с помощью пользовательской функции readBlock(), которая снова принимает два параметра: один - номер блока, а другой - массив для хранения содержимого блока. Вы можете использовать функцию PICC_DumpToSerial(), если хотите увидеть весь 1 килобайт памяти с записанным в нее блоком.

// прочитать блок
readBlock(block, readbackblock);
// раскомментируйте строку ниже, если хотите увидеть весь 1 килобайт памяти с записанным в нее блоком.
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

Наконец, мы печатаем содержимое массива readbackblock с помощью цикла for и отображаем его в мониторе последовательного порта.

// вывести в печать контент блока
Serial.print("read block: ");
for (int j=0 ; j<16 ; j++)
{
  Serial.write (readbackblock[j]);
}
Serial.println("");

Проект на Arduino

RFID система контроля доступа для дверного замка

Давайте создадим небольшой проект на Arduino, чтобы продемонстрировать, как простой модуль RFID считывателя RC522 можно использовать для создания RFID системы контроля доступа для дверного замка. Наша программа будет сканировать уникальный идентификатор каждой RFID метки, когда она достаточно близко, чтобы запитываться от считывателя RC522. Если UID метки соответствует предопределенному значению (MasterTag), которое хранится в памяти Arduino, доступ будет предоставлен. И если сканируем любую неизвестную метку, доступ будет запрещен. Круто! Так ведь?

Так выглядит результат.

Рисунок 13 Демонстрация работы RFID системы контроля доступа для дверного замка
Рисунок 13 – Демонстрация работы RFID системы контроля доступа для дверного замка

Конечно, этот проект можно привязать к открытию дверей, включению реле, включению светодиода или к чему-то еще.

Если вы не знакомы с символьными LCD дисплеями размером 16×2, то взгляните на эту статью.

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

Рисунок 14 RFID система контроля доступа для дверного замка. Подключение RFID считывателя RC522 и LCD дисплея к Arduino
Рисунок 14 – RFID система контроля доступа для дверного замка. Подключение RFID считывателя RC522 и LCD дисплея к Arduino

Всё! Теперь попробуйте приведенный ниже скетч в работе.

#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>

#define RST_PIN 9
#define SS_PIN 10

byte readCard[4];
String MasterTag = "20C3935E";	// ЗАМЕНИТЕ этот ID метки на ID своей метки!!!
String tagID = "";

// Создание объектов
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //Параметры: (rs, enable, d4, d5, d6, d7) 

void setup() 
{
  // Инициализация
  SPI.begin();        // SPI шина
  mfrc522.PCD_Init(); // MFRC522
  lcd.begin(16, 2);   // LCD дисплей

  lcd.clear();
  lcd.print(" Access Control ");
  lcd.setCursor(0, 1);
  lcd.print("Scan Your Card>>");
}

void loop() 
{
  
  // Ждем, пока не будет доступна новая метка
  while (getID()) 
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    
    if (tagID == MasterTag) 
    {
      lcd.print(" Access Granted!");
      // Вы можете написать здесь любой код, например, открывание дверей,
      // включение реле, зажигание светодиода или что-то другое, что взбредет вам в голову.
    }
    else
    {
      lcd.print(" Access Denied!");
    }
    
    lcd.setCursor(0, 1);
    lcd.print(" ID : ");
    lcd.print(tagID);
      
    delay(2000);

    lcd.clear();
    lcd.print(" Access Control ");
    lcd.setCursor(0, 1);
    lcd.print("Scan Your Card>>");
  }
}

// Чтение новой метки, если она доступна
boolean getID() 
{
  // Получение готовности для чтения PICC карт
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  { // Продолжать, если к RFID считывателю поднесена новая карта
    return false;
  }
  
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  { // Когда карта поднесена, считать серийный номер и продолжить
    return false;
  }
  
  tagID = "";
  for ( uint8_t i = 0; i < 4; i++) 
  { // Карты MIFARE, кторые мы используем, содержат 4-байтовый UID
    //readCard[i] = mfrc522.uid.uidByte[i];
    tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Сложить эти 4 байта в одну переменную String
  }
  tagID.toUpperCase();
  mfrc522.PICC_HaltA(); // остановить чтение
  return true;
}

Программа довольно проста. Сначала мы включаем необходимые библиотеки, определяем выводы Arduino, создаем объекты LCD и MFRC522 и определяем главную метку.

#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>

#define RST_PIN 9
#define SS_PIN 10

byte readCard[4];
String MasterTag = "20C3935E";	// ЗАМЕНИТЕ этот ID метки на ID своей метки!!!
String tagID = "";

// Создание объектов
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //Параметры: (rs, enable, d4, d5, d6, d7) 

В функции setup() мы инициализируем интерфейс SPI, объект MFRC522 и LCD дисплей. После этого мы печатаем на LCD дисплее приветственное сообщение.

void setup() 
{
  // Инициализация
  SPI.begin();        // SPI шина
  mfrc522.PCD_Init(); // MFRC522
  lcd.begin(16, 2);   // LCD дисплей

  lcd.clear();
  lcd.print(" Access Control ");
  lcd.setCursor(0, 1);
  lcd.print("Scan Your Card>>");
}

В функции loop() мы ждем, пока не будет отсканирована новая метка. Как только это будет сделано, мы сравним неизвестную метку с мастер-меткой, определенной в функции setup(). Всё! Если ID метки совпадает с ID мастера, доступ предоставляется, в противном случае в доступе будет отказано.

void loop() 
{
  
  // Ждем, пока не будет доступна новая метка
  while (getID()) 
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    
    if (tagID == MasterTag) 
    {
      lcd.print(" Access Granted!");
      // Вы можете написать здесь любой код, например, открывание дверей,
      // включение реле, зажигание светодиода или что-то другое, что взбредет вам в голову.
    }
    else
    {
      lcd.print(" Access Denied!");
    }
    
    lcd.setCursor(0, 1);
    lcd.print(" ID : ");
    lcd.print(tagID);
      
    delay(2000);

    lcd.clear();
    lcd.print(" Access Control ");
    lcd.setCursor(0, 1);
    lcd.print("Scan Your Card>>");
  }
}

Ключевым моментом в проекте является пользовательская функция getID(). Как только она просканирует новую карту, внутри цикла for она преобразует 4 байта UID в строки и объединяет их для создания одной строки.

boolean getID() 
{
  // Получение готовности для чтения PICC карт
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  { // Продолжать, если к RFID считывателю поднесена новая карта
    return false;
  }
  
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  { // Когда карта поднесена, считать серийный номер и продолжить
    return false;
  }
  
  tagID = "";
  for ( uint8_t i = 0; i < 4; i++) 
  { // Карты MIFARE, кторые мы используем, содержат 4-байтовый UID
    //readCard[i] = mfrc522.uid.uidByte[i];
    tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Сложить эти 4 байта в одну переменную String
  }
  tagID.toUpperCase();
  mfrc522.PICC_HaltA(); // остановить чтение
  return true;
}

Теги

ArduinoRFIDДатчикКонтроль доступа

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.


  • 2022-12-20radioprog

    Здравствуйте!
    А какая именно ошибка?

  • 2022-12-20Андрей

    Здравствуйте!
    Arduino: Uno, IDE 1.8.20 дает ошибку компиляции при подключении MFRC522. Подскажите, пожалуйста, в чем может быть проблема?

  • 2022-11-26Сергей Горячев

    Здравствуйте! А как на метку записать текущее время?