浏览量: 314 次浏览

RFID智能控制门禁

2020年2月2日 1 作者 Nie Hen

使用RFID射频设备 arduino pro mini 继电器 电磁锁 实现的控制门禁
下面介绍RFID使用方法 以及配合 继电器 电磁锁实现的控制系统

效果:
enter description here
enter description here
(这里我的RFID射频设备 出现了问题 非正常工作 正常情况上面的红色指示灯不亮)

RFID

非接触型IC卡,应用非常的广泛,停车场的感应币(token)、餐厅饭卡、员工识别证…主要的差别在于资料安全加密和验证的等级。

启动RFID读写器之后,读写器的天线将不停地发送电磁波,每当卡片进入此电磁场,卡片内部的线圈和电路将与此电磁场产生共振,从而获得电能

卡片所需的电力来自读写器的电磁场。

当卡片被电磁能启动(activate)之后,将等待接收与回应来自读写器的命令。微控器和Mifare读写器之间采用TTL数位讯号传递资料,为了用电波传送数位讯号,必须将数位讯号加上载波调变,Mifare的载波频率是13.56MHz。数位讯号在调变成电波之前,从读写器发送的讯号会采用米勒(Miller)编码,而从卡片发出讯息则经过曼彻斯特(Manchester)编码。读写器在操作卡片时,都会经过三次双向认证,互相验证使用的合法性,而且通讯过程中的所有数据都经过加密,以确保安全。

使用arduino

enter description here
enter description here
库文件 GitHub链接

若不使用程式库,我们需要详阅MFRC522晶片的规格书,了解读写器、卡片和微控制器之间的数据通讯流程,以及晶片内部的暂存器的指令位址,才能动手撰写程式。

基础函数
PCD_Init():初始化MFRC522读卡机模组
PICC_IsNewCardPresent():是否感应到新的卡片
. PICC_ReadCardSerial():读取卡片的资料
PICC_GetType():取得卡片类型
PICC_GetTypeName():取得卡片类型名称
每张Mifare卡片都有个唯一的ID(unique identifier,简称UID),当读写机读取到卡片的资料之后,UID的长度和内容,可从底下两个属性值取得:

uid.size:包含UID的长度
uid.uidByte:包含UID码的阵列

读取UID码

使用示例代码

#include <SPI.h>
#include <MFRC522.h>     // 引用程式庫

#define RST_PIN      A0        // 讀卡機的重置腳位
#define SS_PIN       10        // 晶片選擇腳位

MFRC522 mfrc522(SS_PIN, RST_PIN);  // 建立MFRC522物件

void setup() {
  Serial.begin(9600);
  Serial.println("RFID reader is ready!");

  SPI.begin();
  mfrc522.PCD_Init();   // 初始化MFRC522讀卡機模組
}

void loop() {
    // 確認是否有新卡片
    if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
      byte *id = mfrc522.uid.uidByte;   // 取得卡片的UID
      byte idSize = mfrc522.uid.size;   // 取得UID的長度

      Serial.print("PICC type: ");      // 顯示卡片類型
      // 根據卡片回應的SAK值(mfrc522.uid.sak)判斷卡片類型
      MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
      Serial.println(mfrc522.PICC_GetTypeName(piccType));

      Serial.print("UID Size: ");       // 顯示卡片的UID長度值
      Serial.println(idSize);

      for (byte i = 0; i < idSize; i++) {  // 逐一顯示UID碼
        Serial.print("id[");
        Serial.print(i);
        Serial.print("]: ");
        Serial.println(id[i], HEX);       // 以16進位顯示UID值
      }
      Serial.println();

      mfrc522.PICC_HaltA();  // 卡片停止模式
    } 
}

enter description here
图中的id 会用到

参考

注意这个设备工作在高频 因此容易受到一些因素影响

继电器:

继电器有一个输入回路,一般接低压电源,有一个输出回路,一般接高压电源。
输入回路中有一个电磁铁线圈,当输入回路有电流通过,电磁铁产生磁力,吸力使输出回路的触点接通,则输出回路导电(通)。
当输入回路无电流通过,电磁铁失去磁力,输出回路的触点弹回原位,断开,则输出回路断电(断)。
enter description here
继电器有三个接线口(图中0, 1, 2),用电表量一下,0和1接线口之间是通的(常闭),0和2接线口之间是不通的(常开)
看继电器上的标注:输出为10A 250VAC(即: 支持最高250V交流电压, 10A电流),或 10A 30VDC(即: 支持最高30V直流电压, 10A电流)

