极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 86465|回复: 101

【占坑】抛弃钥匙,寝室RFID门禁系统进化史...

  [复制链接]
发表于 2014-1-2 17:11:48 | 显示全部楼层 |阅读模式
本帖最后由 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。
代码如下:
  1. #include <SPI.h>
  2. #include <RFID.h>
  3. #include <LCD5110_CN.h>
  4. #define servopin 7
  5. #define sensor 0
  6. #define BL 9
  7. LCD5110 myGLCD(2,3,4,5,6);//CLk-SCK,Din-MOSI,DC,RST-IO,CS-CE
  8. extern uint8_t SmallFont[];

  9. RFID rfid(10,8);    //D10--读卡器SDA引脚、D8--读卡器RST引脚

  10. //4字节卡序列号,第5字节为校验字节
  11. unsigned char serNum[5];

  12. void servopulse(int angle)//定义一个脉冲函数

  13. {

  14.   int pulsewidth=(angle*11)+500;  //将角度转化为500-2480的脉宽值

  15.   digitalWrite(servopin,HIGH);    //将舵机接口电平至高

  16.   delayMicroseconds(pulsewidth);  //延时脉宽值的微秒数

  17.   digitalWrite(servopin,LOW);     //将舵机接口电平至低

  18.   delayMicroseconds(20000-pulsewidth);

  19. }
  20. void setup()
  21. {
  22.    myGLCD.InitLCD();
  23.   Serial.begin(9600);
  24.   pinMode(BL,OUTPUT);
  25.   pinMode(servopin,OUTPUT);
  26.   myGLCD.setFont(SmallFont);
  27.   SPI.begin();
  28.   rfid.init();
  29. }

  30. void loop()
  31. {
  32. /* int val1=analogRead(sensor);
  33. if(val1>200)
  34.   {analogWrite(BL,512);}
  35.   else
  36.   {digitalWrite(BL,LOW);}*/
  37. //通过光敏,控制5110的背光

  38.   long randNumber = random(0, 20);

  39.   
  40.   unsigned char i,tmp;
  41.   unsigned char status;
  42.   unsigned char str[MAX_LEN];
  43.   unsigned char RC_size;

  44.   //找卡
  45.   rfid.isCard();
  46.   //读取卡序列号
  47.   if (rfid.readCardSerial())
  48.   {
  49.     Serial.print("The card's number is  : ");
  50.     Serial.print(rfid.serNum[0]);
  51.     Serial.print(" , ");
  52.     Serial.print(rfid.serNum[1],BIN);
  53.     Serial.print(" , ");
  54.     Serial.print(rfid.serNum[2],BIN);
  55.     Serial.print(" , ");
  56.     Serial.print(rfid.serNum[2],BIN);
  57.     Serial.print(" , ");
  58.     Serial.print(rfid.serNum[4],BIN);
  59.     Serial.println(" ");

  60.     if(rfid.serNum[0]==205||rfid.serNum[0]==170||rfid.serNum[0]==219||rfid.serNum[0]==117||rfid.serNum[0]==155){
  61.       for(int i=0;i<100;i++)
  62.       {
  63.         servopulse(45);
  64.         if(rfid.serNum[0]==205||rfid.serNum[0]==117||rfid.serNum[0]==155)
  65.         {
  66.           myGLCD.clrScr();
  67.           Serial.println("Welcome Mr.Xiao");
  68.           myGLCD.print("Welcome",int(randNumber)+20,int(randNumber));
  69.           myGLCD.print("Mr.Xiao",int(randNumber)+20,int(randNumber)+20);
  70.           analogWrite(BL,HIGH);
  71.         }
  72.         if(rfid.serNum[0]==219)
  73.         {
  74.           myGLCD.clrScr();
  75.           Serial.println("Welcome Mr.Yang");
  76.            myGLCD.print("Welcome",int(randNumber)+20,int(randNumber));
  77.           myGLCD.print("Mr.Yang",int(randNumber)+20,int(randNumber)+20);
  78.           digitalWrite(BL,HIGH);
  79.         }
  80.         if(rfid.serNum[0]==170)
  81.         {
  82.           myGLCD.clrScr();
  83.           Serial.println("Welcome Mr.Huang");
  84.         myGLCD.print("Welcome",int(randNumber)+20,int(randNumber));
  85.           myGLCD.print("Mr.Huang",int(randNumber)+20,int(randNumber)+20);
  86.           digitalWrite(BL,HIGH);
  87.         }
  88.         
  89.       }      //引用脉冲函数
  90.     delay(3000);
  91.     for(int i=0;i<100;i++)
  92.       {
  93.         servopulse(0);
  94.       }
  95.   }
  96.   }  
  97.     if (!rfid.readCardSerial()){
  98.       
  99.       digitalWrite(servopin,LOW);
  100.       digitalWrite(BL,LOW);
  101.   }
  102.     rfid.halt();                //指挥卡进入睡眠模式            
  103.   }
