RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)

2022-08-261.7万
AI 快速预览详细 收起
本文介绍了RC522 RFID模块的上手教程,从焊接排针到连接Arduino Uno,再到烧录示例代码。文章详细说明了各引脚的定义及连接方式,帮助初学者快速掌握RFID模块的基本使用方法。通过一步步操作,读者可以轻松实现读取卡片信息的功能。

  近期入手了一套 RC522 的 RFID 模块,现在把我近期把玩这个模块的经历分享给大家,大家可以参照这个过程,上手这个模块的玩法。



RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)图1

  刚到手的 RFID 模块与排针是分开的,需要自己焊上,焊什么的不用多说了吧,来这看贴文的应该都要会这个技能。选择焊直排针还是弧排针就看自己的需求了。

  RC522 RFID 的板子大概都是下面这个样子的。



RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)图2

  翻出吃灰已久的焊枪,一番操作后排针就焊上了,下面是找了一张已经焊好的板子的图。



RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)图3

  焊接的地方有一排引脚说明。我查了相关资料,下面整理出来各引脚的定义说明。

SDA SCK MOSI MISO IRQ GND RST 3.3V
选择设备 时钟信号 主出从入(数据) 主入从出(数据) 中断 接地 置位 电源

  接下来将 RC522 与 Arduino 连接,以下使用 Arduino Uno 进行连接。连接的对照表格示意如下:

MFRC522针脚 Arduino Uno 针脚
3.3V 3.3V
GND GND
RST 9
SDA/SS 10
MOSI 11
MISO 12
SCK 13

  范例需要使用到 MFRC522 的库,我们可以在库管理器中搜索到这个库,安装即可。



RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)图4

  库文件的来源:https://github.com/miguelbalboa/rfid

  安装完成后,在 Arduino IDE 菜单栏中选择 文件 - 示例 -  第三方示例 - MFRC522 - DumpInfo  打开示例。

  将 Arduino 连接至电脑,配置开发板选项为 Arduino Uno



RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)图5

  端口是否已选择 Arduino Uno 所在的端口。



RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)图6

  点击烧录按钮,将程序烧录至 Arduino 开发板中。

  打开串口监视器,查看运行情况。这个时候可以把卡片放到RFID模块上,看到读取的信息。



RC522 RFID 模块上手,由浅入深,探索一下整合(持续更新)图7

  通过上述过程,我们已经调试测试了 MFRC522 模块,接下来还会有更多精彩的使用方法与整合运用方式。后续会在本贴陆续更新,请大家持续关注。

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(1)
IsoFace爱招飞
IsoFace爱招飞
作者

[md]  前面使用了 Arduino 来连接 MFRC522 ,现在我打算用 ESP8266 来试一下,当然我还要加上亿点点内容,再加一块显示屏,再加两个继电器,再加两个 LED 发光二极管指示灯。
  下面我把需要用到的零件列一下,方便制作收集:
| 序号 | 零件名称 | 数量 |
| ---- | ----------------------------------- | -------------------------- |
| 1 | NodeMCU ESP8266 Lua WIFI V3 开发板 | 1 |
| 2 | 2 路 5V/12V 继电器模块 高低电位触发 | 1 |
| 3 | MFRC-522 RC522 RFID IC 卡感应 附白卡 | 1 |
| 4 | I2C LCD1602 液晶显示屏 | 1 |
| 5 | LED 发光二极管 | 红色、绿色各 1 个,共计 2 个 |
| 6 | 220Ω 电阻 | 2 |
| 7 | 蜂鸣器模块 | 1 |
  接下来,就可以准备开始玩一波了!
  首先要准备将各零件连接起来,连接完成后的图示就是下面显示的这样子:[/md]

[md]  连接连好了,Arduino 代码在哪里?别急,马上给你。
  在使用以下代码前,请先下载并配置以下的库。
* ESP8266开发板的专用库。
Arduino IDE 安装完成以后,进入首选项(Preferences),找到附加开发板管理器地址(Additional Board Manager URLs),并在其后添加如下信息:http://arduino.esp8266.com/stable/package_esp8266com_index.json[/md]

[md]  保存后重启 Arduino IDE,点击菜单栏 工具 - 开发板 - 开发板管理器,找到 `esp8266` 安装即可。[/md]

