如何使用 Arduino 和 RFID 以及 RC522 模块

  • RFID 技术允许使用被动或主动标签,通过射频和唯一的 UID 来识别物体,而无需直接的视觉接触。
  • RC522 模块基于 MFRC522 芯片,工作频率为 13,56 MHz,支持 MIFARE Classic 板,主要通过 SPI 与 Arduino 通信。
  • MIFARE Classic 1K 卡将其内存组织成扇区和块,具有 Key A/Key B 密钥和访问条件,这些都必须了解和更改。
  • 通过将 MFRC522 库与 Arduino 结合使用,可以实现诸如门禁控制或可充电交通卡等实用项目。

如何使用 Arduino 和 RFID:传感器和项目完整指南

如果你曾在超市自助结账机前操作过,看到你把商品放在托盘上后,它们会自动显示在屏幕上,那么你已经见识过RFID技术了。这并非魔法或心灵感应:它是一种基于射频的系统,无需直接接触即可识别物体。你甚至可以用一个简单的Arduino板和一个像RC522这样价格低廉的读卡器在家实现同样的功能。

在本指南中,您将逐步学习如何使用 Arduino 和 RC522 RFID 阅读器来读写标签,了解 RFID 的本质、现有系统类型、无源卡的供电方式、MIFARE Classic 1K 卡的内存组织结构,以及如何构建实际项目,例如门禁系统或可充值交通卡。请做好准备,我们将深入探讨该主题,但会以清晰易懂的方式进行讲解。

什么是RFID技术?它是如何工作的?

射频识别(RFID)系统利用无线电波传输的唯一标识符来识别物体。该标识符通常称为UID(唯一标识符),可以理解为标签的ID。整个系统由两个主要部分组成:RFID标签(或应答器)和RFID读写器(收发器)。

RFID标签有多种形式:类似信用卡的塑料卡、钥匙扣、粘贴在产品上防止被盗的贴纸,甚至还有植入动物皮下用于识别的芯片。它们的内部组件基本相同:天线和用于存储信息并与读写器通信的小型芯片。

标签分为只读标签和读写标签。只读标签的UID在出厂时已预先编程,无法修改;读写标签则可以使用合适的读卡器(例如RC522模块)进行读写操作。这使得充值交通卡、预付费门禁系统、考勤系统等应用成为可能。

另一方面,我们还有RFID读写器或收发器。这种设备不仅接收数据,还会发射射频电磁场。了解这个电磁场对于理解无源标签的供电方式以及卡片和读写器之间如何交换信息至关重要。

RFID标签的供电和工作原理

一个很常见的问题是:如果超市商品上的RFID标签或门禁卡没有电池,它们从哪里获得能量来工作?关键在于,许多这类标签是无源的,它们通过读写器产生的电磁场进行感应供电。

当无源标签靠近读写器时,其天线会进入模块产生的电磁场(例如,RC522 的电磁场频率为 13,56 MHz)。该电磁场会在标签天线中感应出电流,用于瞬间为内部芯片供电。芯片“唤醒”后,会调制其发送回读写器的信号(称为反向散射),对 UID 以及(如果适用)存储在内存中的其他数据进行编码。

与红外等技术不同,标签和读取器之间不需要直接视线接触:射频可以穿透某些材料,尽管其行为取决于频率、金属、水等的存在。读取器捕获反向散射信号,对其进行解释,然后将数据发送到微控制器(例如 Arduino、ESP8266 或 ESP32)或计算机。

根据频率划分的RFID系统类型

射频频谱非常宽广,而且无线电波在不同频率下的特性并不相同。因此,RFID技术会根据应用场景使用不同的频段。读写器和标签必须设计成在同一频率下工作,就像收音机必须调到正确的电台一样。

一般来说,我们可以根据RFID系统使用的频段,将其分为三大类:

  • 低频 (LF):大约 125-134 kHz。
  • 高频(HF):大约 13,56 MHz,其中包括 MIFARE 和 NFC 等技术。
  • 超高频(UHF):大约在 433 MHz 到 860-960 MHz 之间。

低频(LF)RFID系统

低频RFID系统波长相对较长,因此能够更好地穿透薄层材料和含水量高的物体,例如水果或饮料。它们在薄金属附近也表现良好。