复制代码

      
这里有两个库文件
           

(3)        试验品1.0
电路连接的部分结束后,我使用了比较简陋的纸壳将整个装置包装起来,将电路部分固定在了里面。然后将整个包装粘合在门后,其中读卡器是在门缝走线(还好是木门O(∩_∩)O哈哈~)。
   

这里有个效果视频


这里有几个问题,希望可以和大家探讨下:
1.电源供电部分?不知道有没有更好的供电方案,那个舵机供电太烦恼了,不得不用有两头供电的移动电源。
2.有没有自动激活好方法?希望能够实现晚上系统断电,早上系统激活工作。这样可以增强系统续航力。
3.更好的用户界面,像欢迎,查询。用点阵还是液晶屏?

以上只是我想法的最基础版本,可以说是系统1.0版吧,但这样已经完成了最初的预想。我想这个基础版还是有很大的发展空间,完全可以基于此,进一步使整个寝室智能化。下一步我想加强系统的稳定性,以及增加密码键功能,开发出2.0,3.0版本。也希望有兴趣的朋友那个给出宝贵的建议,大家一起分享快乐。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2014-1-2 17:12:41 | 显示全部楼层
本帖最后由 code-AR 于 2015-5-16 18:52 编辑

占楼备用...

      占楼一年多了,还是没填坑。惭愧呀!!!

      现在填些坑吧,后来版本我加入了休眠机制,进一步降低了功耗,一块5000mAH的移动电源可以支持一个星期没问题。新版本在我的寝室已经正常工作了半年多了吧。如果还想减低功耗,就要自己绘制电路开板了,麻烦了就搁置了。
     硬件方面就是比原来的版本多了个外部唤醒的开关,去除了内部的显示屏,在这里把新的代码贴下
  1. #include<SPI.h>
  2. #include<RFID.h>
  3. #include <Enerlib.h>//低功耗公共库
  4. #define servopin 7

  5. Energy energy;             // 宣告"Energy"程式物件

  6. const byte swPin = 2;      // 外部开关引脚
  7. byte times = 0;            // 记录睡眠状态
  8. volatile byte state = 0;  

  9. RFID rfid(10,8);
  10. //4字节卡序列号,第5字节为校验字节
  11. unsigned char serNum[5];

  12. void servopulse(int angle)//定义一个脉冲函数

  13. {

  14.   int pulsewidth=(angle*11)+500;  //将角度转化为500-2480的脉宽值

  15.   digitalWrite(servopin,HIGH);    //将舵机接口电平至高

  16.   delayMicroseconds(pulsewidth);  //延时脉宽值的微秒数

  17.   digitalWrite(servopin,LOW);     //将舵机接口电平至低

  18.   delayMicroseconds(20000-pulsewidth);

  19. }
  20. void wakeISR() {
  21.   if (energy.WasSleeping()) {
  22.     state = 1;
  23.   }
  24.   else {
  25.     state = 2;
  26.   }
  27. }

  28. void setup()
  29. {
  30.   //Serial.begin(9600);
  31.   attachInterrupt(0, wakeISR,RISING);//CHANGE);
  32.   pinMode(servopin,OUTPUT);
  33.   SPI.begin();
  34.   rfid.init();
  35. }

  36. void loop()
  37. {
  38.   unsigned char i,tmp;
  39.   unsigned char status;
  40.   unsigned char str[MAX_LEN];
  41.   unsigned char RC_size;

  42.   if (state == 1) {
  43.     //Serial.println("Was sleeping...");
  44.   }
  45.   else if (state == 2) {
  46.     //Serial.println("Was awake...");
  47.   }
  48.   state = 0;

  49.   //找卡
  50.   rfid.isCard();
  51.   //读取卡序列号
  52.   if (rfid.readCardSerial())
  53.   {
  54.     if(rfid.serNum[0]==155||rfid.serNum[0]==234||rfid.serNum[0]==219){
  55.       for(int i=0;i<100;i++)
  56.       {
  57.         servopulse(45);        
  58.       }      //引用脉冲函数
  59.       delay(3000);
  60.       for(int i=0;i<100;i++)
  61.       {
  62.         servopulse(0);
  63.       }
  64.     }
  65.   }  
  66.   if (!rfid.readCardSerial()){
  67.     digitalWrite(servopin,LOW);  
  68.   }
  69.   if(!rfid.isCard())
  70.   {
  71.     energy.PowerDown();      
  72.   }
  73.   rfid.halt();                //指挥卡进入睡眠模式
  74. }

