Считыватель карт RFID RC522 на ESP32 (с LCD)
В этом проекте модуль RFID RC522 на базе MFRC522 подключается к ESP32 по SPI и читает UID карты или метки. Это основа для дверных замков, клубных систем и контроля доступа. Прочитанный UID выводится на LCD-экран; эта версия не сравнивает его со списком разрешённых карт. ВНИМАНИЕ: RC522 работает только от 3.3V; подача 5V сожжёт модуль!

Видео
Схема

Исходный код
1// ─────────────────────────────────────────
2// BlueGrays · bluegrays.com
3// Считыватель карт RFID RC522 на ESP32 (с LCD)
4// ─────────────────────────────────────────
5// Читает модуль RFID RC522 по SPI; UID поднесённой карты 3 с показывается
6// в HEX на I2C LCD 16x2, затем возвращается экран "scan a card" (поднеси
7// карту).
8//
9// Пины:
10// GPIO 5 -> RC522 SDA (SS)
11// GPIO 18 -> RC522 SCK, GPIO 19 -> RC522 MISO, GPIO 23 -> RC522 MOSI
12// GPIO 27 -> RC522 RST
13// GPIO 21 -> LCD SDA, GPIO 22 -> LCD SCL
14// RC522 3.3V -> RC522 3.3V -> 3V3, IRQ не подключается
15// LCD VCC -> LCD VCC -> 5V (VIN), все GND общие
16
17#include <Wire.h>
18#include <LiquidCrystal_I2C.h>
19#include <SPI.h>
20#include <MFRC522.h>
21
22// Определения пинов
23const int RST_PIN = 27; // RC522 RST
24const int SS_PIN = 5; // RC522 SDA (SS)
25
26// Пины SPI — стандартные VSPI
27MFRC522 rfid(SS_PIN, RST_PIN);
28LiquidCrystal_I2C lcd(0x27, 16, 2); // Адрес LCD 0x27 или 0x3F
29
30unsigned long lastScan = 0; // Время последнего сканирования (мс)
31const unsigned long DISPLAY_HOLD = 3000; // Время показа UID (мс)
32bool showingCard = false; // UID на экране?
33
34// Экран ожидания
35void showWaitMessage() {
36 lcd.clear();
37 lcd.setCursor(0, 0);
38 lcd.print("Kart okutun");
39 lcd.setCursor(0, 1);
40 lcd.print("Scan a card");
41}
42
43void setup() {
44 Wire.begin(21, 22); // I2C: SDA=21, SCL=22
45 lcd.init();
46 lcd.backlight();
47
48 // Заставка 3 с
49 lcd.setCursor(3, 0);
50 lcd.print("BlueGrays");
51 lcd.setCursor(3, 1);
52 lcd.print("RFID v1.0");
53 delay(3000);
54
55 // Запустить SPI и RC522
56 SPI.begin();
57 rfid.PCD_Init();
58 delay(50);
59
60 showWaitMessage();
61}
62
63void loop() {
64 // Когда время вышло, вернуться к экрану ожидания
65 if (showingCard && millis() - lastScan > DISPLAY_HOLD) {
66 showWaitMessage();
67 showingCard = false;
68 }
69
70 // Выйти, если новой карты нет или её не удалось прочитать
71 if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
72 delay(50);
73 return;
74 }
75
76 // Вывести UID в HEX, например 0A:1B:2C:3D
77 lcd.clear();
78 lcd.setCursor(0, 0);
79 lcd.print("Kart UID:");
80 lcd.setCursor(0, 1);
81 for (byte i = 0; i < rfid.uid.size; i++) {
82 if (rfid.uid.uidByte[i] < 0x10) lcd.print("0");
83 lcd.print(rfid.uid.uidByte[i], HEX);
84 // Для UID из 7 байт без разделителя: 14 символов помещаются в строку
85 if (rfid.uid.size <= 5 && i < rfid.uid.size - 1) lcd.print(":");
86 }
87
88 lastScan = millis();
89 showingCard = true;
90
91 // Остановить карту и шифрование
92 rfid.PICC_HaltA();
93 rfid.PCD_StopCrypto1();
94}
95
Частые вопросы
Какие пины использовать для подключения RC522 к ESP32?
Используются пины SPI ESP32 по умолчанию: SCK = GPIO 18, MISO = GPIO 19, MOSI = GPIO 23. Для SDA (SS) и RST используй пины, указанные в коде (например, 5 и 27); напряжение питания должно быть 3,3 V.
Работают ли LCD и RFID одновременно?
Да. LCD использует I2C (GPIO 21/22), а RC522 — шину SPI, поэтому они не мешают друг другу; две отдельные шины связи работают одновременно.
Почему на одних картах UID 4 байта, а на других 7?
Карты MIFARE Classic обычно используют 4-байтный UID, а метки MIFARE Ultralight и NTAG — 7-байтный. При сравнении проверяй и длину UID.
Можно ли добавлять разрешённые карты, не меняя код?
Да, можно написать доработку, которая добавляет следующую карту в список после поднесения «карты администратора», и сохранять список в постоянной памяти через Preferences.