然而,这种优势也伴随着明显的局限性:典型范围只有几厘米,数据传输速率低,导致内存容量有限,标签成本较高。这些系统通常用于简单的门禁控制、老式近距离感应钥匙和动物标记。

高频(HF)RFID和NFC系统

13,56 MHz 的高频段可能是“创客”和 DIY 项目中最流行的频段,因为 MIFARE 卡和NFC(近场通信)技术就位于该频段,许多手机都使用这种技术进行非接触式支付。

高频系统在金属附近以及中高湿度环境下均能良好工作,在理想条件下,其有效范围通常为几厘米到一米左右。数据传输速率虽然不高,但足以满足身份识别、访问和小规模数据传输等应用需求。许多全球标准都基于高频技术,从而促进了设备和卡的互操作性。

超高频(UHF)射频识别系统

与此相反的是超高频(UHF)系统,其传输距离从几厘米到20多米不等。当需要快速远距离读取大量标签时,例如仓库库存管理、活动现场人数统计或运动员冲过终点线计时,超高频系统是理想之选。

缺点是波长较短,信号衰减更大,穿透金属和水的能力也较弱。即便如此,它们仍广泛应用于收费系统、停车场门禁控制和大规模物流追踪。

RC522 RFID模块:特性和引脚

对于 Arduino 项目而言,最常用的读卡器之一是基于 NXP MFRC522 芯片的 RC522。它是一款价格实惠且应用广泛的模块,工作频率高达 13,56 MHz,支持 MIFARE 卡,并允许对兼容的标签进行读写操作。

它通常以套装形式出售,套装内包含读卡器、信用卡和RFID钥匙扣。这些卡通常是1K或4K的MIFARE Classic卡,这是交通运输、门禁控制和低成本解决方案中非常流行的标准。RC522产生高频电磁场,实际有效范围约为3-5厘米,理论上可以更远一些。

在与微控制器通信方面,RC522 主要通过SPI(串行外设接口)集成,支持高达 10 Mbps 的速度。它也支持 I2C 和 UART,但由于 SPI 在这种情况下速度更快、更简单,因此大多数 Arduino 项目都使用 SPI。

该模块的电气工作电压范围为 2,5V 至 3,3V。电路板上通常会有一个清晰标记的 VCC 引脚,用于连接 3,3V 电源。切勿直接使用 5V 电源供电,否则可能会损坏模块。值得一提的是,该模块的逻辑电平通常可以承受 5V 电压,因此在进行基本测试时,无需电平转换器即可将其连接到 Arduino UNO 的数字引脚。不过,在专业设计中,建议对电平进行转换。

RC522模块的引脚连接

典型的RC522包含8个与微控制器连接引脚:

  • VCC电源电压介于 2,5V 和 3,3V 之间。
  • RST:复位引脚;允许通过将电平设置为 LOW/HIGH 来关闭和重新启动模块。
  • GND地球的质量或参考物。
  • IRQ:中断引脚,当标签进入读卡器区域时,可以向微控制器发出警报。
  • MISO / SCL / TX多功能引脚;例如 SPI 中的 MISO、I2C 中的 SCL 或 UART 中的 TX。
  • 摩西:SPI 中主设备到从设备的输出数据线。
  • SCK:SPI接口时钟。
  • SS / SDA / RX:SPI 中的从机选择引脚,I2C 中的 SDA 或 UART 中的 RX。

在 Arduino UNO 和其他基于 ATmega328P 的开发板上,SPI 引脚已由硬件定义,因此使用 SPI 的典型连接图如下:

  • VCC → 来自 Arduino 的 3,3V 电压。
  • GND → Arduino GND。
  • SCK → UNO/Nano 上的第 13 引脚。
  • 摩西 → UNO/Nano 上的第 11 引脚。
  • 味噌 → UNO/Nano 上的第 12 引脚。
  • SS(基督复临安息日会) → 引脚 10(或您选择的 SS 引脚,但您必须在代码中指定它)。
  • RST → 例如,Arduino 引脚 9。
  • IRQ → 可选,如果未使用中断,则可以不连接。

在 Arduino Mega、Leonardo 或 Micro 等开发板上,SPI 线可能位于不同的引脚或 ICSP 连接器上,因此在进行任何接线之前,务必查看官方文档中的等效表。