[md]  然后点击 `工具-开发板-ESP8266` 在目录中选择对应的型号。这样开发板就切换完成了。这个示例使用的代码如下:
```C
//购买之 RFID-522 脚位顺序
//RFID脚位 NodeMCU脚位
//MISO GPIO12 D6
//SCK GPIO14 D5
//SS(SDA) GPIO4 D2 有的会连 D8 配合 LCD 使用改为 D4
//MOSI GPIO13 D7
//GND
//3.3V
//RST GPIO5 D1 配合 LCD 使用改为 D3
//接无源蜂鸣器,负极接地,信号接 D8 控制输出 3V 或 0V 控制生成长短哔声
//NodeMCU 开发板偏好设置如下
// http://arduino.esp8266.com/stable/package_esp8266com_index.json
//
//LCD脚位接法 NodeMCU
//GND GND
//VSS Vin/5V
//SCL D1
//SDA D2
//蜂鸣器发出声音
//需要pitches文件
//https://gitee.com/isoface-iot/Smart/blob/master/demo/iot/s-eq-dem-2209_rfid_mqtt_relay/esp8266_ino/pitches.h
#include "pitches.h"
//创建要发音的音色数组
int Music[25] = {
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4,
NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5,
NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5
};
#include
#include
#include
// WiFi 声明 ============================================================================================================================
//https://github.com/prampec/IotWebConf/tree/v2.x.x
#include
const char thingName[] = "Relay"; // 开发板当 AP 使用时,所采用的名称,类似 SSID.
const char wifiInitialApPassword[] = "66666666"; // 开发板当 AP 使用时,连接所需之密码.
// 在运行时使用浏览器修改设置,用户名称为 admin,密码就是上行设置值
#define STRING_LEN 128
#define NUMBER_LEN 32
#define CONFIG_VERSION "Relay01" // 配置特定密钥。如果更改了配置结构,就需修改该值.
// CONFIG_PIN 重新设置脚位,例如设 D0 脚位,在开发板启动时 与GND 脚位连接,将会重新进行,(用于密码遗忘)
#define CONFIG_PIN D0
// 状态指示器针脚,首先它会亮起(保持低电平),在Wifi连接上它会闪铄,当连接到Wifi时,它将关闭(保持高电平)。
#define STATUS_PIN LED_BUILTIN
// MQTT 声明 ============================================================================================================================
// pubsubclient MQTT 程序库网址 https://github.com/knolleary/pubsubclient
#include
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
char hexStr[NUMBER_LEN]; // 设置 RFID 卡号
char mapic[STRING_LEN]; // 设置该机 MQTT主题名称
bool wifiready = false;
// 声明回传的方法
void configSaved();
boolean formValidator();
boolean connectAp(const char* apName, const char* password);
void connectWifi(const char* ssid, const char* password);
void charToStringL(const char S[], String &D); //将 char[] 转为 String 自订函数
DNSServer dnsServer;
WebServer server(80);
HTTPUpdateServer httpUpdater;
char mqttServerValue[STRING_LEN];
char mqttUserNameValue[STRING_LEN];
char mqttUserPasswordValue[STRING_LEN];
char mqttTopicValue[STRING_LEN];
char ipAddressValue[STRING_LEN];
char gatewayValue[STRING_LEN];
char netmaskValue[STRING_LEN];
IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION);
IotWebConfParameter ipAddressParam = IotWebConfParameter("IP位址", "ipAddress", ipAddressValue, STRING_LEN, "text", NULL, "192.168.3.124");
IotWebConfParameter gatewayParam = IotWebConfParameter("网关", "gateway", gatewayValue, STRING_LEN, "text", NULL, "192.168.3.1");
IotWebConfParameter netmaskParam = IotWebConfParameter("子网掩码", "netmask", netmaskValue, STRING_LEN, "text", NULL, "255.255.255.0");
IotWebConfParameter mqttServerParam = IotWebConfParameter("MQTT 服务器-", "mqttServer", mqttServerValue, STRING_LEN);
IotWebConfParameter mqttUserNameParam = IotWebConfParameter("MQTT 用户", "mqttUser", mqttUserNameValue, STRING_LEN);
IotWebConfParameter mqttUserPasswordParam = IotWebConfParameter("MQTT 密码", "mqttPass", mqttUserPasswordValue, STRING_LEN, "password");
IotWebConfParameter mqttTopicParam = IotWebConfParameter("MQTT 主题", "mqttTopic", mqttTopicValue, STRING_LEN);
// 开发板固定 发送的主题 mqttTopicValue/uid 这是RFID卡号
// 开发板固定 接收的主题 mqttTopicValue/inp 自行决定发送之消息 例如 单号 货号 产品名称 可以是中文 (LCD无法显示中文)
// 开发板固定 接收的主题 mqttTopicValue/re01 =1 开启 1 号继电器 =0 关闭 1 号继电器
// 开发板固定 接收的主题 mqttTopicValue/re02 =1 开启 2 号继电器 =0 关闭 2 号继电器
IPAddress ipAddress;
IPAddress gateway;
IPAddress netmask;
// LCD1602 声明 =============================================================================================================================
//https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
#include
#include //引用I2C库
LiquidCrystal_I2C lcd(0x27, 16, 2); //设备位址,这里的位址是0x3F,一般是0x20,或者0x27,具体看模块手册
// RFID 读卡机 声明 ===========================================================================================================================
#include
#include "MFRC522.h"
#define RST_PIN D3 // RFID 读卡机的重置脚位 RC522
#define SS_PIN D4 //RFID 读卡机的芯片选择脚位
MFRC522 mfrc522(SS_PIN, RST_PIN); // 创建MFRC522物件
//============================================================================================================================================
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Starting up...");
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
Serial.println("RFID ready");
// WiFi 设置 =============================================================================================================================
iotWebConf.setStatusPin(STATUS_PIN);
iotWebConf.setConfigPin(CONFIG_PIN);
iotWebConf.addParameter(&ipAddressParam);
iotWebConf.addParameter(&gatewayParam);
iotWebConf.addParameter(&netmaskParam);
iotWebConf.addParameter(&mqttServerParam);
iotWebConf.addParameter(&mqttUserNameParam);
iotWebConf.addParameter(&mqttUserPasswordParam);
iotWebConf.addParameter(&mqttTopicParam);
iotWebConf.setConfigSavedCallback(&configSaved); // 回传副程序 - 保存设置
iotWebConf.setFormValidator(&formValidator); // 回传副程序 - 检查输入参数是否有错
iotWebConf.setApConnectionHandler(&connectAp); //启动系统缺省 192.168.4.1 之AP 造成无法引入设置之IP
iotWebConf.setWifiConnectionHandler(&connectWifi); // 回传副程序 - 启动 WiFi 副程序名称 connectWifi
// -- Initializing the configuration.
boolean validConfig = iotWebConf.init();
if (!validConfig) {
mqttServerValue[0] = '\0';
mqttUserNameValue[0] = '\0';
mqttUserPasswordValue[0] = '\0';
}
else
{
strcpy(mapic, mqttTopicValue);
}
// -- 在Web服务器上设置必需的URL处理进程.
server.on("/", handleRoot);
server.on("/config", [] { iotWebConf.handleConfig(); });
server.onNotFound([]() {
iotWebConf.handleNotFound();
});
//设置 MQTT ===================================================================================================
// client.setServer("192.168.3.125", 1883);
client.setServer(mqttServerValue, 1883);
client.setCallback(callback);
if (client.connected()) {
char mymapic[STRING_LEN];
strcpy(mymapic, mapic); // strcpy(复制目的字符串,来源字符串
strcat(mymapic, "/#");
client.subscribe(mymapic);
}
//设置蜂鸣器===================================================================================================
pinMode(D8, OUTPUT); //设置 D8 脚位用于控制蜂鸣
lcd.begin(); // 初始化LCD
lcd.backlight(); //设置LCD背景等亮
//设置继电器===================================================================================================
pinMode(D9, OUTPUT); //设置继电器使用 D9 D10 脚位为输出状态
pinMode(D10, OUTPUT);
digitalWrite(D9,HIGH);
digitalWrite(D10,HIGH);
}
void loop() {
// WiFI 运行 ============================================================================================================================
iotWebConf.doLoop(); // -- 尽可能频繁地调用doLoop.
// MQTT 接收主题(单号) ========================================================================================================================
client.loop();
if (client.connected()) {
// RFID 运行 ============================================================================================================================
if ( ! mfrc522.PICC_IsNewCardPresent()) { // 检查是否为新卡
delay(50);
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
delay(50);
return;
}
else
{
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
// 转换卡号以十六进位的字符串显示
to_hex(mfrc522.uid.uidByte, mfrc522.uid.size);
// 蜂鸣器响声
beep(23); //不可大于 24
//发送卡号到 MQTT Broker
char pubmapic[STRING_LEN];
strcpy (pubmapic, mapic);
strcat(pubmapic, "/uid");
Serial.println(pubmapic);
// MQTT 发送主题(卡号) ========================================================================================================================
Serial.println("connected");
Serial.println(pubmapic);
client.publish(pubmapic, hexStr);
delay(1500); //得暂停 要不然回圈会很快扫卡 读好几次
}
}
else
{
if (wifiready) {
reconnect();
}
}
/** 此段程序取消 因为会紧跟着显示 hello Word 信号数
将来在发送大量字符串时可以参考使用
long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, 50, "hello world #%ld", value);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("outTopic", msg);
}
**/
}
// RFID 副程序 =============================================================================================================================
void beep(int len) {
for (int i = 0; i < len; i++) {
tone(D8, Music[i], 100); // 从第8Pin发声,发出100ms的声音
//delay(200);
}
}
// -----------------------------------------------------------------------------------------------------------------------------------------------
// 转换卡号以十六进位的字符串显示
void to_hex(byte *buffer, byte buffSize) {
char* s = &hexStr[0];
for (byte i = 0; i < buffSize; i++) {
snprintf(s, 3, "%02x", buffer[i]);
s += 2;
}
hexStr[buffSize * 2] = 0;
Serial.println(hexStr);
lcd.clear(); //显示清除
lcd.setCursor(0, 0); //设置显示行列数
lcd.print(F("Card UID:")); //输出字符到LCD1602上
lcd.setCursor(0, 1);
lcd.print(hexStr);
}
// WiFi 副程序 =============================================================================================================================
void handleRoot() //处理“/”路径的Web请求.
{
// -- 让IotWebConf测试并处理强制门户请求.
if (iotWebConf.handleCaptivePortal())
{
// -- 主要的需 求已经提供.
return;
}
String s = "";
s += "网络设置作业您好!";
s += "
    ";
    s += "
  • 固定 IP 设置: ";
    s += ipAddressValue;
    s += "
";
s += "请至设置页面 请修改.";
s += "\n";
server.send(200, "text/html", s);
}
// -----------------------------------------------------------------------------------------------------------------------------------------------
void configSaved()
{
Serial.println("设置即将更新.");
}
// -----------------------------------------------------------------------------------------------------------------------------------------------
boolean formValidator()
{
Serial.println("Validating form.");
boolean valid = true;
if (!ipAddress.fromString(server.arg(ipAddressParam.getId())))
{
ipAddressParam.errorMessage = "请提供正确的 IP 位址!";
valid = false;
}
if (!netmask.fromString(server.arg(netmaskParam.getId())))
{
netmaskParam.errorMessage = "请提供正确的子网掩码!";
valid = false;
}
if (!gateway.fromString(server.arg(gatewayParam.getId())))
{
gatewayParam.errorMessage = "请提供正确的网关位址!";
valid = false;
}
return valid;
}
// -----------------------------------------------------------------------------------------------------------------------------------------------
boolean connectAp(const char* apName, const char* password)
{
// -- 自定义AP设置
return WiFi.softAP(apName, password, 4);
}
// -----------------------------------------------------------------------------------------------------------------------------------------------
void connectWifi(const char* ssid, const char* password)
{
ipAddress.fromString(String(ipAddressValue));
netmask.fromString(String(netmaskValue));
gateway.fromString(String(gatewayValue));
if (!WiFi.config(ipAddress, gateway, netmask)) {
Serial.println("WiFi 连接失败 请检查网络设置");
}
wifiready = true;
Serial.print("ip: ");
Serial.println(ipAddress);
Serial.print("gw: ");
Serial.println(gateway);
Serial.print("net: ");
Serial.println(netmask);
WiFi.begin(ssid, password);
}
// MQTT 副程序 =============================================================================================================================
// 接收主题後调用进程
void callback(char* topic, byte* payload, unsigned int length) {
String mapre01; // 预定收到的主题1 /re01
String mapre02; // 预定收到的主题2 /re02
String mapre03; // 预定收到的主题3 /inp
String mappu01; // 预定发送的主题3 /UID
String mapres; // 实际从 MQTT Broker 接收到的主题
String information; // 实际从 MQTT Broker 接收到的主题内容
String RelayOpen="1";
//将 char[] 转为 String charToStringL(需转换的 Char数组, 转换後的 String)
charToStringL(mapic, mapre01); //用户自设的主题
charToStringL(mapic, mapre02);
charToStringL(mapic, mapre03);
charToStringL(mapic, mappu01);
mapre01 = mapre01 + "/re01"; //1号继电器 的主题
mapre02 = mapre02 + "/re02"; //2号继电器 的主题息
mapre03 = mapre03 + "/inp"; //其他收到的主题
mappu01 = mappu01 + "/uid"; //发布的主题
charToStringL(topic, mapres); //实际从 MQTT Broker 接收到的主题
for (int i = 0; i < length; i++) { //读取收到的字符串
information = information + (char)payload[i];
}
if (mapres != mappu01) { // 不显示发布的主题
Serial.print("接收消息 " + mapres + " [");
Serial.print(information);
Serial.print("] ");
lcd.clear(); // LCD 显示清除
lcd.setCursor(0, 0); // 设置显示行列数
lcd.print("Message:");
lcd.setCursor(0, 1);
beep(15); // 蜂鸣器响声 24
beep(15);
}
if (mapres == mapre01) {
if (information == RelayOpen) {
Serial.println("Open Relay-1");
lcd.print("Open Relay-1"); //输出消息到 LCD1602 显示
digitalWrite(D9,LOW);
}
else {
Serial.println("Close Relay-1");
lcd.print("Close Relay-1");
digitalWrite(D9,HIGH);
}
}
if (mapres == mapre02) {
if (information == RelayOpen) {
Serial.println("Open Relay-2");
lcd.print("Open Relay-2");
digitalWrite(D10,LOW);
}
else {
Serial.println("Close Relay-2");
lcd.print("Close Relay-2");
digitalWrite(D10,HIGH);
}
}
if (mapres == mapre03) {
lcd.print(information);
}
/**
digitalWrite(D9,LOW);
delay(200);
digitalWrite(D10,LOW);
delay(2000);
digitalWrite(D9,HIGH);
delay(200);
digitalWrite(D10,HIGH);
delay(1000);
**/
Serial.println();
// 收到消息的第一个字符 开发板上 LED 亮灯
if ((char)payload[0] == '1') {
digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is active low on the ESP-01)
} else {
digitalWrite(BUILTIN_LED, HIGH); // 关闭 LED 灯
}
}
void reconnect() {
// 一直循环直到连上 MQTT Broker
while (!client.connected()) {
Serial.print("正在连接 MQTT Broker...");
// 随机生成 client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// 开始进行连接
lcd.clear(); // LCD 显示清除
lcd.setCursor(0, 0); // 设置显示行列数
if (client.connect(clientId.c_str(), mqttUserNameValue, mqttUserPasswordValue)) {
Serial.println("MQTT Broker 已经连接上");
char mymapic[STRING_LEN];
strcpy(mymapic, mapic); // strcpy(复制目的字符串,来源字符串
strcat(mymapic, "/#");
client.subscribe(mymapic);
lcd.print("RFID Ready:"); // 正确开机 在LCD 显示消息
} else {
Serial.print("连接失败, rc=");
Serial.print(client.state());
Serial.println("五秒钟之后再连接");
lcd.print("failed, rc="); // 在LCD 显示错误消息
lcd.print(client.state());
lcd.setCursor(0, 1);
lcd.print("try again in 5 seconds... ");
delay(5000);
}
}
}
//将 char[] 转为 String 自订函数
void charToStringL(const char S[], String & D)
{
byte at = 0;
const char *p = S;
D = "";
while (*p++) {
D.concat(S[at++]);
}
}
```
  刷写完成后,重启 ESP8266 ,此时 WiFi 是以 AP 模式运行的,我们用手机或者电脑连接到SSID为 `Relay` 的无限网络,使用浏览器访问 ,打开网页页面,点击设置页面,进入设置的页面程序。根据页面要求设置对应的连接项或者设置项,其中的 MQTT 相关的设置项是为后续的连接作铺垫的,所以测试时,也请先设置好可用的MQTT服务器。设置保存后断开连接,并重启ESP8266。
  在通电后,请先立即移除 ESP8266 针脚 TX RX 的连接,查看 LCD 屏幕的显示情况。等待 LCD 屏幕显示 `RFID Ready` 后,再将 TX RX 针脚重新接上。这个时候,可以将卡片放置于 MFRC522 的感应区,可以听到蜂鸣器的声音,同时屏幕上会显示刷卡的结果。
  到这里了,你可能会问,这个继电器怎么没用上啊?MQTT 是干什么用的?接下来还会有更新的内容,希望大家能持续关注。[/md]
- 没有更多了 -