|
本帖最后由 code-AR 于 2014-4-7 15:26 编辑
不知道大家是否在学校生活中常常会有忘带钥匙的情况出现,每当忘带钥匙,室友不在寝室的话,站在寝室外等待各种尴尬。同时不知道是不是学校门锁老旧,开门比较纠结花时间。那时候就有制作自动门锁的想法。后来入手了RFID读卡器,可以正常读取市面上的Mifare S50,S70非接触智能卡,像学校的饭卡就可以读取。就构想了这个基于RFID的寝室门禁系统。
系统原理是基于非接触式卡的序列号是唯一的,制造厂家在产品出厂前已将此序列号固化,不可再更改。这样不同的卡都是唯一的存在,可以利用读卡器读取卡的序列号,来判断卡的拥有者(像我的室友)。基本原理可以参考下图:
寝室RFID门禁系统1.0
首先来一张全景图吧。
(1) 准备工作
制作材料:
 Arduino UNO
 NOKIA 5110液晶屏
 RFID-RC522读卡器
 MG-996R舵机
 移动电源
首先,是将RFID-RC522和UNO连接起来,这个读卡器是基于SPI通讯。但这里有一个封装比较好的库文件支持RC522,可以自定义SPI针脚位。NOKIA 5110液晶屏也有库文件——支持画图,中文显示,可以自定义针脚位。因为开启门锁需要较强拉力,这样MG-996R所需电量比较大,实际使用时,需要给舵机单独供电。整个电路部分还是比较简单的,只是能够完成最基本的功能展现。
(2) 软件部分
主控部分用的的是Arduino Uno,使用了arduino IDE 1.04。
代码如下: - #include <SPI.h>
- #include <RFID.h>
- #include <LCD5110_CN.h>
- #define servopin 7
- #define sensor 0
- #define BL 9
- LCD5110 myGLCD(2,3,4,5,6);//CLk-SCK,Din-MOSI,DC,RST-IO,CS-CE
- extern uint8_t SmallFont[];
- RFID rfid(10,8); //D10--读卡器SDA引脚、D8--读卡器RST引脚
- //4字节卡序列号,第5字节为校验字节
- unsigned char serNum[5];
- void servopulse(int angle)//定义一个脉冲函数
- {
- int pulsewidth=(angle*11)+500; //将角度转化为500-2480的脉宽值
- digitalWrite(servopin,HIGH); //将舵机接口电平至高
- delayMicroseconds(pulsewidth); //延时脉宽值的微秒数
- digitalWrite(servopin,LOW); //将舵机接口电平至低
- delayMicroseconds(20000-pulsewidth);
- }
- void setup()
- {
- myGLCD.InitLCD();
- Serial.begin(9600);
- pinMode(BL,OUTPUT);
- pinMode(servopin,OUTPUT);
- myGLCD.setFont(SmallFont);
- SPI.begin();
- rfid.init();
- }
- void loop()
- {
- /* int val1=analogRead(sensor);
- if(val1>200)
- {analogWrite(BL,512);}
- else
- {digitalWrite(BL,LOW);}*/
- //通过光敏,控制5110的背光
- long randNumber = random(0, 20);
-
- unsigned char i,tmp;
- unsigned char status;
- unsigned char str[MAX_LEN];
- unsigned char RC_size;
- //找卡
- rfid.isCard();
- //读取卡序列号
- if (rfid.readCardSerial())
- {
- Serial.print("The card's number is : ");
- Serial.print(rfid.serNum[0]);
- Serial.print(" , ");
- Serial.print(rfid.serNum[1],BIN);
- Serial.print(" , ");
- Serial.print(rfid.serNum[2],BIN);
- Serial.print(" , ");
- Serial.print(rfid.serNum[2],BIN);
- Serial.print(" , ");
- Serial.print(rfid.serNum[4],BIN);
- Serial.println(" ");
- if(rfid.serNum[0]==205||rfid.serNum[0]==170||rfid.serNum[0]==219||rfid.serNum[0]==117||rfid.serNum[0]==155){
- for(int i=0;i<100;i++)
- {
- servopulse(45);
- if(rfid.serNum[0]==205||rfid.serNum[0]==117||rfid.serNum[0]==155)
- {
- myGLCD.clrScr();
- Serial.println("Welcome Mr.Xiao");
- myGLCD.print("Welcome",int(randNumber)+20,int(randNumber));
- myGLCD.print("Mr.Xiao",int(randNumber)+20,int(randNumber)+20);
- analogWrite(BL,HIGH);
- }
- if(rfid.serNum[0]==219)
- {
- myGLCD.clrScr();
- Serial.println("Welcome Mr.Yang");
- myGLCD.print("Welcome",int(randNumber)+20,int(randNumber));
- myGLCD.print("Mr.Yang",int(randNumber)+20,int(randNumber)+20);
- digitalWrite(BL,HIGH);
- }
- if(rfid.serNum[0]==170)
- {
- myGLCD.clrScr();
- Serial.println("Welcome Mr.Huang");
- myGLCD.print("Welcome",int(randNumber)+20,int(randNumber));
- myGLCD.print("Mr.Huang",int(randNumber)+20,int(randNumber)+20);
- digitalWrite(BL,HIGH);
- }
-
- } //引用脉冲函数
- delay(3000);
- for(int i=0;i<100;i++)
- {
- servopulse(0);
- }
- }
- }
- if (!rfid.readCardSerial()){
-
- digitalWrite(servopin,LOW);
- digitalWrite(BL,LOW);
- }
- rfid.halt(); //指挥卡进入睡眠模式
- }
复制代码
这里有两个库文件
(3) 试验品1.0
电路连接的部分结束后,我使用了比较简陋的纸壳将整个装置包装起来,将电路部分固定在了里面。然后将整个包装粘合在门后,其中读卡器是在门缝走线(还好是木门O(∩_∩)O哈哈~)。
这里有个效果视频
这里有几个问题,希望可以和大家探讨下:
1.电源供电部分?不知道有没有更好的供电方案,那个舵机供电太烦恼了,不得不用有两头供电的移动电源。
2.有没有自动激活好方法?希望能够实现晚上系统断电,早上系统激活工作。这样可以增强系统续航力。
3.更好的用户界面,像欢迎,查询。用点阵还是液晶屏?
以上只是我想法的最基础版本,可以说是系统1.0版吧,但这样已经完成了最初的预想。我想这个基础版还是有很大的发展空间,完全可以基于此,进一步使整个寝室智能化。下一步我想加强系统的稳定性,以及增加密码键功能,开发出2.0,3.0版本。也希望有兴趣的朋友那个给出宝贵的建议,大家一起分享快乐。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|