Arduino使用RFID模块来储存卡信息实现智能门锁(MF RC522)

本文介绍了一种使用Arduino和RFID模块实现的简易门禁系统。该系统利用MFRC522芯片通过SPI通信与Arduino交互,实现了NFC卡信息的读取与验证功能。通过一个案例详细讲解了硬件连接、所需库文件及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用RFID模块实现门禁的功能 Arduino的RFID模块的使用(MF RC522)



前言

很久以前就想做一个使用NFC卡来开关门锁的小玩意,找了很多案例都没有找到合适的,网上教的人也比较少于是只能慢慢摸索,学习速度很慢,在这里我将用一个小案例来说一说Arduino的RFID模块的使用.


一、RFID是什么?

1.RFID简介

射频识别(RFID)是 Radio Frequency Identification 的缩写。

其原理为阅读器与标签之间进行非接触式的数据通信,达到识别目标的目的。RFID 的应用非常广泛,典型应用有动物晶片、汽车晶片防盗器、门禁管制、停车场管制、生产线自动化、物料管理。

具体请看百度: 射频识别技术.

2.RFID-RC522模块介绍

来看看RFID模块的样子RFID-RC522模块

二、如何使用

1.硬件部分

模块使用的是MF RC522芯片,模块与Arduino通讯方式为SPI(同步串行外设接口总线)通信,Arduino工作在主模式下,RC522工作在从模式下,在本例程中我使用的是arduino的Arduino Pro Micro开发板,如下为引脚定义,请自行核对

MFRC522 Reader/PCDArduino Uno/101Arduino MegaArduino Nano v3Arduino Leonardo/MicroArduino Pro Micro
模块的引脚PinPinPinPinPinPin
RST/ResetRST95D9RESET/ICSP-5RST
SPI SSSDA(SS)1053D101010
SPI MOSIMOSI11 / ICSP-451D11ICSP-416
SPI MISOMISO12 / ICSP-150D12ICSP-114
SPI SCKSCK13 / ICSP-352D13ICSP-315
还用到了一个按钮和三个表示状态的led灯,连接如下

和arduino的连接

2.软件部分

2.1 需要使用到的库文件

RFID-RC522的库链接: 点击进入下载.如何安装请百度。

2.2 代码段

功能为按下按钮开始储存卡的数据,绿灯常亮。再次按下退出,开始门锁功能,黄灯常亮,如果有已经储存的卡放置在读卡器前绿灯亮一下然后熄灭,反之红灯亮一下。

#include <SPI.h>
#include <MFRC522.h>


#define SS_PIN 10
#define RST_PIN 5


#define Button_Pin 4
#define yellow_Led 5
#define green_Led 6
#define red_Led 7


//按钮用的定义//
unsigned char val = 0;//变量val 存储按钮的状态
unsigned char old_val = 0;//暂存val变量的上一个时间状态
unsigned char state1=0;
unsigned char Button1=0;
unsigned char kacck=0;   //让"开始储存卡"只用一次

static int CardNumber = 0;  //卡的储存次数

MFRC522 rfid(SS_PIN, RST_PIN); 
MFRC522::MIFARE_Key key; 


byte nuidPICC[8][4];

void setup() { 
  
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  rfid.PCD_Init(); // Init MFRC522 
  rfid.PCD_SetAntennaGain(rfid.RxGain_max);

  pinMode(yellow_Led,OUTPUT);
  pinMode(green_Led,OUTPUT);
  pinMode(red_Led,OUTPUT);
  pinMode(Button_Pin,INPUT);

  blink_LED();
  digitalWrite(yellow_Led,HIGH);
  
}
 