NC为继电器常闭端,COM为继电器公共端,NO为继电器常开端

工作室继电器类型
enter description here
参考
参考

电磁开关
我们使用的电磁开关目前无法进行长时间的和继电器长时间连接
在控制电磁开关打开两秒后 控制电磁开关关闭。
(使用的电磁开关不能和继电器同时接上去,电磁开关要另外接线)
enter description here

esp控制继电器
enter description here
使用GPIO0 为信号引脚
输入电压为5v 如果要读取信号需要再连线到TX上面 使用GPIO3为输入
(使用GPIO1 和GPIO3 作为输入时需要将代码里面的Sear给关掉)
使用GPIO3来检测arduino的GPIO2电位
如果是高电位 发信号控制继电器打开电磁开关
如果是低电位 则不需要管

参考B站视频链接

连接线路控制

enter description here
其中继电器 信号引脚使用GPIO2
红灯使用GPIO3
绿灯使用GPIO4
当可以通过时 给GPIO2高电位 不能通过时低电位

先读取一下卡的ID 获取到之后 放入到代码中进行判断
如果是对的ID卡 绿灯亮 电磁锁打开
如果是错的ID卡 红灯亮 电磁锁关
所有的亮 与开 3秒后都会关闭

完整代码

#include <SPI.h>
#include <MFRC522.h> 
#define SS_PIN 10 
#define RST_PIN 9
int mSwitch = 2 ; int LEDRed = 3 ; int LEDGreen = 4 ;//设定电磁阀开关及红绿灯Pin值
MFRC522 mfrc522 ( SS_PIN , RST_PIN ); //建立MFRC522.   
void setup () { 
  pinMode ( LEDRed , OUTPUT ); 
  pinMode ( LEDGreen , OUTPUT ); 
  pinMode ( mSwitch , OUTPUT );
  Serial . begin ( 9600 ); //设定串列通讯速率
  SPI . begin (); //设定SPI bus 
  mfrc522 . PCD_Init (); //设定MFRC522 
  Serial . println ( " Put your card close to the reader... " );
  Serial . println (); 
  } 
  void loop () { 
  digitalWrite ( LEDGreen , LOW ); 
  digitalWrite ( LEDRed , LOW ); 
  digitalWrite ( mSwitch , LOW ); 
  if ( ! mfrc522 . PICC_IsNewCardPresent ()) { return ; } //
  if ( ! mfrc522 . PICC_ReadCardSerial ()) { return ; } //Show UID on serial monitor 
  Serial.print ( "Card No. :" 
  ) ; 
  String content = "" ; 
  byte letter ; 
  for ( byte i = 0 ; i < mfrc522 . uid . size ; i ++) 
  { 
    Serial . print ( mfrc522 . uid . uidByte [ i ] < 0x10 ? " 0" : " " ); 
    Serial . print ( mfrc522 . uid . uidByte [ i ], HEX ); 
     content . concat ( String ( mfrc522 . uid . uidByte [ i ] < 0x10 ? " 0" : " " )); 
    content . concat ( String ( mfrc522 . uid . uidByte [ i ], HEX ));
}
Serial . println (); 
Serial . print ( " Message : " ); 
content . toUpperCase ();      
  //需要改成可通行的卡号
  if ( content . substring ( 1 ) == "FA 91 83 08" ) {
      Serial . println ( " Pass... " ); 
      Serial . println (); //亮绿灯,电磁阀开
        digitalWrite ( LEDGreen , HIGH ); 
        digitalWrite ( LEDRed , LOW ); 
        digitalWrite ( mSwitch , HIGH ); 
        delay ( 3000 ); 
    }
  else { Serial . println ( " Stop..." ); //亮红灯,电磁阀关
    digitalWrite ( LEDGreen , LOW ); 
    digitalWrite ( LEDRed , HIGH ); 
    digitalWrite ( mSwitch , LOW ); 
    delay ( 3000 ); 
    }
    }