安装 MFRC522 库和基本标签读取

虽然 MFRC522 可以从头开始编程,但其内部通信相当复杂,因此通常的做法是使用Miguel Balboa 开发的库,该库可在 GitHub 和 Arduino IDE 的库管理器中找到。该库封装了初始化读卡器、检测卡片、验证扇区以及读写数据块所需的所有操作。

要从 Arduino IDE 安装它,只需打开库管理器,搜索“MFRC522”,然后选择社区维护的版本(GitHub Community)。您还需要包含 SPI 库,该库已包含在 IDE 中。

安装完成后,读取标签 UID 的典型流程(简单示例)如下:

  • 包括书店 SPI.hy MFRC522.h.
  • 定义读卡器将使用的 RST 和 SS 引脚。
  • 通过传递这些引脚来创建一个 MFRC522 对象。
  • 在 setup() 函数中,初始化 Serial、SPI 和读卡器。 PCD_Init().
  • 在 loop() 中,使用 PICC_IsNewCardPresent() 看看附近是否有卡片 PICC_ReadCardSerial() 读取您的基本数据。
  • 使用以下方式访问 UID mfrc522.uid.uidByte 并使用 mfrc522.uid.size 来设置大小。
  • 致电结束与唱片公司的沟通。 PICC_HaltA().

这种类型的草图非常适合获取多张卡或钥匙扣的 UID并进行快速测试,例如,对于简单的访问控制,只需将读取的 UID 与授权 UID 列表进行比较即可。

MIFARE Classic 1K 卡的内存结构

RC522 通常配备的卡是MIFARE Classic 1K卡。这些卡提供 1 KB 的内存,按扇区和块进行分层组织,并具有相当特殊的密钥和权限系统,在写入任何内容之前应该了解该系统。

总内存被划分为 16 个扇区,编号从 0 到 15。每个扇区包含 4 个数据块,扇区内的数据块编号从 0 到 3。每个数据块存储16 字节的数据,即 16 个编号为 0 到 15 的位置,因此每个扇区提供 64 字节的存储空间。

每个扇区包含四个数据块,其中只有三个用于存储用户数据:每个扇区的第 0、1 和 2 块(扇区 0 除外,它具有特殊特性)。每个扇区的最后一个数据块,即第 3 块,被称为尾部数据块。它存储加密密钥和访问位,用于控制该扇区允许的操作。

在预告片中,这 16 个字节被划分如下:

  • 关键A.: 6 字节。
  • 访问条件:3 个字节,用于定义读/写权限、身份验证和密钥可见性。
  • 未使用的字节 (U):1 个未使用的字节。
  • 关键 B: 6 字节。

出厂时模块自带的卡片通常将密钥 A 和密钥 B 初始化为 FF FF FF FF FF FF,这极其不安全,因为任何了解该标准的人都可以验证并修改卡片内容。在 DIY 项目中,一种比较常见的做法是在所有扇区使用相同的密钥,但为了真正的安全,最好使用不同的密钥。

此外,第 0 扇区的第 0 个数据块比较特殊:它存储着卡的唯一标识符(在这些 MIFARE Classic 卡中通常为 4 个字节)和制造商数据。实际上,该数据块被视为只读;尝试修改它可能会永久损坏卡片。

更改扇区的钥匙 A 和钥匙 B

如果你想在 Arduino 和 RC522 项目中有效地使用 MIFARE 卡,首先应该做的就是更改默认密钥。这样可以防止任何拥有读卡器和标准库的人未经授权篡改你的卡。

更新特定扇区(例如,扇区 15)密钥的基本思路如下:

  • 在代码中定义当前键(如果未更改,则使用出厂默认值)。
  • 确定您希望在该领域使用的新关键词 A 和关键词 B。
  • 计算该扇区的拖车区块编号,即 扇区 * 4 + 3 (适用于第 15 区,第 63 街区)。
  • 首先使用当前密钥 A 进行身份验证 PCD_Authenticate() 关于拖车模块。
  • 阅读预告片部分 MIFARE_Read() 获取您的内容。
  • 修改缓冲区中与新键对应的字节。
  • 如有必要,请再次进行身份验证(例如,使用密钥 B)。
  • 写入更新后的尾部代码块 MIFARE_Write().

