ESP8266 NodeMCU с RFID-считывателем/записывателем MFRC522 (Arduino IDE)

Узнайте, как подключить модуль RFID-считывателя MFRC522 к плате ESP8266 NodeMCU. Вы научитесь получать необработанные данные RFID, считывать UID RFID-карты и записывать персональные данные на RFID-карты. Мы будем использовать библиотеку Arduino_MFRC522v2, а программирование ESP8266 будет выполняться с помощью Arduino IDE.

ESP8266 NodeMCU с RFID-считывателем/записывателем MFRC522 (Arduino IDE)

У нас есть аналогичное руководство для ESP32 с RFID-считывателем/записывателем MFRC522 (Arduino IDE).

В этом руководстве мы рассмотрим:

RFID-считыватель/записыватель MFRC522

В этом руководстве мы будем использовать RFID-считыватель/записыватель MFRC522, и именно его мы рекомендуем приобрести для работы с ESP8266.

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

Система RFID состоит из меток и считывателя:

  • Метки (бесконтактные интегральные карты – PICC) прикрепляются к объекту, который необходимо идентифицировать. В данном примере у нас есть брелок и электромагнитная карта, которые поставляются вместе с модулем RFID-считывателя/записывателя MFRC522. Каждая метка имеет уникальный идентификатор (UID).

RFID MFRC522 карта, метки, брелок
  • Считыватель/записыватель (устройство бесконтактной связи – PCD) – это двусторонний радиопередатчик-приёмник, который отправляет сигнал на метку и считывает её ответ.

Модуль RFID-считывателя/записывателя MFRC522

RFID-считыватель MFRC522 работает при напряжении 3,3 В и поддерживает протоколы связи SPI и I2C. Библиотека, которую мы будем использовать для управления RFID-считывателем, поддерживает оба протокола, но мы будем использовать SPI.

Необходимые компоненты

Вот список необходимых компонентов для этого проекта:

Вы можете использовать ссылки выше или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!

Чтобы узнать больше о RFID-считывателе с Arduino, прочитайте: Контроль доступа с использованием RFID-считывателя MFRC522 и Arduino.

Установка библиотеки Arduino_MFRC522v2

Для этого руководства мы будем использовать библиотеку MFRC522v2.h для управления RFID-считывателем. В Arduino IDE перейдите в Sketch > Include Library > Manage Libraries или нажмите на значок Library Manager на левой боковой панели.

Найдите MFRC522v2 и установите библиотеку от GithubCommunity.

Установка библиотеки RFID MFRC522v2 в Arduino IDE

Распиновка и подключение RFID-считывателя/записывателя MFRC522 к ESP8266 NodeMCU

Мы подключим RFID-считыватель MFRC522 через стандартные SPI-пины ESP8266 NodeMCU. Используйте следующую таблицу.

Схема подключения модуля RFID MFRC522 к плате ESP8266 NodeMCU

RFID-считыватель MFRC522

ESP8266

Описание

SDA

GPIO 15 (D8)

Вход сигнала SPI, линия данных I2C или вход данных UART

SCK

GPIO 14 (D5)

Тактовый сигнал SPI

MOSI

GPIO 13 (D7)

Вход данных SPI

MISO

GPIO 12 (D6)

Выход данных SPI (master-in-slave-out), тактовый сигнал I2C или последовательный выход UART

IRQ

Не подключать

Пин прерывания; сигнализирует микроконтроллеру о наличии RFID-метки поблизости

GND

GND

RST

GPIO 0 (D3)

Низкий сигнал переводит модуль в режим пониженного энергопотребления; высокий сигнал выполняет сброс модуля

3.3V

3.3V

Питание (2,5–3,3 В)

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

Чтение необработанных данных RFID-карты – код

Следующий пример считывает необработанные данные с RFID-метки. С помощью этого примера вы лучше поймёте, как данные хранятся на метках MIFARE 1K.

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-mfrc522-rfid-reader-arduino/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
//#include <MFRC522DriverI2C.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522Debug.h>

// Learn more about using SPI/I2C or check the pin assigment for your board: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
MFRC522DriverPinSimple ss_pin(15);

MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
//MFRC522DriverI2C driver{};     // Create I2C driver
MFRC522 mfrc522{driver};         // Create MFRC522 instance

void setup() {
  Serial.begin(115200);  // Initialize serial communication
  while (!Serial);       // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).

  mfrc522.PCD_Init();    // Init MFRC522 board.
  MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial);    // Show details of PCD - MFRC522 Card Reader details.
  Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}

