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// Leitor de cartões RFID RC522 com ESP32 e LCD
4// ─────────────────────────────────────────
5// Lê o módulo RFID RC522 via SPI; o UID do cartão lido aparece em HEX no
6// LCD I2C 16x2 por 3 s e depois volta a tela de "aproxime um cartão".
7//
8// Pinos:
9// GPIO 5 -> RC522 SDA (SS)
10// GPIO 18 -> RC522 SCK, GPIO 19 -> RC522 MISO, GPIO 23 -> RC522 MOSI
11// GPIO 27 -> RC522 RST
12// GPIO 21 -> LCD SDA, GPIO 22 -> LCD SCL
13// RC522 3.3V -> RC522 3.3V -> 3V3, o IRQ fica desconectado
14// LCD VCC -> LCD VCC -> 5V (VIN), todos os GNDs em comum
15
16#include <Wire.h>
17#include <LiquidCrystal_I2C.h>
18#include <SPI.h>
19#include <MFRC522.h>
20
21// Definição dos pinos
22const int RST_PIN = 27; // RC522 RST
23const int SS_PIN = 5; // RC522 SDA (SS)
24
25// Os pinos SPI são o padrão do VSPI
26MFRC522 rfid(SS_PIN, RST_PIN);
27LiquidCrystal_I2C lcd(0x27, 16, 2); // Endereço do LCD 0x27 ou 0x3F
28
29unsigned long lastScan = 0; // Hora da última leitura (ms)
30const unsigned long DISPLAY_HOLD = 3000; // Tempo de exibição do UID (ms)
31bool showingCard = false; // Há um UID na tela
32
33// Tela de espera
34void showWaitMessage() {
35 lcd.clear();
36 lcd.setCursor(0, 0);
37 lcd.print("Kart okutun");
38 lcd.setCursor(0, 1);
39 lcd.print("Scan a card");
40}
41
42void setup() {
43 Wire.begin(21, 22); // I2C: SDA=21, SCL=22
44 lcd.init();
45 lcd.backlight();
46
47 // Tela de abertura por 3 s
48 lcd.setCursor(3, 0);
49 lcd.print("BlueGrays");
50 lcd.setCursor(3, 1);
51 lcd.print("RFID v1.0");
52 delay(3000);
53
54 // Inicia o SPI e o RC522
55 SPI.begin();
56 rfid.PCD_Init();
57 delay(50);
58
59 showWaitMessage();
60}
61
62void loop() {
63 // Quando o tempo acaba, volta para a tela de espera
64 if (showingCard && millis() - lastScan > DISPLAY_HOLD) {
65 showWaitMessage();
66 showingCard = false;
67 }
68
69 // Sai se não houver cartão novo ou se ele não puder ser lido
70 if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
71 delay(50);
72 return;
73 }
74
75 // Mostra o UID em HEX, por exemplo 0A:1B:2C:3D
76 lcd.clear();
77 lcd.setCursor(0, 0);
78 lcd.print("Kart UID:");
79 lcd.setCursor(0, 1);
80 for (byte i = 0; i < rfid.uid.size; i++) {
81 if (rfid.uid.uidByte[i] < 0x10) lcd.print("0");
82 lcd.print(rfid.uid.uidByte[i], HEX);
83 // Sem separador para UID de 7 bytes: 14 caracteres cabem na linha
84 if (rfid.uid.size <= 5 && i < rfid.uid.size - 1) lcd.print(":");
85 }
86
87 lastScan = millis();
88 showingCard = true;
89
90 // Para o cartão e encerra a criptografia
91 rfid.PICC_HaltA();
92 rfid.PCD_StopCrypto1();
93}
94
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.