在此过程中,务必在操作完成前不要将卡从读卡器中移开,因为中断对尾部块的写入可能会导致该扇区无法访问。密钥更改后,您还需要更新 Arduino 代码,以便在将来对该扇区进行操作时使用这些新密钥。

阅读和写作模块:模拟交通卡

MIFARE Classic 读写功能的一个很好的应用示例是模拟可充值公共交通卡的行为。原理很简单:卡片在一个特定的区块中存储若干行程,系统允许您加载行程(充值)或使用这些行程(上车或上电车时进行验证)。

为此,例如,可以将第 15 扇区预留用于用户数据,并使用其中的一个数据块(例如,第 60 块)来存储行程计数器。可用行程数存储在该数据块的第 0 个字节中。该数据块的其余字节可以用于其他数据,也可以留空。

重新加载部分的典型代码流程如下:

  • 确定 图A和图B 现行保护相关行业的法规(例如,我们在上一步中修改的法规)。
  • 定义扇区号、数据块(60)和尾部块(63)。
  • 声明一个 16 字节数组(blockData),其中第一个字节表示行程次数。
  • 每次将卡片靠近读卡器时, 读取第 60 块 使用 MIFARE_Read() 获取当前行程。
  • 将充电次数(例如 10 次)加到读取的值上。
  • 更新数据。根据新的行程数量设置路段。
  • 使用密钥 A 对相应的尾部代码块进行身份验证。
  • 用以下方式写入第 60 块 MIFARE_Write().
  • 请再次阅读以确认该值已正确更新。

对于行程消耗部分(公交车上的验证),代码几乎完全相同,只是计数器不是加一,而是减一。减一之前,它会检查读取的值是否为零:如果没有剩余行程,则拒绝访问并提示用户重新加载。如果计数器大于零,则减一,重写该代码块,并在屏幕上显示剩余行程数。

在这两种情况下,正确处理 MFRC522 库函数的返回码(例如,身份验证或写入错误)非常重要,并且始终在每个周期结束时使用 PCD_StopCrypto1() 停止加密通信,并使用 PICC_HaltA() 停止卡本身的加密通信。

基于UID的简单访问控制

另一个使用 RC522 和 Arduino 的经典项目是基本的门禁系统,它根据所展示电路板的 UID 来决定是否允许进入。这种方法不使用电路板的内部存储器,而只使用其唯一标识符,因此安全性相当有限,但它可以作为一个简单的示例。

通常的做法是:

  • 使用基本库函数(PICC_IsNewCardPresent、PICC_ReadCardSerial 等)读取卡 UID。
  • 将读取到的 UID 的字节复制到临时数组(例如 ActualUID)。
  • 在代码中定义几个数组,其中包含已授权卡的 UID(例如,User1、User2)。
  • 创建一个字节数组比较函数,该函数返回 如果两者相同,则为真。.
  • 将 ActualUID 与每个授权的 UID 进行比较,如果存在匹配项,则激活数字输出、显示“访问已授予”消息或激活电子锁。
  • 如果与任何匹配项都不匹配,则显示“访问被拒绝”并保持系统关闭。

在实际环境中,这种系统容易受到标签克隆攻击,因为许多廉价读卡器允许复制或模拟UID。为了提高安全性,需要使用卡的内部存储器、自定义密钥,以及可能比MIFARE Classic更强大的加密机制——MIFARE Classic的安全性目前备受质疑。即便如此,它仍然是学习读卡工作流程以及如何与物理执行器集成的绝佳教学示例。

通过以上内容,您现在已经牢固掌握了RFID的基本概念,了解不同频段的特性,了解MIFARE Classic 1K卡的内部工作原理,掌握了RC522模块与Arduino的基本连接和使用方法,并且详细了解了如何读写模块来创建实际应用系统,例如门禁系统或交通卡系统。接下来,自然而然地,您可以将RFID与其他模块(例如LCD屏幕、继电器、Wi-Fi、云数据库)结合使用,并学习如何控制智能灯泡,从而构建更全面的解决方案,使其更接近您每天在商店、公共交通和非接触式支付设备中看到的专业系统。

如何在 Windows 11 中审核应用程序权限
相关文章:
如何在 Windows 11 中审核和控制应用程序权限

在 Google 中将其添加为首选来源