void loop() {
  // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
  if (!mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards.
  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Dump debug info about the card; PICC_HaltA() is automatically called.
  MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));

  delay(2000);
}

Посмотреть исходный код

После сборки схемы загрузите приведённый выше код на вашу плату.

После загрузки откройте Serial Monitor на скорости 115200 бод. Поднесите метку к считывателю и посмотрите, как информация о метке отображается.

Модуль RFID MFRC522 с ESP8266 NodeMCU - считывание карты и брелока

На экране отображается UID карты, тип метки и блоки памяти. Метка имеет тип MIFARE с 1 КБ памяти.

Библиотека RFID MFRC522v2 - чтение секторов, блоков, UID, информации о карте в Arduino IDE

Вот несколько ключевых аспектов, которые необходимо учитывать при работе с хранением данных на метке MIFARE 1K.

Структура памяти

Память организована в 16 секторов (от 0 до 15), и каждый сектор разделён на 4 блока (от 0 до 3), что даёт в общей сложности 64 блока. Каждый блок может хранить 16 байт данных (от 0 до 15).

Блок производителя

Сектор 0, блок 0 хранит UID (первые 4 байта), контрольный байт CRC и данные производителя. Этот блок доступен только для чтения и не может быть изменён (за исключением карт с изменяемым UID). Как видно из результатов в Serial Monitor, UID нашей метки – 82 72 9F 0B.

Хранение данных и трейлер сектора

Первые три блока каждого сектора можно использовать для хранения данных. Последний блок каждого сектора является трейлером сектора. Этот трейлер сектора хранит 2 ключа или пароля и управляет доступом к остальным блокам в секторе. Например, блок номер 7 управляет блоками 4, 5 и 6. Не следует записывать данные в эти блоки, иначе вы, вероятно, заблокируете свою карту и она станет непригодной для использования.

Подводя итог, чистая ёмкость хранения карт Mifare 1K составляет:

(16 секторов/карта x 3 блока данных/сектор x 16 байт/блок) - 16 байт (первый блок) = 752 байт/карта

Всего 16 секторов по 4 блока (64 блока). Каждый блок содержит 16 байт, что даёт 1024 байта (1 КБ). Однако 16 блоков (по одному в каждом секторе) являются трейлерами секторов, которые хранят ключи доступа и разрешения, а не пользовательские данные. Это оставляет 48 блоков, доступных для пользовательских данных. Вычитая 16 байт за блок производителя, доступный только для чтения (сектор 0, блок 0), эффективная пользовательская ёмкость составляет 752 байта.

Чтение UID RFID-карты – код

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

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-mfrc522-rfid-reader-arduino/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
//#include <MFRC522DriverI2C.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522Debug.h>

// Learn more about using SPI/I2C or check the pin assigment for your board: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
MFRC522DriverPinSimple ss_pin(15);

MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
//MFRC522DriverI2C driver{};     // Create I2C driver
MFRC522 mfrc522{driver};         // Create MFRC522 instance

void setup() {
  Serial.begin(115200);  // Initialize serial communication
  while (!Serial);       // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).

  mfrc522.PCD_Init();    // Init MFRC522 board.
  MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial);    // Show details of PCD - MFRC522 Card Reader details.
     Serial.println(F("Scan PICC to see UID"));
}

void loop() {
     // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
     if (!mfrc522.PICC_IsNewCardPresent()) {
             return;
     }

     // Select one of the cards.
     if (!mfrc522.PICC_ReadCardSerial()) {
             return;
     }

  Serial.print("Card UID: ");
  MFRC522Debug::PrintUID(Serial, (mfrc522.uid));
  Serial.println();

  // Save the UID on a String variable
  String uidString = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    if (mfrc522.uid.uidByte[i] < 0x10) {
      uidString += "0";
    }
    uidString += String(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.println(uidString);
}

Посмотреть исходный код

Этот код довольно прост для понимания. Сначала вы инициализируете считыватель в setup().

mfrc522.PCD_Init();    // Init MFRC522 board.
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial);      // Show details of PCD - MFRC522 Card Reader details.
Serial.println(F("Scan PICC to see UID"));

Затем в loop() проверяется, есть ли карта в зоне действия.

// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if (!mfrc522.PICC_IsNewCardPresent()) {
  return;
}

Если карта обнаружена, выполняется её чтение.

// Select one of the cards.
if (!mfrc522.PICC_ReadCardSerial()) {
  return;
}

