Симулятор RFID RC522 онлайн: считыватель карт без модуля
RC522 — модуль, который поставлялся без карты в комплекте, и я неделю искал «а что поднести, чтобы проверить». Скетч из примеров MFRC522 молчал в мониторе, пока я не понял, что подносить надо было именно RFID-карту 13,56 МГц, а не первую попавшуюся магнитную. В браузере этого затыка нет: в карточке считывателя есть кнопка «поднести карту» — нажмите, и скетч видит UID «12 AB 34 CD» через mfrc522.PICC_ReadCardSerial().
Модуль ставится на стенд симулятора из каталога: розовый провод с меткой RFID, четыре пина SPI (SS на D10, SCK на D13, MISO на D12, MOSI на D11). Поднесите карту в карточке — скетч прочитает UID и тип карты; уберите — чтение не сработает. Ниже — стартовый скетч чтения UID, проверка доступа по белому списку, запись сектора и честная граница.
Что эмулируется на стенде
RC522 в каталоге — деталь «RFID-считыватель RC522»: четыре пина SPI (SS на D10, SCK на D13, MISO на D12, MOSI на D11), розовый провод с меткой RFID. На плашке — кнопка «поднести/убрать карту» и поле с UID в hex. Поднесли — mfrc522.PICC_ReadCardSerial() вернёт true, и скетч читает mfrc522.uid.uidByte как массив байт. Тип карты — mfrc522.PICC_GetType — «MIFARE 1KB» по умолчанию. Ловушка из заголовка: «что поднести» — на плате нужна именно карта 13,56 МГц MIFARE Classic, не магнитная; в браузере карта уже в карточке, и подносить её кнопкой.
- SPI на D10-D13: SS на D10, SCK на D13, MISO на D12, MOSI на D11 — стандартный расклад Uno для периферии.
- MFRC522(SS_PIN, RST_PIN): конструктор библиотеки, RST обычно на D9 (в браузере заглушка).
- PICC_ReadCardSerial(): true, если карта в поле; иначе false — повторите цикл.
- uid.uidByte: 4 байта для MIFARE Classic, 7 байт для MIFARE Ultralight — в браузере 4-байтовый UID.
- PICC_GetType: «MIFARE 1KB» — тип карты по умолчанию, как у белой карты из комплекта.
Стартовый скетч: чтение UID карты
#include <SPI.h>#include <MFRC522.h> #define SS_PIN 10#define RST_PIN 9MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); Serial.println("Gotovo, podnesite kartu");} void loop() { if (!mfrc522.PICC_IsNewCardPresent()) return; if (!mfrc522.PICC_ReadCardSerial()) return; Serial.print("UID: "); for (byte i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i], HEX); Serial.print(" "); } Serial.println(); mfrc522.PICC_HaltA();}Запустите скетч, поднесите карту в карточке модуля — монитор печатает «UID: 12 AB 34 CD» (или иной UID, который задан в карточке). На живой плате тот же скетч читает белую карту из комплекта RC522; разница — в реальном времени поднесения и в антиколлизии (две карты в поле — ни одна не читается). Полный разбор подключения и шины — в уроке про основы SPI.
Проверка доступа: UID в белом списке
#include <SPI.h>#include <MFRC522.h> #define SS_PIN 10#define RST_PIN 9MFRC522 mfrc522(SS_PIN, RST_PIN); byte doverie[][4] = { {0x12, 0xAB, 0x34, 0xCD}, {0x00, 0x00, 0xFF, 0x01}};const int N = 2; void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); pinMode(7, OUTPUT); // зелёный pinMode(8, OUTPUT); // красный} void loop() { if (!mfrc522.PICC_IsNewCardPresent()) return; if (!mfrc522.PICC_ReadCardSerial()) return; boolean dostup = false; for (int i = 0; i < N; i++) { boolean sovpadenie = true; for (byte b = 0; b < 4; b++) { if (mfrc522.uid.uidByte[b] != doverie[i][b]) sovpadenie = false; } if (sovpadenie) dostup = true; } digitalWrite(7, dostup ? HIGH : LOW); digitalWrite(8, dostup ? LOW : HIGH); Serial.println(dostup ? "DOSTUP" : "OTKAZ"); mfrc522.PICC_HaltA(); delay(1000); digitalWrite(7, LOW); digitalWrite(8, LOW);}Белый список — простая и достаточная защита для дома: UID сравнивается с массивом доверенных, при совпадении зажигается зелёный светодиод и открывается реле. На плате этого хватает для двери общежития или ящика с инструментом; в промышленной системе UID клонируется за 100 рублей, и нужна криптография сектора — аутентификация ключом A или B по MFRC522.PCD_Authenticate.
Граница: модель против живого модуля
| Проверка | Симулятор | Только железо |
|---|---|---|
| SPI: D10-D13, PCD_Init | да: заглушка, модуль «на шине» | то же, плюс реальные тайминги |
| PICC_IsNewCardPresent, ReadCardSerial | да: кнопкой «поднести карту» | то же, плюс реальная антенна 13,56 МГц |
| UID через uidByte, тип PICC_GetType | да: 4-байтовый UID MIFARE 1KB | то же, плюс 7-байтовые карты |
| PCD_Authenticate, чтение и запись сектора | нет: криптография не моделируется | да — ключ A/B, 16 секторов по 4 блока |
| Антиколлизия: две карты в поле | нет: одна карта в карточке | да — ни одна не читается |
| Дальность считывания 3-5 см | не моделируется | да — антенна и питание решают |
Браузер держит UID и тип карты, а криптографию сектора — нет: PCD_Authenticate и MIFARE_Read/Write в скетче компилируются, но данные не возвращают. На плате у MIFARE Classic 16 секторов по 4 блока, ключ A открытый (по умолчанию FF FF FF FF FF FF), ключ B — для записи; «свой» UID в белый список кладётся через массив, а клонирование карты — через запись в первый сектор с известным ключом.
Грабли RC522
- Забытый SPI.begin(): без него шина не поднимается, и PCD_Init() молчит. SPI.begin() до mfrc522.PCD_Init().
- RST_PIN на D9 или не подключён: в скетче указано 9, на плате провод иногда висит в воздухе — модуль не инициализируется. Лечится RST_PIN на пин с подтяжкой или программный reset.
- Тип карты: MIFARE Classic против Ultralight. UID у Classic 4 байта, у Ultralight 7 — скетч через uid.size работает с обоими, но аутентификация сектора разная.
- Антенна 3-5 см: на плате карту надо поднести вплотную; в браузере кнопка, на плате — расстояние решает. Брелоки с эмблемой метро не работают: у них другая частота.
- Клонирование UID за 100 рублей: для дома UID как защита достаточно, для офиса — нет. Нужна криптография ключа A/B и проверка сектора, а не UID.