你们有没有想过,楼下门禁那个“嘀”一声就能开门的感应卡、公司一卡通、甚至实验室的工具柜授权卡,到底是什么原理?答案就是13.56MHz高频RFID。我一直觉得玩嵌入式最大的乐趣,就是把这种平时觉得“挺高端”的东西拉到桌面上拆开看。而且真没有想象中那么难:一块三十来块的RFID-RC522模块,加上一块十几块钱的ESP32开发板,就能把一套完整的刷卡系统原型搭出来。这篇文章就是写给真正零基础的人,我会从射频原理讲到硬件接线,再一步步把读卡代码跑通,最后做出一套带白名单判断和继电器开锁的小门禁。你不需要懂硬件,也不需要提前会写代码,只要照着一路抄下来,就能真实感受到“刷卡能力”是怎么落到ESP32上的。
1. 一张卡凭什么能“嘀”一下就被认出来:RFID电磁耦合与协议
1.1 从物理角度看“刷卡”:线圈里的电磁感应
我第一次拆开门禁卡的时候也挺惊讶:里面没有电池,也没有复杂电路,就一个很小的线圈加一颗芯片,外面封上PVC塑料就成了卡片。它工作的核心是电磁感应。
读卡模块(就是RC522那一端)的天线线圈会持续发射13.56MHz的电磁波。当卡片靠近时,卡片内部的线圈进入这个交变磁场里,根据法拉第电磁感应定律,线圈里就会产生感应电动势;这个电压经过卡片芯片内部整流,就变成了给芯片供电的电源。同时,卡片芯片会通过改变自身线圈的负载状态,把自己存储的数据以“负载调制”的方式回传给读卡器。你可以这样理解:读卡器像变压器初级线圈,卡片像次级线圈,两者之间没有导线连接,但靠磁场完成了“输电”和“对话”。
这个频率范围内的RFID,行业里习惯叫高频RFID,国际标准主要是ISO/IEC 14443A,也就是NFC的基础通信协议之一。所以你能看到,手机NFC能刷公交、刷门禁,和RC522读卡本质上是在同一个射频频段里工作的。
1.2 ID卡和IC卡:别把两种卡混为一谈
大家手里那种门禁卡,粗略分两类:低频ID卡和高频IC卡。
| 类别 | 工作频率 | 典型芯片/协议 | 特点 |
|---|---|---|---|
| ID卡 | 125kHz | EM4100等 | 只存一个出厂ID号,无法写入数据,不可加密 |
| IC卡 | 13.56MHz | MIFARE Classic 1K(S50)等 | 可读写数据区,支持密钥认证,结构复杂得多 |
刚开始做RFID项目,最容易踩的坑就是买错卡。RC522模块只能读13.56MHz的IC卡,如果你买了一套125kHz的ID读卡器钥匙扣,那完全不是同一个东西。我们后面用的都是IC卡,而且是ISO/IEC 14443A标准下的MIFARE卡。
MIFARE Classic 1K卡,容量是1KB,内部存储空间被分成16个扇区,每个扇区又有4个数据块。其中0扇区0块的最后4个字节就是卡片UID(唯一标识),也就是我们常说的“卡号”。对绝大部分门禁应用来说,我们最关心这个UID,因为它标志着一张卡的身份。UID在出厂时固化,正常情况下不能改写(有些特殊UID卡可以改,这个后面讲)。
1.3 RC522模块:把复杂协议压缩成一块小板子
如果让你自己搭射频读卡电路,要处理载波调制、解调、防碰撞、认证等等一系列底层细节,门槛非常高。但好在NXP设计的RC522芯片把这些都封装好了,市面上大量模块直接把芯片、天线、匹配电路、稳压电路集成在一块小板子上,焊接好引脚就能用。
模块常见接口有三种:SPI、I2C、UART。我强烈建议用SPI接口,因为速度快、接线固定、网上资料最多。SPI方式下,你只要通过四条信号线(加上电源和复位)就能跟RC522通信。RC522会替你完成“发现卡片、防碰撞、选中卡片、认证、读写数据”这些复杂动作,ESP32这边只需要发指令、收结果,就像调用一个小工具。
用RC522配ESP32还有一个很实际的原因:两者都是3.3V逻辑电平,不需要额外电平转换,直连就行;而且ESP32的GPIO数量足够,就算接一堆外围设备也不紧张。这套组合做出来的东西,从门禁到智能储物柜、从签到工具到互动装置,都能用得上。
2. RC522模块接线:ESP32的SPI总线分配与供电细节
2.1 先看懂模块上的引脚:每个引脚到底干嘛的
RC522模块引脚图和丝印上写得很清楚,但很多零基础朋友看到一堆字母就发懵,我先拆一遍:
- VCC / GND:电源。VCC接3.3V,GND接GND。
- RST:复位/使能引脚。对RC522来说,这个引脚控制芯片复位和启动,必须由ESP32控制,不能悬空。
- SDA:SPI接口的片选信号,也叫SS/CS。SPI允许一主多从,靠片选来决定当前跟哪个设备通信。低电平选中RC522,所以这个引脚必须由ESP32主动控制。
- SCK:SPI时钟线,由ESP32输出同步时钟,决定了通信节奏。
- MOSI:主出从入。ESP32发给RC522的指令和数据走这根线。
- MISO:主入从出。RC522返回给ESP32的数据走这根线。
- IRQ:中断请求输出。RC522检测到卡片时会主动拉低此引脚提示外部MCU,其实不接也能工作,用轮询方式读卡够了,零基础阶段可以先不管它。
从引脚功能就能看出来,RC522是被动方,ESP32是主动方。主动方先选中模块,再通过MOSI发指令,从模块读数据通过MISO,整个过程完全由ESP32控制。
2.2 一张表搞定接线:默认VSPI引脚
ESP32的Arduino环境默认把SPI映射到了VSPI总线,标准引脚如下:
- SCK → GPIO18
- MOSI → GPIO23
- MISO → GPIO19
这三个是固定映射,你可以通过代码改成HSPI,但对新手来说没必要。片选SS引脚是可以自定义的,选一个没被其他外设占用的GPIO就行。RST也是自定义引脚。我自己常用的接线方案是这样的:
| RC522引脚 | 对应ESP32 GPIO | 说明 |
|---|---|---|
| VCC | 3.3V | 电源正极 |
| GND | GND | 共地 |
| RST | GPIO27 | 自定义复位脚 |
| SDA | GPIO5 | 自定义片选脚 |
| SCK | GPIO18 | SPI时钟 |
| MOSI | GPIO23 | 主出从入 |
| MISO | GPIO19 | 主入从出 |
| IRQ | 不接 | 默认不使用中断模式 |
接线原则很简单:先接电源,再接信号线。RC522模块大部分是排针引出,用杜邦线直接插到ESP32开发板上。注意别把VCC和GND接反,接反大概率烧模块,这是新手入门最快“交学费”的方式之一。
2.3 供电细节:为什么我坚持用3.3V而不是5V
你现在去网上搜,还能看到不少教程让RC522接5V,理由是“模块上有稳压芯片,5V也能承受”。这句说法有一定道理,因为某些版本的模块板上确实有稳压电路,但我实测下来有几个问题:
第一,RC522工作电压范围就是2.5V到3.3V,引脚电平也都是3.3V逻辑,接入5V会让模块内部部分电路工作在超出设计值的高压下,长时间使用发热明显。第二,SPI引脚的电平如果被拉到5V,会和ESP32的3.3V GPIO电平不匹配,轻则通信不稳定,重则损伤ESP32引脚。第三,从功耗角度,5V供电并没有任何好处,反而白白增加发热。
真正稳妥的做法:RC522的VCC直接接ESP32开发板的3.3V引脚,地线共地,信号线全部直连。如果你后面加继电器、电磁锁、大功率蜂鸣器,一定要注意负载回路的电源和ESP32的3.3V分开,只共用GND,不然刷卡瞬间电流掉压,ESP32就会重启,现场效果就是“刚嘀一声就死机”。
另外,天线正下方那个区域,PCB上尽量别有金属物体。RC522模块底部有天线线圈,如果你把模块直接贴在金属桌面上,磁场会被金属吸收,读卡距离会肉眼可见地缩短。后面避坑章节我还会展开讲。
3. 三条消息打通读写链路:MFRC522读卡Demo逐步拆解
3.1 Arduino IDE环境准备:让ESP32先能编译烧录
先把开发环境搭起来。打开Arduino IDE,在“文件 → 首选项 → 附加开发板管理器网址”里填入ESP32官方开发板索引地址,然后在“工具 → 开发板 → 开发板管理器”里搜索esp32,安装对应的开发板支持包。这个过程需要联网,如果下载慢,国内用户可以把地址改成镜像。
安装完成后,在“工具 → 开发板”里选择你的板型。市面上山寨版ESP32 DevKit基本可以选“ESP32 Dev Module”,端口要先在设备管理器里确认是否出现了COM口。如果插上USB没有反应,大概率是板载USB转串口芯片驱动没装好。常见的驱动芯片有CP2102、CH340等,去官方驱动站下载对应驱动安装即可。环境配置这块,很多新手卡在端口识别上,我可以很负责地说,这一步搞不定,后面再好的代码也烧不进去。
3.2 安装MFRC522库
RFID读卡不需要你自己从头写协议,社区已经有大佬封装好了库。在Arduino IDE的“工具 → 管理库”里搜索MFRC522,选择那个维护活跃的版本安装即可。装完之后,“文件 → 示例 → MFRC522”下面会出现一大串示例程序。
放着这么多示例不用白不用,我建议你先跑一下dumpInfo示例。这个程序会把放到感应区上的卡片信息全部读出来:UID、卡片类型、每个扇区的认证状态和数据。它就像一张“验尸报告”,能帮你快速确认电路是否真的通了。后续做项目时,这个示例程序也可以留着当调试工具。
3.3 最小读卡代码逐行拆解
下面这段代码是我在官方示例基础上精简出来的,完成了“卡片放上去,串口打印卡号”这一个核心动作。不求花哨,只求把整个RFID链路跑通。
#include <SPI.h> #include <MFRC522.h> #define RST_PIN 27 #define SS_PIN 5 MFRC522 mfrc522(SS_PIN, RST_PIN); // 创建MFRC522实例 void setup() { Serial.begin(115200); SPI.begin(); // 初始化SPI总线 mfrc522.PCD_Init(); // 初始化RC522芯片 Serial.println(F("把卡片放到感应区...")); } void loop() { // 检测感应区内是否有新卡 if (!mfrc522.PICC_IsNewCardPresent()) { return; } // 选中卡片,获取UID if (!mfrc522.PICC_ReadCardSerial()) { return; } // 打印卡号(UID) Serial.print(F("卡号: ")); for (byte i = 0; i < mfrc522.uid.size; i++) { if (mfrc522.uid.uidByte[i] < 0x10) { Serial.print(F("0")); // 保证两位显示,例如0A而不是A } Serial.print(mfrc522.uid.uidByte[i], HEX); } Serial.println(); // 停止与该卡片的会话,避免卡一直处于激活状态 mfrc522.PICC_HaltA(); }关键点逐个说:
第一,PICC_IsNewCardPresent()从名字就能看出来,它是“是否有一张新卡出现”。实际运行中,如果你把卡一直贴在读卡区,这个函数可能返回false,因为它检测的是“新卡进入”这一动作,并不是持续检测卡存在。所以刷一下后想再刷同一张卡,需要把卡拿开再靠近。
第二,PICC_ReadCardSerial()是真正去读取卡片的UID。成功后,UID数据会放在mfrc522.uid.uidByte[]数组里,长度存在uid.size。对MIFARE Classic 1K卡来说,size通常是4字节,也就是8位十六进制字符,比如A1B2C3D4。打印时每个字节补一个前导0,是为了让输出格式统一,方便后面做字符串比对。
第三,PICC_HaltA()对应ISO/IEC 14443A协议里的HALT指令。执行之后,卡片会进入停止状态,不再响应读卡器。如果不做这一步,某些卡会持续停留在激活状态,下次再调用读取函数时可能出现异常。这个收尾动作不是可选项,是协议规范的一部分。
这里还要注意一个细节:MFRC522读卡不需要密钥就能读UID,但如果你要进一步读卡内数据块,就必须知道该扇区的密钥。默认的MIFARE Classic卡出厂密钥通常是FFFFFFFFFFFF,这是公开知识,也只适用于你自己的空白卡测试。
3.4 编译烧录与串口验证
写完代码,点上传按钮。如果编译通不过,优先检查库是不是装好了、开发板类型选没选对。烧录完成后打开串口监视器,波特率设置成115200,程序会提示你把卡片放到感应区。
这时候拿卡靠近模块天线,串口窗口里应该会打印出类似卡号: A1B2C3D4的信息。我第一次跑通的时候,还是挺有成就感的:一张PVC卡片、一块小板子、几根杜邦线,就这么完成了“识别身份”的动作。如果你放卡没反应,别急着怀疑代码,先把卡贴近天线、换个角度试试,还不行就查接线。后面避坑部分我会给完整的排查链路。
4. 从“读卡号”到“刷卡放行”:白名单判断与继电器联动
4.1 授权卡白名单:门禁系统的核心逻辑
能读到卡号只是第一步,一台门禁机不是读到卡就开门,它得判断“这张卡有没有权限”。实现方法特别直白:把允许通过的卡号存进一个数组,每次读到卡都去比对一遍。
String authorizedUID[] = { "A1B2C3D4", "A1B2C3D5" }; bool checkAccess(String uid) { for (int i = 0; i < sizeof(authorizedUID) / sizeof(authorizedUID[0]); i++) { if (uid.equalsIgnoreCase(authorizedUID[i])) { return true; } } return false; }使用的时候,在上一部分的读卡代码里,把串口打印的内容统一转成大写字符串,再传给checkAccess()。返回true就是授权卡,返回false就是陌生卡。这个逻辑很简单,但它是整个“刷卡能力”的灵魂:从“能读到卡”变成了“能做判断”。
需要注意的一点是,MIFARE卡UID不一定是4字节。比如某些NFC标签模拟出来的UID是7字节或10字节,所以比对逻辑里别写死字符串长度,直接用完整串比对就行。
4.2 反馈机制:LED灯和蜂鸣器让人知道刷卡结果
门禁系统必须有反馈,不然用户根本不知道刷成功还是失败。最常见的反馈是灯和声音。我建议接线这样分配:
| 器件 | 引脚 | 说明 |
|---|---|---|
| 绿色LED | GPIO4 | 刷成功亮 |
| 红色LED | GPIO14 | 刷失败亮 |
| 有源蜂鸣器 | GPIO13 | 嘀一声/嘀嘀两声 |
绿色LED和蜂鸣器接线要串一个限流电阻,有源蜂鸣器是给高电平就响、给低电平就停那种,千万注意别买成无源蜂鸣器,无源的需要PWM频率才会发声,用digitalWrite是响不了的。
反馈函数的写法可以这样:
#define LED_OK_PIN 4 #define BUZZER_PIN 13 void feedbackOK() { digitalWrite(LED_OK_PIN, HIGH); digitalWrite(BUZZER_PIN, HIGH); delay(200); digitalWrite(BUZZER_PIN, LOW); digitalWrite(LED_OK_PIN, LOW); } void feedbackDenied() { digitalWrite(BUZZER_PIN, HIGH); delay(100); digitalWrite(BUZZER_PIN, LOW); delay(100); digitalWrite(BUZZER_PIN, HIGH); delay(100); digitalWrite(BUZZER_PIN, LOW); }刷成功就是“嘀”一声长响加绿灯,刷失败就是“嘀嘀”两声短响加红灯。人对于声音和灯光的反应比看串口快得多,这套反馈一旦接上,整个东西瞬间就有了“产品感”。
这里有个小坑:用delay会让整个程序暂停,如果用户迅速连续刷多张卡,后面几秒的刷卡动作会被忽略。Demo阶段无所谓,如果要做成正式系统,建议改用millis()或定时器做非阻塞控制,刷卡回应和主循环互不拖累。这个属于产品化阶段才需要优化的点。
4.3 联动继电器:让刷卡真正“开门”
门禁门锁大多是电磁锁或电控锁,工作电压通常是12V甚至24V,电流也不小,ESP32的GPIO根本不可能直接驱动。标准做法是加继电器隔离。
继电器模块选择很关键。我强烈建议买带光耦隔离的双路或单路继电器模块,原因后面避坑部分会讲。接线方式:
| 继电器模块引脚 | 连接 |
|---|---|
| IN | ESP32 GPIO26 |
| VCC | ESP32 5V引脚(部分模块需要5V驱动线圈) |
| GND | 与ESP32共地 |
| COM/NO | 串接到电磁锁电源回路里 |
控制逻辑很简单,刷卡验证通过后,把GPIO26拉高,继电器吸合,电磁锁通电,保持3秒再断开,模拟“开门”的动作:
#define RELAY_PIN 26 if (checkAccess(uid)) { feedbackOK(); digitalWrite(RELAY_PIN, HIGH); // 吸合继电器 delay(3000); // 开门3秒 digitalWrite(RELAY_PIN, LOW); // 释放 }接线时请注意:电磁锁的12V电源回路、继电器触点、电磁锁三者要串联成一个相对独立的强电回路,ESP32和继电器模块之间只有信号线和共地线。千万不要把12V电源直接接到ESP32的任何引脚上,这个错误一旦发生,开发板当场报废是轻的。
继电器模块还有个细节:绝大多数型号的VCC是给继电器线圈供电的,标称要求5V。如果直接从ESP32的3.3V取电,很多继电器线圈的最低动作电压都达不到,模块完全没反应。所以如果你是拿5V供电给继电器,那VCC接ESP32的5V引脚没问题,但要记住5V引脚和3.3V引脚在开发板内部是两路电源,共地就行。最后再强调一次:去耦电容或者光耦模块能有效减少继电器产生的电磁干扰,别省这个钱。
5. 零基础最容易翻车的4个环节:实测避坑记录
5.1 卡片读不出或距离特别短:天线和供电的连环坑
如果你遇到“卡片贴上去半天没反应”,不要急着怀疑代码,我按照发生概率从高到低排一下排查链路:
第一,卡和天线的耦合角度。卡片平面必须大致平行于RC522天线平面,很多新手竖着拿卡或者隔着厚卡套,读卡距离自然就缩水。第二,模块底下有没有金属。金属会吸收磁场能量,哪怕底下放了一张铝箔,读卡也会立刻变得不稳定。第三,供电电压。如果你用USB口给ESP32供电,同时板子又接了显示屏、Wi-Fi,USB口电压已经被拉低,RC522天线场强不够,读卡距离会明显变近。换个带载能力强的适配器彻底解决。
第四,还有一个容易踩的坑是模块质量问题。市面上RC522模块版本很杂,经典蓝色PCB版本和后来那种镀金天线的“兼容版”,读卡距离差别很大。实测下来,某些廉价款读MIFARE卡的距离只有1厘米,而标准蓝色板能做到4到6厘米。买了这种模块,靠调代码是救不回来的,早点换模块。
5.2 ESP32反复重启:电源跌落和启动引脚的双重问题
我见过不少人在群里问“为什么一刷卡ESP32就重启”,大概率的元凶有两个。
一个是电源跌落。RC522天线工作瞬间电流虽然只有几十毫安,但如果你的系统里有OLED、LED灯组、继电器,刷卡瞬间所有外设电流叠在一起,会超过USB口或稳压器的承受能力,VCC跌到ESP32的最低工作电压以下,芯片整个复位。这种现象在加了继电器以后尤其明显,因为继电器线圈吸合瞬间电流相当大。稳妥的做法是分区供电:MCU和RC522用3.3V,继电器和蜂鸣器用独立5V,两者只共GND。
另一个就是刚讲的继电器模块问题。廉价继电器模块没有光耦隔离,线圈断开瞬间会产生很高的反向尖峰电压,这个尖峰会顺着信号线回流到GPIO,甚至触发ESP32复位。解决办法很简单:买带光耦隔离的模块,或者至少在继电器线圈两端并联一个续流二极管。这已经不是“零基础可以不看”的优化,是必须注意的硬件保护措施。
5.3 GPIO引脚冲突:看不见的“幽灵”问题
ESP32的GPIO并不都是“普通IO”,有些引脚在上电阶段有特殊作用,外部电路接法不对会让板子直接启动失败。我踩过的和看过别人踩的典型有这么几个:
GPIO0:启动时必须为高电平。如果外部电路把它拉低,板子会进入下载模式而不是正常运行。所以别把按键的一端接到GND、另一端接到GPIO0,除非你明确知道自己在干嘛。
GPIO12:启动时读取这一引脚的电平决定内部Flash电压(1.8V还是3.3V)。如果外部给它接了强上拉到高电平,可能导致Flash工作电压判断错误,板子无法启动。很多新手把LED或继电器信号接GPIO12,然后出现“上电黑屏/无法烧录”的怪问题。
GPIO1和GPIO3:这对引脚是板载串口(UART0)接USB转串口芯片用的。如果外设把这两个引脚占用了,板子就没法和电脑通信,既不能烧录也不能看串口输出。
我这套方案里,SS选GPIO5、RST选GPIO27、LED选GPIO4、蜂鸣器选GPIO13、继电器选GPIO26,都是为了避开这些坑。你在网上抄别人的接线图时,别只看“功能”,要确认引脚是否安全。
5.4 卡类型买错:M1卡、UID卡和ID卡搞混
买卡的时候,商家页面写什么“门禁卡IC卡ID卡可复制卡”,新手很容易看晕。我给你一个非常直接的购买建议:只买“13.56MHz MIFARE Classic 1K(S50)空白卡”,商家如果标了“UID卡”“CUID卡”,也可以,但你要知道区别:
| 卡类型 | 说明 | RC522能否读 |
|---|---|---|
| M1卡(S50) | 标准MIFARE Classic 1K,UID出厂固化 | 能 |
| UID卡 | UID可改写的特殊卡,用于复制实验 | 通常能 |
| CUID卡 | 兼容性较好的UID可改卡 | 能 |
| ID卡 | 125kHz低频卡,和高频完全不兼容 | 不能 |
零基础阶段一张标准M1卡就够用了,搞清楚这张卡的UID在哪、怎么读出来,后面再玩复制实验也不迟。
如果你发现RC522什么都读不到,先看看你手里的卡是不是125kHz的ID厚卡,很多“小区门禁钥匙扣”就是低频卡,刷卡机也在物理形态上没啥区别,但要认清RC522跟它们八字不合。
6. 从门禁Demo到原型产品:持久化、NFC模拟与安全边界
6.1 掉电不丢授权:用Preferences保存白名单
前面白名单是写在代码数组里的,每次新增授权卡都要改代码重新烧录,这在Demo阶段没问题,产品化就太蠢了。更好做法是把白名单存进ESP32的NVS闪存里,用Arduino标准的Preferences库就能做。
#include <Preferences.h> Preferences prefs; void setup() { // ... prefs.begin("rfid", false); // 打开名为rfid的命名空间 String uid = prefs.getString("uid1", ""); // 首次使用没有数据,返回空字符串 } void addUID(String uid) { prefs.putString("uid1", uid); prefs.end(); } void loadUIDs() { prefs.begin("rfid", true); // 只读模式打开 String uid1 = prefs.getString("uid1", ""); String uid2 = prefs.getString("uid2", ""); prefs.end(); }这样,你可以在运行中通过某个按键把当前卡片加入白名单,掉电后依然保留。如果卡号多,最好把整个白名单序列化成一个JSON字符串存在SPIFFS或Flash里,维护起来更灵活。Preferences库本身操作简单、可靠性高,普通门禁场景足够。
6.2 让手机NFC也能刷:卡模拟和读写器的区别
既然RC522是13.56MHz读取器,理论上手机NFC也可能替代物理卡。但这里有个关键区别:手机NFC通常默认工作在“读卡器模式”或“卡模拟模式”,能不能被RC522读到,取决于手机App有没有真正开启卡模拟。
想在ESP32项目里体验“手机刷门禁”,有两条路线:
一条是让手机模拟一张ISO/IEC 14443A卡片。部分安卓手机自带NFC卡模拟功能,或者通过特定App把一张空白MIFARE卡的UID模拟到手机里,之后RC522读到的是一个虚拟UID。需要注意,不是所有手机都允许模拟未经过认证的卡,iPhone的NFC更是默认封闭,除非走Apple的专属接口,否则实现起来很受限。
另一条路线是用支持卡模拟的PN532模块替换RC522,做出一个可以“复制卡到手机”的设备。这个方向涉及更多加密协议细节,而且容易被滥用,我在这里只提示方向:如果你要做的是产品原型,请先确认NFC安全机制和授权链路,而不是绕过它们。
6.3 安全提醒:高频RFID的复制风险别不当回事
谈点现实的问题:MIFARE Classic 1K卡的加密机制已经非常古老,默认密钥是公开的,当年早就有完整破解方案。现在网上便宜的UID卡,可以在几秒钟内复制一张普通M1门禁卡,而且刷起来一模一样,因为很多老旧门禁系统只读UID,不做密钥认证。
所以,如果你只是给自己宿舍搞一个智能门锁练手,RC522加M1卡完全够玩,但千万别把这种方案直接用在真实的高安全门禁、支付、身份认证场景里。你要用它做个原型的思路没问题,但产品化必须换安全等级更高的方案,比如CPU卡、DESFire EV2这类芯片卡,或者手机NFC SE安全单元配合动态密钥授权。
RFID这门技术在项目里让人又爱又恨,爱的是它的“无线电近场识别”能力实在太便利,恨的是安全边界一旦没划好,复制成本太低了。搞嵌入式玩到后面,一定要有这根安全弦,尤其是你开始做门禁、开锁、储物这类和物理世界对接的东西。
回到最开始那个问题:ESP32的刷卡能力到底哪来的?拆开看无非就是一张IC卡和一块读卡芯片之间的电磁耦合,ESP32负责把“读到卡”翻译成“做什么”。我做了这么多年嵌入式项目,最大的心得就是别怕拆,买一块板、一张卡、一个模块,接错几根线、烧废几个固件,收获比看十篇教程都大。如果你读完这篇文章能自己复现一个“嘀一声报卡号”的Demo,那下一步就可以把继电器接上,把它真装成一个门禁设备——那个“嘀”声背后,藏着的是一套稳定运行了几十年的电磁近场通信协议,而你刚刚亲手把它请进了自己的项目里。