Наконец, выводится UID и сохраняется в переменную.

  Serial.print("Card UID: ");
  MFRC522Debug::PrintUID(Serial, (mfrc522.uid));
  Serial.println();

  // Save the UID on a String variable
  String uidString = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    if (mfrc522.uid.uidByte[i] < 0x10) {
      uidString += "0";
    }
    uidString += String(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.println(uidString);
}

Загрузите код на вашу плату. Откройте Serial Monitor на скорости 115200 бод.

Модуль RFID MFRC522 с ESP8266 NodeMCU - чтение карты

Подносите разные метки к считывателю и наблюдайте, как их уникальные UID выводятся на экран.

Чтение UID RFID-карты MFRC522 - демонстрация примера в Arduino IDE

Запись/чтение персональных данных на RFID-карту и с неё – код

В этом примере мы покажем, как записать пользовательские данные в определённые блоки. Затем мы также покажем, как считать данные из этих же блоков.

/*
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp8266-nodemcu-mfrc522-rfid-reader-arduino/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
//#include <MFRC522DriverI2C.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522Debug.h>

// Learn more about using SPI/I2C or check the pin assigment for your board: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
MFRC522DriverPinSimple ss_pin(15);

MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
//MFRC522DriverI2C driver{};     // Create I2C driver
MFRC522 mfrc522{driver};         // Create MFRC522 instance

MFRC522::MIFARE_Key key;

byte blockAddress = 2;
byte newBlockData[17] = {"Rui Santos - RNT"};
//byte newBlockData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};   // CLEAR DATA
byte bufferblocksize = 18;
byte blockDataRead[18];

void setup() {
  Serial.begin(115200);  // Initialize serial communication
  while (!Serial);       // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).

  mfrc522.PCD_Init();    // Init MFRC522 board.
  Serial.println(F("Warning: this example overwrites a block in your card, use with care!"));

  // Prepare key - all keys are set to FFFFFFFFFFFF at chip delivery from the factory.
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
}

void loop() {
  // Check if a new card is present
  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    delay(500);
    return;
  }

  // Display card UID
  Serial.print("----------------\nCard UID: ");
  MFRC522Debug::PrintUID(Serial, (mfrc522.uid));
  Serial.println();

  // Authenticate the specified block using KEY_A = 0x60
  if (mfrc522.PCD_Authenticate(0x60, blockAddress, &key, &(mfrc522.uid)) != 0) {
    Serial.println("Authentication failed.");
    return;
  }

  // Write data to the specified block
  if (mfrc522.MIFARE_Write(blockAddress, newBlockData, 16) != 0) {
    Serial.println("Write failed.");
  } else {
    Serial.print("Data written successfully in block: ");
    Serial.println(blockAddress);
  }

  // Authenticate the specified block using KEY_A = 0x60
  if (mfrc522.PCD_Authenticate(0x60, blockAddress, &key, &(mfrc522.uid)) != 0) {
    Serial.println("Authentication failed.");
    return;
  }

  // Read data from the specified block
  if (mfrc522.MIFARE_Read(blockAddress, blockDataRead, &bufferblocksize) != 0) {
    Serial.println("Read failed.");
  } else {
    Serial.println("Read successfully!");
    Serial.print("Data in block ");
    Serial.print(blockAddress);
    Serial.print(": ");
    for (byte i = 0; i < 16; i++) {
      Serial.print((char)blockDataRead[i]);  // Print as character
    }
    Serial.println();
  }

  // Halt communication with the card
  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();

  delay(2000);  // Delay for readability
}

Посмотреть исходный код

Как работает код?

Мы начинаем с подключения необходимых библиотек для настройки RFID-считывателя.

#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
//#include <MFRC522DriverI2C.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522Debug.h>

Далее определяется пин CS (Chip Select) как пин 15, который будет использоваться для SPI-связи со считывателем.

// Learn more about using SPI/I2C or check the pin assigment for your board: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
MFRC522DriverPinSimple ss_pin(15);

MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
//MFRC522DriverI2C driver{};     // Create I2C driver
MFRC522 mfrc522{driver};         // Create MFRC522 instance

MFRC522::MIFARE_Key key;

Затем мы определяем переменную blockAddress. Она указывает блок на RFID-метке, в который будут записываться или из которого будут считываться данные. В этом примере blockAddress установлен в 2, что означает, что код будет взаимодействовать с блоком 2 памяти карты. Вы можете изменить это значение, если хотите записывать в другой блок.

byte blockAddress = 2;

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

Далее, newBlockData[17] содержит данные, которые вы хотите записать на карту. Сейчас установлено значение Rui Santos – RNT, но вы можете его изменить. Убедитесь, что длина не превышает 16 байт.

byte newBlockData[17] = {"Rui Santos - RNT"};

Если вы хотите очистить данные блока, можно передать следующий массив байтов:

byte newBlockData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

В setup() инициализируется модуль MFRC522.

mfrc522.PCD_Init();    // Init MFRC522 board.

Также устанавливается ключ по умолчанию для RFID-карты в следующих строках. По умолчанию все байты равны 0xFF – это заводской ключ. Этот ключ позволяет получить доступ к блокам данных карты.

// Prepare key - all keys are set to FFFFFFFFFFFF at chip delivery from the factory.
for (byte i = 0; i < 6; i++) {
  key.keyByte[i] = 0xFF;
}

В loop() проверяется, обнаружена ли новая RFID-карта. Если карта присутствует, считывается и отображается UID карты.

if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
  delay(500);
  return;
}

// Display card UID
Serial.print("----------------\nCard UID: ");
MFRC522Debug::PrintUID(Serial, (mfrc522.uid));
Serial.println();

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

// Authenticate the specified block using KEY_A = 0x60
if (mfrc522.PCD_Authenticate(0x60, blockAddress, &key, &(mfrc522.uid)) != 0) {
  Serial.println("Authentication failed.");
  return;
}

Примечание: 0x60 – это команда, которая указывает на использование KEY_A для аутентификации. KEY_A – это один из двух ключей (KEY_A и KEY_B), доступных на RFID-картах, каждый из которых предоставляет различные права доступа. Использование 0x60 означает, что код пытается аутентифицироваться с помощью KEY_A, который по умолчанию равен 0xFF 0xFF 0xFF 0xFF 0xFF на RFID-картах MIFARE.

Если аутентификация прошла успешно, данные (сохранённые в newBlockData) записываются в этот блок.

// Write data to the specified block
if (mfrc522.MIFARE_Write(blockAddress, newBlockData, 16) != 0) {
  Serial.println("Write failed.");
} else {
  Serial.print("Data written successfully in block: ");
  Serial.println(blockAddress);
}

После записи код считывает данные обратно из блока и выводит их в Serial Monitor.

// Read data from the specified block
if (mfrc522.MIFARE_Read(blockAddress, blockDataRead, &bufferblocksize) != 0) {
  Serial.println("Read failed.");
} else {
  Serial.println("Read successfully!");
  Serial.print("Data in block ");
  Serial.print(blockAddress);
  Serial.print(": ");
  for (byte i = 0; i < 16; i++) {
    Serial.print((char)blockDataRead[i]);  // Print as character
  }
  Serial.println();
}

Наконец, код завершает связь с картой и останавливает шифрование.

// Halt communication with the card
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();

Тестирование примера

В этом примере мы сохранили следующие персональные данные «Rui Santos – RNT» в блок номер 2 на двух разных RFID-картах.

Библиотека RFID MFRC522v2 - чтение персональных данных из секторов и блоков - демонстрация примера в Arduino IDE

Другие полезные примеры

В библиотеке Arduino_MFRC522v2 есть несколько примеров, которые могут быть полезны. В подменю Hack вы найдёте примеры ChangeUID и FixBrickedUID.

Важно: большинство RFID-карт не позволяют изменять UID. Этот код работает только на определённых картах MIFARE Classic, которые имеют записываемый блок UID. У большинства RFID-карт UID установлен как доступный только для чтения, поэтому если вы попытаетесь изменить UID, это не сработает.

Примеры библиотеки RFID MFRC522v2 в Arduino IDE

Заключение

В этом руководстве вы узнали, как подключить модуль RFID-считывателя/записывателя MFRC522 к ESP8266. Мы рассмотрели, как работает хранение данных на картах Mifare 1K и как выгрузить информацию карт. Мы также научились получать UID карты, записывать новые данные в определённый блок и считывать данные из определённого блока.

Надеемся, что это руководство по работе ESP8266 с RFID-считывателем/записывателем MFRC522 было для вас полезным. У нас есть аналогичное руководство для платы Arduino:

Если вы хотите узнать больше об ESP8266 и найти вдохновение для новых проектов, обязательно ознакомьтесь с нашими ресурсами:

Спасибо за чтение.