| 
	 
	
		在生活中,家是我们最后也是最重要的归依,原有的铜锁,越来越不安全,而且携带一堆钥匙更是不方便,许多智慧家居都已寻求更简单、方便、快速的方式来保全我们最重要的家。如果我们能够用创客神器来Arduino来保全我们最重要的家,透过RFID卡,当成一个开门的Key卡,那该有多好?所以本月我们要使用Arduino,透过简单RFID Mifare卡,建立一个安全的门锁开门利器。 
		 
			主要材料:
		 
			所需工具:
		 
			制作步骤:
		
			
				第1步:   
				电控锁一般门禁系统进出入口大部份为门,而门闭合与开合的关键装置则为锁(如下图所示),但是人力锁闭合与开合的关键装置需要透过人的开锁行为来运作,以联接门禁系统之辨识系统来闭合与开合,该『锁』必须是电力装置方能达到需求。
 所以一般都是电力控制之电控锁,方能在「开锁装置」(例如钥匙、密码、开锁卡片,或是指纹、掌纹、视网膜或声音等生物特征)辨识并判断使用者的身份正确后,启动回路通电(或断电)至电控锁开门。
			
				第2步:   
				驱动MF RC522 RFID模块MF RC522 RFID模块本身就可以读取Mifare卡片的数据,我们依照下表进行电路连接,连接MF RC522 RFID模块,进行电路组立。
 (表1)RFID门禁管制接脚表:
			
				第3步:   
				 
			
				第4步:   
				电路组立之后,依照下表之RFID门禁管制机测试程序一进行程序攥写的动作。RFID门禁管制接脚表:
			
				第5步:   
				RFID門禁管制機測試程式一(doorcontrol01)#include <LiquidCrystal.h>
 #include <SPI.h>
 
 #include <RFID.h>
 
 /* LiquidCrystal display with:
 LiquidCrystal(rs, enable, d4, d5, d6, d7)
 
 LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
 
 LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
 
 LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
 
 R/W Pin Read = LOW / Write = HIGH // if No Pin connect RW , please leave R/W Pin for Low State
 Parameters
 
 */
 LiquidCrystal lcd(8,9,10,38,40,42,44); //ok
 
 RFID rfid(53,5); //this is used for Arduino Mega 2560
 
 //RFID rfid(10,5); //this is used for Arduino UNO
 
 void setup()
 
 {
 
 Serial.begin(9600);
 
 Serial.println(“RFID Mifare Read");
 
 SPI.begin();
 
 rfid.init();
 
 // PinMode(11,OUTPUT);
 
 // digitalWrite(11,LOW);
 
 lcd.begin(20, 4);
 
 // 設定 LCD 的行列數目 (4 x 20)
 
 lcd.setCursor(0,0);
 
 // 列印 “Hello World" 訊息到 LCD 上
 
 lcd.print(“RFID Mifare Read");
 
 }
 void loop()
 
 {
 
 // 將游標設到 column 0, line 1
 
 // (注意: line 1 是第二行(row),因為是從 0 開始數起):
 
 Serial.println(millis()/1000);
 
 delay(200);
 
 if (rfid.isCard()) { //找尋卡片
 
 if (rfid.readCardSerial()) { //取得卡片的ID+CRC校驗碼
 
 //第0~3個byte:卡片ID
 
 Serial.println(" “);
 
 Serial.print(“RFID Card Number is : “);
 
 Serial.print(rfid.serNum[0],HEX);
 
 Serial.print(" , “);
 
 Serial.print(rfid.serNum[1],HEX);
 
 Serial.print(" , “);
 
 Serial.print(rfid.serNum[2],HEX);
 
 Serial.print(" , “);
 
 Serial.println(rfid.serNum[3],HEX);
 
 //第4個byte:CRC校驗位元
 
 Serial.print(“CRC is : “);
 
 Serial.println(rfid.serNum[4],HEX);
 
 lcd.setCursor(2, 1);
 
 lcd.print(rfid.serNum[0],HEX);
 
 lcd.setCursor(5, 1);
 
 lcd.print(rfid.serNum[1],HEX);
 
 lcd.setCursor(8, 1);
 
 lcd.print(rfid.serNum[2],HEX);
 
 lcd.setCursor(11, 1);
 
 lcd.print(rfid.serNum[3],HEX);
 
 
 
 }
 
 
 
 }
 
 rfid.halt(); //命令卡片進入休眠狀態
 
 delay(500); //延時0.5秒
 
 }
			
				第6步:   
				RFID卡控制开锁我们已经可以正确读取卡号号,我们加入继电器模块来控制外部电力装置开关与否,主要是将电磁锁(如图1所示)的开门开关电路,参照(表1)所示,接至继电器模块的Com与NC两接点,在正确读取到适合卡号时,启动继电器模块,使继电器模块的Com与NC两接点短路,让电磁锁(如图1所示)开门。
 由于MF RC522 RFID模块本身就可以读取Mifare卡片的数据,我们依照表1进行电路连接,连接MF RC522 RFID模块,读者依照下表之RFID门禁管制机测试程序二进行程序攥写的动作。
 
 (表 3)RFID 門禁管制機測試程式二:
 #include <LiquidCrystal.h>
 #include <SPI.h>
 
 #include <RFID.h>
 
 #include <String.h>
 
 #define openkeyPin 4
 
 int debugmode = 0;
 
 /* LiquidCrystal display with:
 LiquidCrystal(rs, enable, d4, d5, d6, d7)
 
 LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
 
 LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
 
 LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
 
 R/W Pin Read = LOW / Write = HIGH // if No Pin connect RW , please leave R/W Pin for Low State
 Parameters
 
 */
 LiquidCrystal lcd(8,9,10,38,40,42,44); //ok
 
 RFID rfid(53,5); //this is used for Arduino Mega 2560
 
 //RFID rfid(10,5); //this is used for Arduino UNO
 
 String keyno1 = String(“6AE4E616″);
 
 void setup()
 
 {
 
 Serial.begin(9600);
 
 Serial.println(“RFID Mifare Read");
 
 SPI.begin();
 
 rfid.init();
 
 pinMode(openkeyPin,OUTPUT);
 
 digitalWrite(openkeyPin,LOW);
 
 lcd.begin(20, 4);
 
 // 設定 LCD 的行列數目 (4 x 20)
 
 lcd.setCursor(0,0);
 
 // 列印 “Hello World" 訊息到 LCD 上
 
 lcd.print(“RFID Mifare Read");
 
 }
 void loop()
 
 {
 
 // 將游標設到 column 0, line 1
 
 // (注意: line 1 是第二行(row),因為是從 0 開始數起):
 
 if (rfid.isCard()) { //找尋卡片
 
 if (rfid.readCardSerial()) { //取得卡片的ID+CRC校驗碼
 
 //第0~3個byte:卡片ID
 
 Serial.println(" “);
 
 Serial.print(“RFID Card Number is : “);
 
 Serial.print(strzero(rfid.serNum[0],2,16));
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[0],HEX);
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[0],DEC);
 
 Serial.print(" , “);
 
 Serial.print(strzero(rfid.serNum[1],2,16));
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[1],HEX);
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[1],DEC);
 
 Serial.print(" , “);
 
 Serial.print(strzero(rfid.serNum[2],2,16));
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[1],HEX);
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[1],DEC);
 
 Serial.print(" , “);
 
 Serial.print(strzero(rfid.serNum[3],2,16));
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[0],HEX);
 
 Serial.print(“/");
 
 Serial.println(rfid.serNum[0],DEC);
 
 //第4個byte:CRC校驗位元
 
 Serial.print(“CRC is : “);
 
 Serial.print(strzero(rfid.serNum[4],2,16));
 
 Serial.print(“/");
 
 Serial.print(rfid.serNum[4],HEX);
 
 Serial.print(“/");
 
 Serial.println(rfid.serNum[4],DEC);
 
 lcd.setCursor(2, 1);
 
 lcd.print(strzero(rfid.serNum[0],2,16));
 
 lcd.setCursor(5, 1);
 
 lcd.print(strzero(rfid.serNum[1],2,16));
 
 lcd.setCursor(8, 1);
 
 lcd.print(strzero(rfid.serNum[2],2,16));
 
 lcd.setCursor(11, 1);
 
 lcd.print(strzero(rfid.serNum[3],2,16));
 
 lcd.setCursor(4, 2);
 
 lcd.print(getcardnumber(rfid.serNum[0],rfid.serNum[1],rfid.serNum[2],rfid.serNum[3]) );
 
 
 
 }
 
 
 
 }
 
 rfid.halt(); //命令卡片進入休眠狀態
 
 if (keyno1 == getcardnumber(rfid.serNum[0],rfid.serNum[1],rfid.serNum[2],rfid.serNum[3]))
 
 {
 
 digitalWrite(openkeyPin,HIGH);
 
 lcd.setCursor(0, 3);
 
 lcd.print(“Access Granted:Open");
 
 Serial.println(“Access Granted:Door Open");
 
 }
 
 else
 
 {
 
 digitalWrite(openkeyPin,LOW);
 
 lcd.setCursor(0, 3);
 
 lcd.print(“Access Denied:Closed");
 
 Serial.println(“Access Denied:Door Closed");
 
 }
 
 
 
 
 
 delay(500); //延時0.5秒
 
 }
 String getcardnumber(byte c1, byte c2, byte c3, byte c4)
 
 {
 
 String retstring = String(“");
 
 retstring.concat(strzero(c1,2,16));
 
 retstring.concat(strzero(c2,2,16));
 
 retstring.concat(strzero(c3,2,16));
 
 retstring.concat(strzero(c4,2,16));
 
 return retstring;
 
 }
 String strzero(long num, int len, int base)
 
 {
 
 String retstring = String(“");
 
 int ln = 1 ;
 
 int i = 0 ;
 
 char tmp[10] ;
 
 long tmpnum = num ;
 
 int tmpchr = 0 ;
 
 char hexcode[]={‘0′,’1′,’2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′,’A’,’B’,’C’,’D’,’E’,’F’} ;
 
 while (ln <= len)
 
 {
 
 tmpchr = (int)(tmpnum % base) ;
 
 tmp[ln-1] = hexcode[tmpchr] ;
 
 ln++ ;
 
 tmpnum = (long)(tmpnum/base) ;
 
 /*
 
 Serial.print(“tran :(“);
 
 Serial.print(ln);
 
 Serial.print(“)/(“);
 
 Serial.print(hexcode[tmpchr] );
 
 Serial.print(“)/(“);
 
 Serial.print(tmpchr);
 
 Serial.println(“)");
 
 */
 
 
 
 }
 
 for (i = len-1; i >= 0 ; i –)
 
 {
 
 retstring.concat(tmp[i]);
 
 }
 
 
 
 return retstring;
 
 }
 unsigned long unstrzero(String hexstr)
 
 {
 
 String chkstring ;
 
 int len = hexstr.length() ;
 
 if (debugmode == 1)
 
 {
 
 Serial.print(“String “);
 
 Serial.println(hexstr);
 
 Serial.print(“len:");
 
 Serial.println(len);
 
 }
 
 unsigned int i = 0 ;
 
 unsigned int tmp = 0 ;
 
 unsigned int tmp1 = 0 ;
 
 unsigned long tmpnum = 0 ;
 
 String hexcode = String(“0123456789ABCDEF") ;
 
 for (i = 0 ; i < (len ) ; i++)
 
 {
 
 // chkstring= hexstr.substring(i,i) ;
 
 hexstr.toUpperCase() ;
 
 tmp = hexstr.charAt(i) ; // give i th char and return this char
 
 tmp1 = hexcode.indexOf(tmp) ;
 
 tmpnum = tmpnum + tmp1* POW(16,(len -i -1) ) ;
 
 if (debugmode == 1)
 
 {
 
 Serial.print(“char:( “);
 
 Serial.print(i);
 
 Serial.print(“)/(“);
 
 Serial.print(hexstr);
 
 Serial.print(“)/(“);
 
 Serial.print(tmpnum);
 
 Serial.print(“)/(“);
 
 Serial.print((long)pow(16,(len -i -1)));
 
 Serial.print(“)/(“);
 
 Serial.print(pow(16,(len -i -1) ));
 
 Serial.print(“)/(“);
 
 Serial.print((char)tmp);
 
 Serial.print(“)/(“);
 
 Serial.print(tmp1);
 
 Serial.print(“)");
 
 Serial.println(“");
 
 }
 
 }
 
 return tmpnum;
 
 }
 long POW(long num, int expo)
 
 {
 
 long tmp =1 ;
 
 if (expo > 0)
 
 {
 
 for(int i = 0 ; i< expo ; i++)
 
 tmp = tmp * num ;
 
 return tmp ;
 
 }
 
 else
 
 {
 
 return tmp ;
 
 }
 
 }
 
 我們發現圖 3(a)所示,MF RC522 模組讀到卡(卡號:316C1155),為不是正確的開門卡,所以不會啟動繼電器,而見圖 3(b)所示,MF RC522 模組讀到卡(卡號:6AE4E616),為正確的開門卡,則Arduino 開發模組在 MF RC522 模組讀到該卡號之後,比對表 3 內『String keyno1 = String(“6AE4E616″);』的變數,為相同的變數內容,則使繼電器模組的 Com 與 NC 兩接點短路,讓電磁鎖。
 (责任编辑:admin)
 |