复制代码


低功耗库下方

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2014-1-2 17:38:07 | 显示全部楼层
哈哈,小心读卡模块被人偷走哦~~~~~
回复 支持 反对

使用道具 举报

发表于 2014-1-2 17:53:28 | 显示全部楼层
读卡器放在门里边读不到卡吗?如果被人拿走不哭死,移动电源多长时间充次电?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-2 18:59:50 | 显示全部楼层
Cupid 发表于 2014-1-2 17:53
读卡器放在门里边读不到卡吗?如果被人拿走不哭死,移动电源多长时间充次电?

一般可以支持3-4天,所以希望改进供电部分。
回复 支持 反对

使用道具 举报

发表于 2014-1-2 19:20:20 来自手机 | 显示全部楼层
Damn_intuition 发表于 2014-1-2 17:38
哈哈,小心读卡模块被人偷走哦~~~~~

嗯嗯,直接拿走好了
回复 支持 反对

使用道具 举报

发表于 2014-1-2 22:12:59 | 显示全部楼层
几十块买个磁性门锁,控制电路依然是你那套东西,完美了
回复 支持 反对

使用道具 举报

发表于 2014-1-2 23:03:27 | 显示全部楼层
pipapi 发表于 2014-1-2 22:12
几十块买个磁性门锁,控制电路依然是你那套东西,完美了

有道理 这个应该是个比较好的方案 我也看一下比如下面这个

http://item.taobao.com/item.htm? ... &id=18770053569
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-3 00:06:10 | 显示全部楼层
pipapi 发表于 2014-1-2 22:12
几十块买个磁性门锁,控制电路依然是你那套东西,完美了

这个是寝室,还不太敢拆门锁
回复 支持 反对

使用道具 举报

发表于 2014-1-3 09:29:45 | 显示全部楼层
门是铁的吗?隔着铁不是RC522不能用了吗?
回复 支持 反对

使用道具 举报

发表于 2014-1-3 10:15:34 | 显示全部楼层
不用时是可以完全断电的吧,在门外加个电源开关,打开才真正供电就可以了吧
回复 支持 反对

使用道具 举报

发表于 2014-1-3 10:18:36 | 显示全部楼层
好像就是破 木板门龙骨加胶合板那种吧,可惜估计不敢拆,不然背面开洞,读卡模块贴在前面薄板的背面估计就可读了
回复 支持 反对

使用道具 举报

发表于 2014-1-3 13:30:27 | 显示全部楼层
嗯,在外面放个开关,刷卡的时候再通电,这样能省很多电
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-3 14:21:00 | 显示全部楼层
chaqing 发表于 2014-1-3 10:18
好像就是破 木板门龙骨加胶合板那种吧,可惜估计不敢拆,不然背面开洞,读卡模块贴在前面薄板的背面估计就可 ...

这个的确是,就不知道RFID的模块可不可以通过神马手段增加距离,这样就方便了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-1-3 14:21:57 | 显示全部楼层
shenhaiyu 发表于 2014-1-3 13:30
嗯,在外面放个开关,刷卡的时候再通电,这样能省很多电

这样感觉有些麻烦,还要先启动开关。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-19 14:51 , Processed in 0.042369 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表