在本教程中,我们将学习RFID是什么,它如何运作以及如何制作基于Arduino的RFID门betway锁。您可以观看以下视频或阅读下面的书面教程以获取更多详细信息。
概述
RFID代表无线电频率识别它是一种非联系技术,广泛用于许多行业,如人员跟踪,访问控制,供应链管理,图书馆,收费系统等的书籍跟踪。
RFID的工作原理
射频识别系统由两个主要部件组成,一个位于我们想要被识别的物体上的应答器或标签,以及一个收发器或读卡器。
该RFID阅读器由射频模块、控制单元和产生高频电磁场的天线线圈组成。另一方面,标签通常是被动组件,由天线和电子芯片,所以当它附近的电磁场的收发器,由于感应电压产生的天线线圈这芯片的电压作为功率。
现在,当标签启动后,它可以从阅读器中提取传输的消息,为了将消息发送回阅读器,它使用了一种称为负载操作的技术。标签天线上的负载开关会影响阅读器天线的功耗,功耗可以通过电压降来测量。电压的变化将被捕获为1和0,这就是数据从标签传输到阅读器的方式。
读取器和标签之间还有另一种数据传输方式,称为反向散射耦合。在这种情况下,标签使用部分接收的电源,用于产生另一电磁场,该电磁场将被读取器的天线拾取。
RFID和Arduino
因此,这是基本的工作原理,现在让我们看看我们如何使用RFID与Arduino并建造自己的RFID门锁。我们将使用基于Mifare协议和MFRC522 RFID阅读器的标签,这只需几美元。
这些标签具有1KB的存储器,并且具有可以进行算术运算的微芯片。它们的工作频率为13.56 MHz,工作距离可达10厘米,具体取决于天线的几何形状。如果我们将其中一个标签带到光源前面,我们可以注意到我们之前谈过的天线和微芯片。
至于RFID读取器模块,它使用SPI协议与Arduino板通信,这是我们如何连接它们的方式。请注意,我们必须将模块的VCC连接到3.3V,以及我们不必担心的其他引脚,因为它们是5V宽容。
一旦我们连接模块,我们需要下载MFRC522图书馆来自GitHub。图书馆附带了几个好的例子,我们可以学习如何使用该模块。
首先,我们可以上传“DumpInfo”示例并测试我们的系统是否正常工作。现在,如果我们运行串行监视器并将标签置于模块附近,则读卡器将开始读取标签,并将在串行监视器上显示标记的所有信息。
在这里,我们可以注意到标记的UID号以及1 kB的内存实际上被分为16个扇区,每个扇区为4个块,每个块都可以存储2个字节的数据。对于本教程,我们不会使用任何标记的内存,我们只需使用标记的UID号。
Arduino RFID门锁门禁项目
在我们经历RFID门锁项目的代码之前,让我们来看看这个项目的组件和电路原理图。
除了RFID模块,我们还将使用一个接近传感器来检查门是否关闭或打开,一个伺服电机用于锁机构和一个字符显示。
您可以从下面的链接获取此Arduino教程所需的组件:
- MFRC522 RFID模块........................亚马逊/Banggood/阿里巴巴全球速卖通
- 伺服电机 ............................................亚马逊/Banggood/阿里巴巴全球速卖通
- 液晶显示器 .............................................亚马逊/Banggood/阿里巴巴全球速卖通
- Arduino电路板 ........................................亚马逊/Banggood/阿里巴巴全球速卖通
- 面包板和跳线.................亚马逊/Banggood/阿里巴巴全球速卖通
- 接近传感器CNY70 ........................亚马逊/阿里巴巴全球速卖通
必威外围提钱披露:这些是联盟链接。作为亚马逊助理,我从合格购买中获得。
该项目有以下工作流程:首先,我们必须设置一个主标签,然后系统进入正常模式。如果我们扫描一个未知的标签,访问将被拒绝,但如果我们扫描主,我们将进入一个程序模式,从那里我们可以添加和授权未知的标签。现在如果我们再扫描一次标签就可以打开门了。
我们关门后,门会自动锁上。如果我们想从系统中删除一个标签,我们只需要再次进入程序模式,扫描know标签,它就会被删除。
源代码
现在让我们看一下代码。因此,首先,我们需要包括RFID模块,显示器和伺服电机的库,定义下面的程序所需的一些变量,以及创建库的实例。
#include#include #include #include #define rst_pin 9 #define ss_pin 10字节readcard [4];char * mytags [100] = {};int tagscount = 0;String tagid =“”;布尔成功= false;Boolean ClassTag = false;int proximitysensor;布尔接种= false;//创建实例MFRC522 MFRC522(SS_PIN,RST_PIN);液晶LCD(2,3,4,5,6,7); //Parameters: (rs, enable, d4, d5, d6, d7) Servo myServo; // Servo motor
在“设置”部分中,首先我们初始化模块,并将伺服电机的初始值设置为锁定位置。然后,我们将初始消息打印到显示器,并在以下“循环”循环之前,我们等到扫描主标记。getID()自定义函数获取标记UID,我们将其放入MyTags [0]数组的第一个位置。
void setup(){//初始化SPI.begin();// SPI总线mfrc522.PCD_Init();// mfrc522 lcd.begin(16,2);// LCD屏幕myServo.attach(8);//伺服电机myServo.write(10);//伺服电机的初始锁定位置//打印初始消息lcd.print(“ - 没有主标记! - ”);lcd.setcursor(0,1);lcd.print(“立即扫描”);//等待master card被扫描,while (!successRead) {successRead = getID();if (successRead == true) {myTags[tagsCount] = strdup(tagID.c_str()); // Sets the master tag into position 0 in the array lcd.clear(); lcd.setCursor(0, 0); lcd.print("Master Tag Set!"); tagsCount++; } } successRead = false; printNormalModeMessage(); }
让我们看看getID()自定义函数。首先,它检查是否有一个新的标签放置在阅读器附近,如果有,我们将继续“for”循环,这将获得标签的UID。我们使用的标记有4字节的UID号,所以这就是为什么我们需要对这个循环进行4次迭代,并使用concat()函数将4字节添加到单个String变量中。我们还将字符串的所有字符设置为大写,并在结束时停止读取。
UINT8_T getID(){//准备好读取piccs(!mfrc522.picc_isnewcardpresent()){//如果放置到RFID读取器的新PICC继续返回0;}如果(!mfrc522.picc_readcardserial()){//由于picc放置了串行并继续返回0;} tagid =“”;for(uint8_t i = 0; i <4; i ++){//我们使用的mifare piccs有4个字节uid readcard [i] = mfrc522.uid.uidbyte [i];tagid.concat(string(mfrc522.uid.uidbyte [i],hex));//在单个字符串变量中添加4个字节} tagid.touppercase();mfrc522.picc_halta();//停止阅读返回1;}
在进入主循环之前,在设置部分的末尾,我们还调用了printNormalModeMessage()自定义函数,该函数在显示器上打印“Access Control”消息。
void printNormalModeMessage(){延迟(1500);lcd.clear ();lcd.print(“ - Access Control-”);lcd.setcursor(0,1);lcd.print(“扫描你的标签!”);}
在主循环中,我们从读取近距离传感器的值,告诉我们门是否关闭。
int proximitysensor = analogread(a0);
因此,如果门关闭,使用与我们在getID()自定义函数中描述的相同的行,我们将扫描并获取新标记的UID。我们可以在这里注意到,由于“if”语句中的“return”行,代码在扫描标记之前不会继续执行。
一旦我们扫描了这个标签,我们就会检查这个标签是否是我们之前注册的master,如果是这样,我们就会进入程序模式。在这种模式下,如果我们扫描一个已经授权的标签,它将从系统中删除,或者如果标签是未知的,它将作为授权添加到系统中。
//检查扫描的标签是否是主标签if (tagID == myTags[0]) {lcd.clear();lcd.print(“计划模式:”);lcd.setcursor(0,1);lcd.print(“添加/删除标记”);while (!successRead) {successRead = getID();if(successRead == true){for(int i = 0; i <100; i ++){if(tagid == mytags [i]){mytags [i] =“”;lcd.clear ();lcd.setCursor(0,0);lcd.print(“删除标签!”);printNormalModeMessage (); return; } } myTags[tagsCount] = strdup(tagID.c_str()); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Tag Added!"); printNormalModeMessage(); tagsCount++; return; } } }
在程序模式之外,通过下一个“for”循环,我们检查扫描的标签是否等于任何挂号标签,我们要么解锁门或保持访问拒绝。最后在“别的”声明中我们等到门关闭,然后我们锁定了门并再次打印了正常模式消息。
//检查扫描的标签是否被授权(int i = 0; i <100; i ++){if(tagid == mytags [i]){lcd.clear();lcd.setCursor(0,0);lcd.print(“获得授予的!”);myServo.write (170);//打开门printNormalModeMessage();correctTag = true;}} if (correctTag == false) {lcd.clear();lcd.setCursor(0,0);lcd.print(“拒绝访问!”);printNormalModeMessage (); } } // If door is open... else { lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Door Opened!"); while (!doorOpened) { proximitySensor = analogRead(A0); if (proximitySensor > 200) { doorOpened = true; } } doorOpened = false; delay(500); myServo.write(10); // Locks the door printNormalModeMessage(); }
这就是项目的全部内容,下面是项目的完整代码:
/ * * Arduino门锁访问控制项目* *由Dejan Nedelkovski,www.www.mfxpo.com * *图书馆:bet188官方网站MFRC522,https://github.com/miguelbalboa/rfid * / #include#include #include #include #define rst_pin 9 #define ss_pin 10字节readcard [4];char * mytags [100] = {};int tagscount = 0;String tagid =“”;布尔成功= false;Boolean ClassTag = false;int proximitysensor;布尔接种= false;//创建实例MFRC522 MFRC522(SS_PIN,RST_PIN);液晶LCD(2,3,4,5,6,7); //Parameters: (rs, enable, d4, d5, d6, d7) Servo myServo; // Servo motor void setup() { // Initiating SPI.begin(); // SPI bus mfrc522.PCD_Init(); // MFRC522 lcd.begin(16, 2); // LCD screen myServo.attach(8); // Servo motor myServo.write(10); // Initial lock position of the servo motor // Prints the initial message lcd.print("-No Master Tag!-"); lcd.setCursor(0, 1); lcd.print(" SCAN NOW"); // Waits until a master card is scanned while (!successRead) { successRead = getID(); if ( successRead == true) { myTags[tagsCount] = strdup(tagID.c_str()); // Sets the master tag into position 0 in the array lcd.clear(); lcd.setCursor(0, 0); lcd.print("Master Tag Set!"); tagsCount++; } } successRead = false; printNormalModeMessage(); } void loop() { int proximitySensor = analogRead(A0); // If door is closed... if (proximitySensor > 200) { if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue return; } if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue return; } tagID = ""; // The MIFARE PICCs that we use have 4 byte UID for ( uint8_t i = 0; i < 4; i++) { // readCard[i] = mfrc522.uid.uidByte[i]; tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Adds the 4 bytes in a single String variable } tagID.toUpperCase(); mfrc522.PICC_HaltA(); // Stop reading correctTag = false; // Checks whether the scanned tag is the master tag if (tagID == myTags[0]) { lcd.clear(); lcd.print("Program mode:"); lcd.setCursor(0, 1); lcd.print("Add/Remove Tag"); while (!successRead) { successRead = getID(); if ( successRead == true) { for (int i = 0; i < 100; i++) { if (tagID == myTags[i]) { myTags[i] = ""; lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Tag Removed!"); printNormalModeMessage(); return; } } myTags[tagsCount] = strdup(tagID.c_str()); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Tag Added!"); printNormalModeMessage(); tagsCount++; return; } } } successRead = false; // Checks whether the scanned tag is authorized for (int i = 0; i < 100; i++) { if (tagID == myTags[i]) { lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Access Granted!"); myServo.write(170); // Unlocks the door printNormalModeMessage(); correctTag = true; } } if (correctTag == false) { lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Access Denied!"); printNormalModeMessage(); } } // If door is open... else { lcd.clear(); lcd.setCursor(0, 0); lcd.print(" Door Opened!"); while (!doorOpened) { proximitySensor = analogRead(A0); if (proximitySensor > 200) { doorOpened = true; } } doorOpened = false; delay(500); myServo.write(10); // Locks the door printNormalModeMessage(); } } uint8_t getID() { // Getting ready for Reading PICCs if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue return 0; } if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue return 0; } tagID = ""; for ( uint8_t i = 0; i < 4; i++) { // The MIFARE PICCs that we use have 4 byte UID readCard[i] = mfrc522.uid.uidByte[i]; tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Adds the 4 bytes in a single String variable } tagID.toUpperCase(); mfrc522.PICC_HaltA(); // Stop reading return 1; } void printNormalModeMessage() { delay(1500); lcd.clear(); lcd.print("-Access Control-"); lcd.setCursor(0, 1); lcd.print(" Scan Your Tag!"); }
我希望你喜欢本教程,请在下方的评论部分提出任何问题。
谢谢!非常好的教程和项目。
谢谢!
先生,请同时使用esp8266_01和PIC微控制器,您的解释对每个人都很有帮助
谢谢!我正在制作智能锁,作为一名机械工程师,我从你们不同的视频中得到了很多帮助。太棒了!
/torbjörn.
很高兴听到这个,谢谢!
HC-SR501模块将具有与CNY70相同的功能?
不是真的,HC-SR501是PIR传感器,CNY70是距离测量传感器。
先生,我不能让它工作。我的所有电线检查了所有的电线。
液晶显示仍然空白!
我该如何解决这个问题?
LCD的问题是对比。尝试调整LCD对比度引脚的电压,尝试使用电位器或不同的分压器,以及使用带有Arduino的LCD显示屏查看我的详细教程。
你好,我已经参考了你的LCD教程,但我没有电位器。请问电阻器的调整是在地面上还是在对比度引脚的5v上进行?我在5v上使用220欧姆,在gnd上使用1000欧姆,正如图片颜色代码所示。是我使用了错误的电阻还是有什么问题。因为我用的是和你一样的LCD和连接,所以应该不会有任何错误?谢谢你! !I need this for a mini project of mine hope you can help me with the LCD contrast issue Thanks!!
尝试使用不同的电阻以获得不同的分压器,从而在LCD上进行对比度。
啊..谢谢你!我试图删除一个对比度销电阻并将其直接连接到地。有效!
谢谢,我读过的最好的教程!
标签id是否存储在EEPROM中,以便在断电后记住先前存储的标签?
谢谢,
李。
你好,如果我使用Arduino Uno而不是Arduino nano,有什么区别吗?
不会有任何区别。
我可以用螺线管12v代替伺服电机吗?如果我想增加led指示灯?我必须做什么(编码)?
请帮助。
你当然能做到。代码不需要太大的改动,可能只是用一个数字引脚来激活电磁阀。
我做到了,
添加螺线管,按按钮从另一侧,LED RGB,电池和LCD I2C适配器换档。除了一个思考外,一切都是完美的,当损耗电源再次开始时,程序开始。现在我试图用我的EEPROM,你有什么建议吗?
而一个小问题,当我尝试在printnormalmodemessage()上制作滚动文本时,程序被卡住,无法扫描卡并运行系统,只需滚动文本就会显示在LCD上,请帮助。先生,谢谢你。
是的,解决问题的问题,您应该找到一种存储EEPROM中数据的方法。
谢谢你的教程,它非常出色并效果完美。
问候,tobo。
伟大的项目,但我如何存储uid ?另外,在腐蚀标签上存储一个名称也是很好的。
马克
即使断电,您也可以使用Arduino的EEPROM存储uid。
你使用了哪个arduino和原因。还有一种方法可以录制扫描卡的方法,并且扫描的时间并能够保存显示。
当然可以制作一个将存储时间的程序,可以使用DS3231实时时钟模块为此目的。
这个项目帮助了我很多。非常感谢。
是否有可能用电动插槽更换Thé伺服电机
当然,任何修改都是可能的。
惊人的教程!谢谢
你好,伟大的文章。我需要大约2英尺的射程,这可能吗?
谢谢,汤姆
是的,一些RFID读者可以激活被动标签超过两英尺远。但是,它们不紧凑,需要比该项目相当多的功率,仅在商业上可用,并且可以相对昂贵。在这种情况下,接近传感器可能是不实用的,并且可以是超声波传感器也可能不够。如果它有意义,请考虑一个可中断的光束,例如IR或激光,其中物体触发RFID读取器激活。另一种可能性是将RFID读取器留出并轮询标签,因为它们通过了跟踪类型应用程序。
你好!
我有一个关于这个项目的问题:
这个项目在没有接近传感器的情况下也可以工作吗?或者我需要一个接近传感器才能正常工作吗?
谢谢
嘿,它会起作用,但它需要在代码中进行一些修改。如果您没有那个,您也可以使用不同的接近传感器。
出于某种原因,getID()在我的上面不起作用。有什么办法能解决这个问题吗?谢谢。
PS:我试图复制并粘贴网站上的代码,这也不适用。
你得到了什么错误?确保已安装MFRC522库,该链接包含在上面的文章中。
它说:getID()在这个作用域中没有声明。
谢谢,伟大的文章。
你可能错过了第143 - 168行。
尝试再次复制代码。
嗨,你如何连接光学传感器CNY70?
矿山已经炒了3次,我按照概略图。
只是为了确保你使用的电阻是220和10k对光学传感器?
如何连接传感器接地和电源?
好吧谢谢
我们将使用你连接适当的引脚到适当的电阻,以及接地和5V。电路图显示了正确的连接方式。
嘿,谢谢你的项目。我想知道CA是否使用超声波传感器而不是接近传感器CNY70?
嘿,是的,你可以使用超声波传感器。当然,您必须适当地修改代码。我用CNY70只是因为它较小。