Считыватель RFID ключей RC522
1
2
3
4
5
6
7
8
SDA
SCK
MOSI
MISO
IRQ
GND
RST
3.3V
- Разрешение линии данных (SPI)
- Тактирование линии данных (SPI)
- Данные от Arduino к RC522 (SPI)
- Данные от RC522 к Arduino (SPI)
- Прерывание
- Общий вывод (GND)
- Сброс (Reset)
- Питание (+3.3V)
  • Обратите внимание при подключении, что считыватель работает от напряжения 3.3 В. Включать стоит в соответствующий пин на плате Arduino.
  • Считыватель может общаться с Arduino по трем самым распространенным для микроконтроллеров последовательным интерфейсам SPI, I2C, UART. В нашем случае выберем SPI. Для подключения требуется четыре линии.
  • В комплекте со считывателем идет два ключа - в форме карты и брелка. Каждый ключ имеет перепрограммируемый User ID, а так же Key для записи информации о пользователе. В ключе может храниться фамилия, имя, адрес, должность и другая личная информация (1 Кбайт данных).
  • На схеме показан простой пример использования считывателя. Если поднести ключ к считывателю, Arduino сравнит UID ключа с хранящимися в базе. Если ключ есть в базе, будет выведена соответствующая надпись и загорится зеленый светодиод. В противном случае - красный. Если поднести ключ с зажатой кнопкой произойдет запоминание в базу UID ключа.
Типовая схема подключения
Методы библиотеки MFRC522
Для работы со считывателем необходимо установить библиотеку <MFRC522.h> из базы библиотек.
.PCD_Init(); - инициализация работы со считывателем
.PCD_Reset(); - Сброс считывателя
.PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid); - Авторизация перед чтением или записью данных.
.MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize); - чтение блока данных
.MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize); - Запись блока данных
.PICC_DumpToSerial(Uid *uid); - вывод в последовательный порт всего содержимого карты
.PICC_IsNewCardPresent(); - карта поднесена к считывателю
.PICC_ReadCardSerial(); - считывание прошло успешно
Больше информации ищите в примерах и документации к библиотеке.
Пример кода
#include <SPI.h>
#include <MFRC522.h>

// контакты
#define SS_PIN 10
#define RST_PIN 9
#define PROG_UID 2
#define VALID_UID 8
#define INVALID_UID 4

byte valid_uids[5][10] = {};        //Массив с валидными UID
int count_saved_uid=0;              //Количество валидных UID
MFRC522 mfrc522(SS_PIN, RST_PIN);  // Создание экземпляра MFRC522

void setup() {
  Serial.begin(9600);               //Инициализация Serial
  SPI.begin();                      //Инициализация SPI

  mfrc522.PCD_Init();               // инициализация MFRC522
  mfrc522.PCD_DumpVersionToSerial();// выводим номер версии прошивки ридера
}

void loop() {
  // Ожидание карты
  if ( ! mfrc522.PICC_IsNewCardPresent())
    return;

  // чтение успешно
  if ( !mfrc522.PICC_ReadCardSerial())
    return;

  // Если нажата кнопка, запоминаем IUD прислоненной карты
  if(digitalRead(PROG_UID)){
    save_uid(mfrc522.uid.uidByte, mfrc522.uid.size);
  }

  // Если UID прислонённой карты есть в базе, выводим сообщение и зажгаем зеленый светодиод
  if(check_uid(mfrc522.uid.uidByte, mfrc522.uid.size)){
     Serial.print("UID: ");
     dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
     Serial.println(" is valid!");
     digitalWrite(VALID_UID,HIGH);
     digitalWrite(INVALID_UID,LOW);
  }
  //Иначе выводим другое сообщение и зажигаем другой светодиод
  else{
    Serial.print("UID: ");
     dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
     Serial.println(" is invalid!");
     digitalWrite(VALID_UID,LOW);
     digitalWrite(INVALID_UID,HIGH);
  }
  
  delay(1000);
}

// Вывод UID
void dump_byte_array(byte *buffer, byte bufferSize) {
    for (byte i = 0; i < bufferSize; i++) {
        Serial.print(buffer[i] < 0x10 ? " 0" : " ");
        Serial.print(buffer[i], HEX);
    }
}
//Функция сохранения UID в базе
void save_uid(byte *buffer, byte bufferSize){
    Serial.print("saving UID: ");
    dump_byte_array(buffer, bufferSize);
    Serial.print("\n");
    for (byte i = 0; i < bufferSize; i++) {
        valid_uids[count_saved_uid][i] = buffer[i];
    }
    count_saved_uid++;
    Serial.print("saved ");
    Serial.print(count_saved_uid);
    Serial.println(" UIDs");
}
//Функция поиска UID в базе
bool check_uid(byte *buffer, byte bufferSize){
  byte c_err=0;
  
  for(byte k = 0; k<count_saved_uid;k++){
    for (byte i = 0; i < bufferSize; i++) {
        if(valid_uids[k][i] != buffer[i]) c_err++;
    }
    if (c_err==0)
      return true;
    else
      c_err=0;
  }
  return false;
}