Ардуино и RFID

RFIDRadio Frequency IDentification или радиочастотная идентификация — способ автоматической идентификации объектов, в котором при помощи радиосигналов считываются или записываются данные, хранящиеся в так называемых транспондерах, или RFID-метках.

Любая RFID-система состоит из считывающего устройства (ридера) и RFID-метки.

Большинство RFID-меток состоит из двух частей. Первая — интегральная схема (ИС) для хранения и обработки информации, модулирования и демодулирования радиочастотного (RF) сигнала и некоторых других функций. Вторая — антенна для приёма и передачи сигнала.

Идентификация объектов производится по уникальному цифровому коду, который считывается из памяти RFID-метки.

По дальности считывания RFID-системы можно подразделить на системы:

  • ближней идентификации (считывание производится на расстоянии до 20 см);
  • идентификации средней дальности (от 20 см до 5 м);
  • дальней идентификации (от 5 м до 300 м).

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

  • метки диапазона LF (125—134 кГц);
  • метки диапазона HF (13,56 МГц);
  • метки диапазона UHF (860—960 МГц).

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

В этом уроке мы научимся подключать RFID-ридер RC522 к Ардуино Уно и считывать данные с RFID-меток. Модуль RC522 имеет дальность обнаружения до 6 см и предназначен для чтения и записи RFID меток с частотой 13.56 МГц.

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

RC522 работает с метками диапазона HF по протоколу MIFARE.

Модуль RC522 имеет SPI-интерфейс. В SPI используются четыре цифровых сигнала:

  • MOSI — выход ведущего, вход ведомого (англ. Master Out Slave In). Служит для передачи данных от ведущего устройства ведомому.
  • MISO — вход ведущего, выход ведомого (англ. Master In Slave Out). Служит для передачи данных от ведомого устройства ведущему.
  • SCLK или SCK — последовательный тактовый сигнал (англ. Serial Clock). Служит для передачи тактового сигнала для ведомых устройств.
  • CS или SS — выбор микросхемы, выбор ведомого (англ. Chip Select, Slave Select).

Также, стоит отметить, что при подключении к Ардуино используется питание на 3.3 В.

RC522GNDVCCRSTSDA (SS)MOSIMISOSCK
Arduino UnoGND3.3V910111213

Программа

Для работы с модулем RC522 можно использовать либо стандартную библиотеку, либо библиотеку MFRC522, написанную специально под данный модуль.

Давайте попробуем прочитать информацию с карты. Воспользуемся для этого скетчем DumpInfo из библиотеки RC522.

#include <SPI.h>
#include <MFRC522.h>
// Константы подключения контактов RST и SS
#define RST_PIN		9		 
#define SS_PIN		10		

MFRC522 mfrc522(SS_PIN, RST_PIN);	

void setup() {
	Serial.begin(9600);		// Инициализация монитора последовательного порта
	while (!Serial);		// Ожидание включения монитора последовательного порта
	SPI.begin();			// Инициализация SPI шины
	mfrc522.PCD_Init();		// Инициализация RC522
	ShowReaderDetails();	        // Вывод данных о модуле RC522
	Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
}

void loop() {
	// Поиск новой метки
	if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Выбор метки
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}
        // Вывод данных с карты
	mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

void ShowReaderDetails() {
	// Получение номера программной версии модуля RC522 
	byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
	Serial.print(F("MFRC522 Software Version: 0x"));
	Serial.print(v, HEX);
	if (v == 0x91)
		Serial.print(F(" = v1.0"));
	else if (v == 0x92)
		Serial.print(F(" = v2.0"));
	else
		Serial.print(F(" (unknown)"));
	Serial.println("");
	// Когда получено 0x00 или 0xFF, передача данных нарушена
	if ((v == 0x00) || (v == 0xFF)) {
		Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
	}
}

Заливаем данный скетч из библиотеки на Ардуино, запускаем монитор последовательного порта и подносим к модулю RFID-метку (например, карту). В результате мы должны увидеть на мониторе следующее:

Нас интересует Card UID — уникальный идентификационный номер метки. Напишем свою простейшую программу, используя стандартную библиотеку, которая определяет — является карта пропуском или нет. Возьмём две или более метки. ID одной из них будет кодом доступа, на другие метки должно выводиться сообщение «Wrong ID!» и гореть красный сигнал от светодиода.

#include <SPI.h>
#include <RFID.h>

// Константы подключения контактов RST и SS 
#define SS_PIN 10
#define RST_PIN 9
 
RFID rfid(SS_PIN, RST_PIN); 
 
int serNum[5];

// Подключение к контактам rgb-светодиода
const byte rPin = 6;
const byte gPin = 5;
const byte bPin = 3;
 
void setup()
{ 
    Serial.begin(9600);            // Инициализация монитора
    SPI.begin();                   // Инициализация SPI шины
    rfid.init();                   // Инициализация RC522

    pinMode( rPin, OUTPUT );
    pinMode( gPin, OUTPUT );
    pinMode( bPin, OUTPUT );
}
 
void loop()
{
    // Если обнаружена метка
    if (rfid.isCard()) {
        // Считываем данные
        if (rfid.readCardSerial()) {
          // Проверка данных
          if ((rfid.serNum[0] == 0xE1)&&(rfid.serNum[1] == 0x54)&&(rfid.serNum[2] == 0x5A)&&(rfid.serNum[3] == 0x2D)&&(rfid.serNum[4] == 0xC2))
          {
            // Если ID карты совпал, вывести надпись "Access granted!", ID карты и подать зелёный сигнал на светодиод
            Serial.println("Access granted!");
            Serial.println("Card number:");
            Serial.print(rfid.serNum[0],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[1],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[2],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[3],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[4],HEX);
            Serial.println(" ");

            digitalWrite( rPin, LOW );
            digitalWrite( bPin, LOW );
            digitalWrite( gPin, HIGH );
          }
          else
          {
            // Если ID карты не верен, вывести "Wrong ID!", ID карты и подать красный сигнал на светодиод
            Serial.println("Wrong ID!");
            Serial.println("Card number:");
            Serial.print(rfid.serNum[0],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[1],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[2],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[3],HEX);
            Serial.print(" ");
            Serial.print(rfid.serNum[4],HEX);
            Serial.println(" "); 

            digitalWrite( bPin, LOW );
            digitalWrite( gPin, LOW );
            digitalWrite( rPin, HIGH );
          }

            delay(1000);
            digitalWrite( bPin, LOW );
            digitalWrite( gPin, LOW );
            digitalWrite( rPin, LOW );
        }       
    }
    rfid.halt();
}

Результат работы нашей программы:

1+

Изменено:

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.