這篇文章來(lái)源于DevicePlus.com英語(yǔ)網(wǎng)站的翻譯稿。
已經(jīng)煩透了丟失鑰匙或者忘記帶鑰匙而被鎖在門(mén)外嗎?好吧,讓我來(lái)為您提供一個(gè)完美的解決方案!今天,我們將制作一款Arduino RFID門(mén)鎖。我想要找到一種簡(jiǎn)單并且安全的方法來(lái)鎖門(mén),而不必購(gòu)買(mǎi)一個(gè)昂貴的裝置。接下來(lái),我們將要學(xué)習(xí)射頻識(shí)別(RFID)技術(shù)并將其應(yīng)用到無(wú)線(xiàn)通信中。
什么是RFID?
“RFID表示射頻識(shí)別,[…]RFID的作用與信用卡或者ATM卡背面的條形碼或磁條相同;它為物體提供了唯一的標(biāo)識(shí)符。而且,就像必須掃描條形碼或詞條才能獲取信息一樣,RFID設(shè)備必須經(jīng)過(guò)掃描才能獲取相關(guān)的識(shí)別信息?!报C 摘自?Technovelgy,一個(gè)記錄科學(xué)技術(shù)與科幻創(chuàng)意的網(wǎng)站。
在本項(xiàng)目中通過(guò)使用RFID技術(shù)來(lái)從RFID標(biāo)簽中讀取數(shù)據(jù),并將信息發(fā)送到MCU的非易失性存儲(chǔ)器。從標(biāo)簽讀取的ID與存儲(chǔ)的信息進(jìn)行比較,如果匹配,則門(mén)將被解鎖/打開(kāi)。
Arduino Nano
RFID RC522
壓電蜂鳴器
2x LED
2x 330 電阻
4×4 鍵盤(pán)
LCD適配器I2C
LCD16X2BL
軟件
Arduino IDE
SketchUp
Github
將LCD 連接到Arduino
LCD有16個(gè)引腳,對(duì)于Arduino Nano來(lái)說(shuō)引腳數(shù)量過(guò)多,因此一定要使用I2C適配器,如此一來(lái)可以?xún)H通過(guò)Arduino的兩個(gè)信號(hào)引腳來(lái)實(shí)現(xiàn)顯示功能。這很有幫助,因?yàn)檫@種情況下需要通過(guò)MCU控制的引腳數(shù)量就會(huì)很少。
圖1:LCD引腳
LCD具有并行接口,這意味著MCU必須同時(shí)操控多個(gè)接口引腳來(lái)對(duì)顯示進(jìn)行控制。下表提供了每個(gè)引腳的說(shuō)明:
圖2:引腳規(guī)格
首先,我們將在LCD和I2C之間建立連接。為此,我們需要一個(gè)I2C LCD顯示適配器(LCD1602)。該適配器將16 x 2字符LCD顯示轉(zhuǎn)換為串行I2C LCD,僅用兩根導(dǎo)線(xiàn)連接即可通過(guò)Arduino進(jìn)行控制。
圖3:Arduino和LCD之間的連接
接下來(lái),我們將在Arduino IDE中添加庫(kù)“”。我們可以通過(guò)該庫(kù)將LCD連接到Arduino。內(nèi)置的LiquidCrystal_I2C庫(kù)可以輕松實(shí)現(xiàn)在LCD屏幕上顯示字母。
您可以點(diǎn)擊此處下載LiquidCrystal_I2C.h。
請(qǐng)按照以下步驟將新的庫(kù)安裝到您的Arduino IDE中:
1) 首先,從Github上下載文件(我將要下載的是Keypad庫(kù))。
2) 壓縮(.zip)每個(gè)文件夾。
3) 拷貝.zip文件到您的Arduino文件夾中。
4) 打開(kāi)Arduino并添加Keypad.zip::Sketch menu > Include Library > Add .ZIP Library。
5) 添加keypad庫(kù):Sketch menu > Include Library > Keypad.
測(cè)試LCD的代碼:
#include #include LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display void setup() { lcd.begin();// initialize the LCD lcd.backlight();// Turn on the blacklight and print a message. lcd.backlight(); lcd.print("Hello, world!"); } void loop() { }
圖4:連接到Arduino Nano的LCD
連接鍵盤(pán)
現(xiàn)在,要進(jìn)入鍵盤(pán)部分了!我們將要對(duì)鍵盤(pán)進(jìn)行連接,以實(shí)現(xiàn)在LCD上顯示從鍵盤(pán)輸入的數(shù)字。
Keypad.h 是一個(gè)讓Arduino能夠從鍵盤(pán)讀取矩陣類(lèi)型鍵盤(pán)數(shù)據(jù)的庫(kù)。
在本教程中我使用的是一個(gè) 4×4 鍵盤(pán)。
下表顯示了Arduino開(kāi)發(fā)板與鍵盤(pán)之間的連接情況。鍵盤(pán)引腳連接到Arduino的數(shù)字輸出引腳。D6引腳是PWM引腳,因此用于蜂鳴器。
Keypad pin | Arduino pin |
1 | D2 |
2 | D3 |
3 | D4 |
4 | D5 |
5 | A0 |
6 | D7 |
7 | D8 |
圖5:Arduino、LCD以及鍵盤(pán)之間的連接
圖6:連接到Arduino的LCD和鍵盤(pán)
連接RFID
接下來(lái),我們將添加RFID。在這種情況下,RFID板使用SPI通信協(xié)議,其中Arduino將作為主機(jī),而RFID閱讀器將作為從機(jī)。讀卡器和標(biāo)簽將被設(shè)計(jì)為以13.56MHz大小的頻率進(jìn)行通信。
這是很重要的一步,因?yàn)镽FID會(huì)幫助我們從卡上讀取數(shù)據(jù),并且確定ID是否對(duì)應(yīng)于EEPROM中存儲(chǔ)的信息。如果匹配,我們就能夠進(jìn)入房間并顯示“解鎖”。否則,LCD將顯示“鎖定”。
圖7: Arduino、LCD以及RFID之間的連接
圖8: Arduino、LCD以及RFID
添加蜂鳴器以及LED
下一步是添加一個(gè)蜂鳴器和2個(gè)LED,以模擬被控制訪問(wèn)系統(tǒng)的狀況。請(qǐng)查看下面的接線(xiàn)圖(圖9)。我們?cè)O(shè)置了一個(gè)蜂鳴器,可以在獲得訪問(wèn)權(quán)限(解鎖)時(shí)蜂鳴。鎖定時(shí),紅色LED始終亮起,解鎖時(shí),綠色LED會(huì)亮起。
為了保護(hù)這些設(shè)備模塊,我決定用3D打印制造出收納的盒子。如果您沒(méi)有3D打印機(jī),可以使用一個(gè)可以盛放所有組件的塑料盒。這會(huì)很有幫助,因?yàn)檫@樣一來(lái)這些模塊將會(huì)被放置于內(nèi)部,只有LED、鍵盤(pán)和LCD會(huì)放置在盒子外。
圖9:Nano、 LCD、鍵盤(pán)、RFID和蜂鳴器連接接線(xiàn)圖
制造收納的盒子
對(duì)于本項(xiàng)目,我想要制造一個(gè)自定義的盒子來(lái)收納所有的組件,并保護(hù)這些組件不被損壞。
我使用SketchUp設(shè)計(jì)了一個(gè)盒子,這個(gè)軟件具有用戶(hù)友好型界面,有一些簡(jiǎn)單的操作按鈕,如橡皮擦、線(xiàn)條和卷尺工具等。
盒子的尺寸是 120x125x37 mm。
如果您對(duì)Sketchup不熟悉,建議您點(diǎn)擊此處閱讀一些Sketchup教程。
圖10:收納盒子(頂部視圖)
圖11:收納盒子(底部視圖)
設(shè)計(jì)盒子時(shí),我考慮了以下尺寸:
頂部視圖:
2 個(gè)用于LED的開(kāi)口 (5.2 mm)
1 個(gè)用于LCD的開(kāi)口 (42.2×7.3 mm)
1 個(gè)用于線(xiàn)纜的開(kāi)口(16×10.5 mm)span>
底部視圖
1 個(gè)用于鍵盤(pán)的開(kāi)口(27×10 mm)
在測(cè)量了組件的尺寸之后,我設(shè)計(jì)了一個(gè)非常緊湊的盒子。您可以根據(jù)自己的喜好對(duì)設(shè)計(jì)進(jìn)行更改。
圖12:內(nèi)部裝有模塊的完整收納盒
代碼流程圖
完整代碼
#include #include #include #include #include #include int relPin; int state=0; byte COD[10]; byte AUX[10]; int k=0; String ; String ; //NFC #define RST_PIN 9 #define SS_PIN 10 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance #define NEW_UID {0xDE, 0xAD, 0xBE, 0xEF} MFRC522::MIFARE_Key key; //LCD LiquidCrystal_I2C lcd(0x27,16,2); //KEYPAD const byte numRows= 4; //number of rows on the keypad const byte numCols= 4; //number of columns on the keypad char keymap[numRows][numCols]= { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; //Code that shows the the keypad connections to the arduino terminals byte rowPins[numRows] = {2,3,4,5}; //Rows 0 to 3 byte colPins[numCols]= {A0,7,8,9}; //Columns 0 to 3 //initializes an instance of the Keypad class Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols); void setup() { pinMode(A0,OUTPUT); digitalWrite(A0,HIGH); pinMode(A3,OUTPUT); digitalWrite(A3,HIGH); pinMode(A1,OUTPUT); digitalWrite(A1,HIGH); pinMode(A2,OUTPUT); digitalWrite(A2,LOW); //NFC Serial.begin(9600); // Initialize serial communications with the PC while (!Serial); // Do nothing if no serial port is opened SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 card for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } lcd.begin(); lcd.backlight(); lcd.setCursor(0,0); lcd.clear(); lcd.print( "BLOCKED" ); } void readNFC(){ // This function will read the code stored on for (byte i =0; i<(mfrc522.uid.size); i++) { // the UID COD[i]=mfrc522.uid.uidByte[i]; } Serial.print("COD"); Serial.print(COD[0]); Serial.print(COD[1]); Serial.print(COD[2]); Serial.print(COD[3]); } void pairNFC(){ Serial.println("COD in pair"); Serial.print(COD[0]); Serial.print(COD[1]); Serial.print(COD[2]); Serial.print(COD[3]); long r=0; int c=0; for(int i=1;i<=EEPROM.read(0);i++){ //The UID cannot be stored on switch(i%4){ // one variable, it was needed to be case 1 :{AUX[0]=EEPROM.read(i); break;} // split case 2 :{AUX[1]=EEPROM.read(i); break;} case 3 :{AUX[2]=EEPROM.read(i); break;} case 0 :{AUX[3]=EEPROM.read(i); break;} } if((i)%4==0) {Serial.println(r); if( AUX[0]==COD[0] && AUX[1]==COD[1] && AUX[2]==COD[2] && AUX[3]==COD[3] ){ //Verify if the code is in EEPROM lcd.clear(); lcd.setCursor(0,0); lcd.print("CODE ALREADY IN"); lcd.setCursor(0,1); lcd.print("SYSTEM"); delay(2000); c=1; break;} } } if(c==0){int aux2=EEPROM.read(0); Serial.println("CODE PAIRED"); Serial.print(COD[0]); Serial.print(COD[1]); Serial.print(COD[2]); Serial.print(COD[3]); EEPROM.write(aux2+1,COD[0]); //Writing code in EEPROM EEPROM.write(aux2+2,COD[1]); EEPROM.write(aux2+3,COD[2]); EEPROM.write(aux2+4,COD[3]); aux2=aux2+4; // Position for a new code Serial.println("aux2"); Serial.println(aux2); EEPROM.write(0,0); EEPROM.write(0,aux2); lcd.clear(); lcd.setCursor(0,0); lcd.print("CODE PAIRED"); delay(2000);} } boolean validationNFC(){ boolean c=false; for(int i=1;i<=EEPROM.read(0);i++){ //Read the EEPROM switch(i%4){ case 1 :{AUX[0]=EEPROM.read(i); break;} case 2 :{AUX[1]=EEPROM.read(i); break;} case 3 :{AUX[2]=EEPROM.read(i); break;} case 0 :{AUX[3]=EEPROM.read(i); break;} } if((i)%4==0) { if( AUX[0]==COD[0] && AUX[1]==COD[1] && AUX[2]==COD[2] && AUX[3]==COD[3]) c=true; //Verify if the code is in EEPROM and make flag=true; } } return c; } int compareCODE(String a) //We type a code on keypad and this will be compared { //with the accessCode; if(a.equals(accessCode)) return 1; else if(a.equals(codpairing)) return 2; else return 0; } String takeCode(char x) //Will display on the LCD the code typed { char vec[10]; vec[0]=x; lcd.setCursor(0,0); lcd.clear(); lcd.print('X'); for(int i=1;i<8;i++) {vec[i]=myKeypad.waitForKey(); //Waits for 8 keys to be pressed and after that lcd.print('X');} //is taking the decision vec[8]=NULL; String str(vec); return str; } void loop() { switch(state){ case 0: { mfrc522.PCD_Init(); if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ){ readNFC(); //It will read the card and it will search for UID in its if(validationNFC()) //memory { state=1; lcd.clear(); lcd.setCursor(0,0); lcd.print( "VALID NFC CODE" ); //The door will be opened delay(1000); return; } else{ lcd.clear(); lcd.setCursor(0,0); lcd.print( "INVALID NFC CODE" ) //If the code was wrongblocked delay(1000); lcd.setCursor(0,0); lcd.clear(); lcd.print( "BLOCKED" ); return; } } char c=myKeypad.getKey(); if(c != NO_KEY){ String codcurent=takeCode(c); int A=compareCODE(codcurent); if(A==0){ //A is a variable that stores the current code lcd.clear(); lcd.print("INVALID CODE"); delay(2000); lcd.setCursor(0,0); lcd.clear(); lcd.print("BLOCKED"); return; } if(A==1){ lcd.setCursor(0,0); lcd.clear(); lcd.print( "VALID CODE " ); delay(2000); state = 1; Return; } if(A==2); { state=2; lcd.clear(); lcd.setCursor(0,0); lcd.print( " Pairing..." ); delay(2000); return;} } break; } case 1:{ lcd.clear(); lcd.setCursor(0,0); lcd.print( "UNLOCKED" ); digitalWrite(A3,LOW); digitalWrite(A1,LOW); //The red LED will be off digitalWrite(A2,HIGH); //The green LED will be on tone(6,3000,5010); //The buzzer will make a sound delay(5000); //After 5 seconds the system will be blocked digitalWrite(A3,HIGH); digitalWrite(A1,HIGH); digitalWrite(A2,LOW); state=0; lcd.setCursor(0,0); lcd.clear(); lcd.print( "BLOCKED" ); return; } case 2:{ mfrc522.PCD_Init(); if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ){ readNFC(); pairNFC(); state=0; delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print( "BLOCKED" ); } break; } } }
結(jié)論
至此,我們成功制作了一款低成本的Arduino RFID門(mén)鎖。對(duì)我來(lái)說(shuō),這是一個(gè)很有趣的項(xiàng)目,因?yàn)槲沂菫樽约菏褂枚谱鞯?。此外,制作一個(gè)這樣的設(shè)備不僅能讓您因?yàn)樽隽艘恍┯杏玫氖露a(chǎn)生滿(mǎn)足感,學(xué)習(xí)到很多知識(shí),還能讓您對(duì)自制電子設(shè)備有初步的嘗試和體驗(yàn)。與各種各樣的開(kāi)發(fā)板打交道是非常具有挑戰(zhàn)性的。本項(xiàng)目還包含了很多有趣的課題,例如:
與其他Arduino庫(kù)一起使用
理解EEPROM的使用
使用多種通信,如I2C, SPI
點(diǎn)擊此處 閱讀本文的第二部分,我們將開(kāi)發(fā)用智能手機(jī)端解鎖的功能!查看我們的Arduino 項(xiàng)目,了解其他有趣且具有挑戰(zhàn)性的Arduino項(xiàng)目!
DevicePlus 編輯團(tuán)隊(duì)
設(shè)備升級(jí)版適用于所有熱愛(ài)電子和機(jī)電一體化的人。
審核編輯黃宇
-
RFID
+關(guān)注
關(guān)注
387文章
6091瀏覽量
237216 -
Arduino
+關(guān)注
關(guān)注
187文章
6458瀏覽量
186504
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論