Как использовать RFID-RC522 с Arduino?

Я работаю над проектом для своего местного Makerspace, у нас ограниченный бюджет, поэтому я надеялся использовать дешевые считыватели RFID/NFC RFID-RC522 на eBay. Я получил пару плат на базе SPI, они работают, однако примеры кода для них ограничены.

Я нашел несколько разных библиотек и остановился на этой: https://github.com/ljos/MFRC522

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

Код работает, но карты Mifare должны иметь 4, 7 или 10-байтовые UID, а пример/библиотека возвращает 5-байтовый серийный номер.

Документации нет, а техническая таблица NXP непонятна... Кроме того, кажется, что она работает с большинство карт, но не работает с картами Mastercard PayWave, соответствующими стандарту ISO 14443. Более дорогой считыватель RDM880, основанный на MFRC500, работает нормально и имеет хорошую библиотеку, но его стоимость делает реализацию невозможной.

Итак, может ли кто-нибудь помочь мне получить это устройство на базе NXP MFRC522, считывающее UID со всех карт ISO 14443?

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

#define RFID_SS  10
#define RFID_RST 5

MFRC522 rfid( RFID_SS, RFID_RST );

void setup() {
  SPI.begin();
  Serial.begin(115200);
  rfid.begin();
}

void loop() {
  byte data[MAX_LEN];
  byte uid[5];

  if ( rfid.requestTag( MF1_REQIDL, data ) == MI_OK ) {
    if ( rfid.antiCollision( data ) == MI_OK ) {
      memcpy( uid, data, 5 );
      for ( int i = 0; i < 5; i++ ) {
        Serial.print( uid[i], HEX );
        Serial.print( ' ' );
      }
      Serial.println();
    }
  }
}

, 👍11

Обсуждение

Вероятно, это не проблема, но ваш массив uid имеет длину 5. Пробовали ли вы использовать массив большего размера, поскольку вам нужен результат размером 10 байт?, @asheeshr

Да, я это сделал, но это не помогло, на самом деле другая программа чтения, похоже, возвращает только 4-байтовые числа, и это другая марка с приличным примером кода, что очень сбивает с толку., @unknowndomain


4 ответа


Лучший ответ:

6

Извините, но я не согласен с вашим "Технические данные NXP непонятны". С ПЕРВОЙ СТРАНИЦЫ технических данных MFRC522:

'Примечание: MFRC522 поддерживает все варианты MIFARE Mini, MIFARE 1K, MIFARE 4K, MIFARE Ultralight, MIFARE DESFire EV1 и MIFARE Plus RF протоколы идентификации

Здесь говорится, что MFRC522 охватывает только часть ISO/IEC 14443. В NXP RC522 отсутствуют следующие сведения:

*MIFARE DESFire EV1 (включая шифрование AES)

MIFARE DESFire EV2 (включает MIsmartApp, транзакционный MAC, неограниченное количество приложений) MIFARE Plus — это замена MIFARE Classic с сертифицированным уровнем безопасности (на основе AES 128)

MIFARE SAM AV2 (модуль безопасного доступа, обеспечивающий безопасное хранение криптографических ключей и криптографических функций)*

Вероятно, это те, которые используются в банковских картах. Опять же, с ПЕРВОЙ СТРАНИЦЫ паспорта MFRC500:

«Поддерживаются все уровни протокола ISO/IEC 14443 A».

Вам придется изучить все различные спецификации MIFARE / ISO/IEC 14443, чтобы узнать, сколько байтов идентификатора существует для разных типов (я подозреваю, что разные типы возвращают разное количество байтов).

Так что, в общем-то, вы влипли. Раскошельтесь на дорогой ридер на базе MFRC500. Я предполагаю, что за более высокую цену вы также получите высококлассный API, документацию и примеры или даже (ух ты!) техническую поддержку.

Ура

,

Вы правы, что MFRC522 не поддерживает эту функцию, но вы ошибаетесь, утверждая, что MFRC500 является решением. Это устройство поддерживает только карты MIFARE Classic, MIFARE 1K (S50) и MIFARE 4K (S70)., @unknowndomain

Также модуль MFRC522 стоит <3 фунтов стерлингов, а MFRC500 — 30 фунтов стерлингов., @unknowndomain


1

MFRC522::requestTag() возвращает тип карты в первых двух байтах 2-го параметра (data в вашем примере выше). Вам нужно будет посмотреть на это значение, чтобы определить, какой это тип карты. Используйте эту информацию, чтобы распечатать требуемые N байты идентификатора.

В крайнем случае вы можете выгрузить все 16 байтов (MAX_LEN) и протестировать их с различными типами карт, чтобы увидеть, какие байты изменяются детерминированным образом, что позволит вам определить правильную длину идентификатора.

И если это сэкономит вам время, если вы вызовете функции самотестирования этой библиотеки - getFirmwareVersion() и digitalSelfTestPass(); необходимо снова вызвать MFRC522::begin(), иначе невозможно будет считать идентификаторы RFID (на момент написания статьи, конечно.)

,

1

Попробуйте использовать самый популярный из них.

https://github.com/miguelbalboa/rfid

Это работает для меня. Он возвращает uID, как вам нужно. Просто удалите другие функции, только получение uid из его примера.

,

0

Пятый байт из RC522 — это просто контрольная сумма.

Например, возможное возвращаемое значение (взято из https://github.com/miguelbalboa/rfid /issues/604#issuecomment-1885042556 ) — это:

8Б 65 66 Б9 31

и если вы выполните двоичное ИЛИ первых четырех чисел, вы получите именно пятое:

In [1]: hex(int("8B", 16)^int("65", 16)^int("66", 16)^int("B9", 16))[2:]
Out[1]: '31'

(Действительно, если сравнить первые четыре байта от RC522 с четырьмя байтами от другого считывателя, они должны совпасть)

,