void loop() {

    Button_Press();

   while(Button1 == 1) {
    Button_Press();
      if((Button1 == 1)&&(kacck==0)) {
    
    

    delay (10);
    kacck = 1;
    }
    if ( ! rfid.PICC_IsNewCardPresent())
     return;

    if ( ! rfid.PICC_ReadCardSerial())
    return;

    MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
 

    // 检测是否为支持的卡片
    if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
      piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
      piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
      Serial.println(F("你的卡可能不受支持"));
    }

    if (Store_CheckCard() ) {
        Serial.println(F("新的卡已经检测到了。"));
        // 将NUID存储到nuidPICC数组中
         
          for (byte i = 0; i < 4; i++) {
          nuidPICC[CardNumber][i] = rfid.uid.uidByte[i];
          }
      

        Serial.println(F("NUID:"));
        Serial.print(F("十六进制为: "));
        printHex(rfid.uid.uidByte, rfid.uid.size);
        Serial.println();

        for (byte a = 0; a < 8; a++){
          Serial.println();
          for (byte i = 0; i < 4; i++) {
          Serial.print(nuidPICC[a][i] < 0x10 ? " 0" : " ");
          Serial.print(nuidPICC[a][i],HEX);
          }
        }
        CardNumber++;
        
      }
      else Serial.println(F("已经读取过这个卡了。"));
    }
       //储存卡
 
    // 如果传感器/读卡器上没有新卡,则返回主程序。这将在空闲时保存整个进程。
  if ( ! rfid.PICC_IsNewCardPresent())
   return;

  // 验证是否已读取NUID
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  if (Checkcard2() ) {
    for (byte i = 0; i < 4; i++) {
          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i],HEX);
          
          }
        
        Serial.println(F("通过")); 
        digitalWrite(green_Led, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(500);                       // wait for a second
        digitalWrite(green_Led, LOW);    // turn the LED off by making the voltage LOW
        delay(500);  
       
        
  }
    else {
      Serial.println();
      Serial.println(F("未通过"));
        
        for (byte i = 0; i < 4; i++) {

          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i],HEX);
          }
      digitalWrite(red_Led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(500);                       // wait for a second
      digitalWrite(red_Led, LOW);    // turn the LED off by making the voltage LOW
      delay(500);     
     }


  // 停止 PICC
  rfid.PICC_HaltA();

  // 停止加密 on PCD
  rfid.PCD_StopCrypto1();

}




///闪烁灯
void blink_LED(){

  unsigned short delay_Time=40;

  for(int j=0;j<3;j++){
    for(int i=5;i<8;i++){
      digitalWrite(i, HIGH);   
      delay(delay_Time);       
      digitalWrite(i, LOW);    
      delay(delay_Time);     
    }
    for(int i=7;i>4;i--){
      digitalWrite(i, HIGH);   
      delay(delay_Time);       
      digitalWrite(i, LOW);    
      delay(delay_Time);     
    }
  }
}

//在储存卡的时候检测卡片是否储存在芯片里/
int Store_CheckCard(){
  unsigned short i=0;
  unsigned short Store_CheckCard_unm1=0;
  while(i<8)
  {
    
    for(unsigned short i1=0;i1<8;i1++)
    {
      if(rfid.uid.uidByte[0] == nuidPICC[i][0] & 
      rfid.uid.uidByte[1] == nuidPICC[i][1] & 
      rfid.uid.uidByte[2] == nuidPICC[i][2] & 
      rfid.uid.uidByte[3] == nuidPICC[i][3])
      {
        Store_CheckCard_unm1++;
      }
    i++;
    }
  }
  
    if  (Store_CheckCard_unm1 == 0){
        return 1;
        Store_CheckCard_unm1 =0;
        }
          
    else return 0;

  
}


/在读取卡的时候检测卡片是否储存在芯片里///
int Checkcard2(){
  unsigned short i=0;
  unsigned short Checkcard2_unm1=0;
  while(i<8)
  {
    
    for(unsigned short i1=0;i1<8;i1++)
    {
      if(rfid.uid.uidByte[0] == nuidPICC[i][0] & 
        rfid.uid.uidByte[1] == nuidPICC[i][1] & 
        rfid.uid.uidByte[2] == nuidPICC[i][2] & 
        rfid.uid.uidByte[3] == nuidPICC[i][3])
      {
        Checkcard2_unm1++;
      }
    i++;
    }
  }
  
    if  (Checkcard2_unm1 != 0){
        return 1;
        Checkcard2_unm1 =0;
        }
          
    else return 0;
}




按下按钮开始写入卡的UNID//
void Button_Press(){
 //按下按钮
  val = digitalRead(Button_Pin);//读取输入数值并且存储
  if((val==LOW)&&(old_val==HIGH))//检查按钮的变化情况
  {
      state1++;
  }
  if(state1==1){
  Button1 = 1;
  digitalWrite(green_Led,HIGH);
  digitalWrite(yellow_Led,LOW);
  
  
  }
  if((state1==2)||(state1==0)){
    state1=0;
    Button1 = 0;
  digitalWrite(green_Led,LOW);
  digitalWrite(yellow_Led,HIGH);
  
  
  }
  old_val=val;//val现在是旧的了,让我们暂存一下

}

/**
 * Helper routine to dump a byte array as hex values to Serial. 
 */
void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

三、如何使用

总结

博主我也是刚刚开始学习,如果有问题可以加QQ群116239571,如果我知道都会回答的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值