Leitor de cartões RFID RC522 com ESP32 e LCD
Neste projeto, vamos conectar o módulo RFID RC522, baseado no MFRC522, ao ESP32 via SPI e ler o UID do cartão ou da etiqueta. Isso serve de base para aplicações como fechaduras, sistemas de associados e controle de acesso. Vamos exibir o UID lido em um display LCD; nesta versão, ele não é comparado com uma lista de cartões autorizados. **ATENÇÃO:** o RC522 funciona apenas com **3,3V**; alimentá-lo com 5V queima o módulo!

Vídeo
Esquema do circuito

Código-fonte
1// ─────────────────────────────────────────
2// BlueGrays · bluegrays.com
3// ESP32 RFID RC522 Card Reader (with LCD)
4// ─────────────────────────────────────────
5// Reads the RC522 RFID module over SPI; the UID of a scanned card is shown
6// in HEX on the 16x2 I2C LCD for 3 s, then the "scan a card" screen
7// returns.
8//
9// Pins:
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 is left unconnected
15// LCD VCC -> LCD VCC -> 5V (VIN), all GNDs common
16
17#include <Wire.h>
18#include <LiquidCrystal_I2C.h>
19#include <SPI.h>
20#include <MFRC522.h>
21
22// Pin definitions
23const int RST_PIN = 27; // RC522 RST
24const int SS_PIN = 5; // RC522 SDA (SS)
25
26// SPI pins are the VSPI default
27MFRC522 rfid(SS_PIN, RST_PIN);
28LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD addr 0x27 or 0x3F
29
30unsigned long lastScan = 0; // Last scan time (ms)
31const unsigned long DISPLAY_HOLD = 3000; // UID display time (ms)
32bool showingCard = false; // Is a UID on the screen
33
34// Waiting screen
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 // Splash screen 3 s
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 // Start SPI and the RC522
56 SPI.begin();
57 rfid.PCD_Init();
58 delay(50);
59
60 showWaitMessage();
61}
62
63void loop() {
64 // When the time is up, go back to the waiting screen
65 if (showingCard && millis() - lastScan > DISPLAY_HOLD) {
66 showWaitMessage();
67 showingCard = false;
68 }
69
70 // Leave if there is no new card or it cannot be read
71 if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
72 delay(50);
73 return;
74 }
75
76 // Print the UID in HEX, e.g. 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 // No separator for a 7-byte UID: 14 chars fit the line
85 if (rfid.uid.size <= 5 && i < rfid.uid.size - 1) lcd.print(":");
86 }
87
88 lastScan = millis();
89 showingCard = true;
90
91 // Halt the card and stop encryption
92 rfid.PICC_HaltA();
93 rfid.PCD_StopCrypto1();
94}
95
Perguntas frequentes
Quais pinos devo usar para conectar o RC522 ao ESP32?▾
São usados os pinos SPI padrão do ESP32: SCK = GPIO 18, MISO = GPIO 19, MOSI = GPIO 23. Para SDA (SS) e RST, use os pinos indicados no código (por exemplo, 5 e 27); a tensão de alimentação deve ser de 3,3 V.
O LCD e o RFID funcionam ao mesmo tempo?▾
Sim. Como o LCD usa I2C (GPIO 21/22) e o RC522 usa o barramento SPI, eles não interferem entre si; os dois barramentos de comunicação funcionam ao mesmo tempo.
Por que o UID tem 4 bytes em alguns cartões e 7 em outros?▾
Os cartões MIFARE Classic geralmente usam um UID de 4 bytes, enquanto as etiquetas MIFARE Ultralight e NTAG usam um UID de 7 bytes. Ao comparar, você também deve verificar o tamanho do UID.
Posso adicionar cartões autorizados sem alterar o código?▾
Sim, você pode programar um modo que adicione o próximo cartão à lista após a leitura do "cartão de administrador" e salvar a lista na memória permanente usando Preferences.
