切换到宽版
  • 15000阅读
  • 81回复

[外设]指纹+红外遥控锁+红外钥匙 制作教程 [复制链接]

上一主题 下一主题
离线liuzxi
 

发帖
25
M币
2787
专家
8
粉丝
6
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2017-02-18
— 本帖被 青柠 设置为精华,作者+3000M币+5专家(2017-04-07) —
一日在淘宝闲逛,看到一个电动锁芯,价格比较便宜,做工精良,顺便买了回来,打算改造下大门,现在指纹锁比较流行,使用也最方便,车都无钥匙进入了,大门指纹开锁是必须的。淘宝搜一下,指纹锁真贵,好的要几千大洋,最便宜的要500块。所以准备自己做一个指纹锁。

一、材料准备

1、电动锁芯

这个锁芯大部分防盗门都可以装上。

2、指纹模块

淘宝的指纹模块有光学和电容式的两种,电容式的体积小,价格便宜点。最便宜的100块,就这个了。参数看着很强大,什么几百组指纹,识别准确率巴拉巴拉,都不关心,串口通讯,应该很好控制。

3、单片机

算了一下16脚够用了,STC15W408AS  SOP16 的手上有现成的。

4、电机控制

此锁芯电机5V可以转,力小转速慢,12V应该是正常工作电压,空载电流100mA,堵转电流700mA左右。
本打算用继电器控制,两个继电器正反转,结实耐用,控制简单,但体积太大。手上还有几个L9110H H桥驱动/全桥驱动/电机驱动芯片DIP-8。这个芯片标的最大耐压12V,我用5V开关电源测试,发热比较大,12V开关电源秒烧。2S电池8.2V工作倒不热,3S电池秒烧。连着烧了两个。所以还是选2S 8.4V工作电压稳妥点。



5、5V供电
7805就行,据说效率不高, mini 360 降压模块,一直用这个,应该效率高点。


6、辅材
主要材料就这些了,还需要无源蜂鸣器,发出宾馆磁卡锁那样 滴滴答的音乐,按键提示等各种不同的音调。按钮,电阻电容,发光二极管若干。


二、原理图

1、 电源部分
实测发现 mini 360 降压模块静态功耗非常大,什么都不接,只接Vin 静态电流十几毫安,如果电池供电,2000mAh的18650锂电,只为这一个模块待机,只能坚持100个小时,也就是4天。根本不能用呀。看来这个模块需要改造,通过资料发现电源芯片的第7脚是en引脚,模块中是直接用10K电阻接在Vin上,保证通电给高电平,只要把这个引脚引出来,用单片机控制电瓶就可以关断降压模块。



图中这个引脚。



改造之后的样子。经过测试关闭之后的待机电流只有uA级别了,满足电池供电需求了。
但是问题来了。单片机把供电关闭之后自己也没电了,所以再也醒不过来了,额……
怎么办呢,只有给单片机单独供电,让单片机一直活着,才可以控制其他部件。

最终的电路图如下:

BAT为2S 18650电池,BAT1是一个旧手机的电池。电路复杂了,两个电池插座,两个电源开关,还要两个电池电压检测程序。

2、 电机控制部分
  

  
电机驱动模块,用两个1欧姆精度1%电阻并联做采样电阻,根据电流控制电机停止。

3、电源模块控制,蜂鸣器电路,指示灯电路
  

  
因为手上只有2302mos管,所以就用的这个,下拉电阻10K~100K都可以,考虑到待机功耗,所以选了100K的。用8050也可以,电阻阻值、位置换一下。

4、按钮电路
  

  
门外一个按钮,用来唤醒单片机指纹开锁,上锁。门内两个按钮一个用来直接开锁上锁,另一个用来录入指纹,清除指纹。

5 MCU部分
  


1.电源模块控制
2. 2S电池电压
3.电机电流检测
4.按钮2
5. 空
6. VCC BAT1单独供电
7. 蜂鸣器
8. GND
9. 10. 串口连接指纹模块
11.内部按钮
12. 外部按钮  并联 红外接收头
13. 14. 指示灯
15. 16. 电机正反转控制


三、PCB






手工热转印,蚀刻,单层板。制作门内门外分两块,







测试过程中发现,老人的指纹磨损,很难识别,所以加入了红外密码开锁,红外接收头和门外按钮公用一个引脚。


四、程序部分

/****************************************************************************
  
/*2016-12-21 指纹模块测试,写指纹  
门外按钮 短按 按下红灯亮,等待搜索指纹,正确红灯灭,蜂鸣器123,错误蜂鸣器4  
门外按钮 长按  反转反锁  
门内按钮1,短按绿灯亮,直接开锁
门内按钮1,长按 反转反锁  
门内按钮2 长按 等待管理员指纹录入,检测5次,正确,录入新指纹 连续录入5次,正确红灯闪烁,5次后,熄灭  
门内按钮2 长长按 等待管理员指纹录入,检测5次,正确,清除所有指纹

/*2016-12-24 所有功能实现     加入休眠功能
  
/*2017-1-15 单片机测量电机电流,电池电压,内部带隙电压  
滴滴滴滴滴滴  单片机电池低   滴答滴答滴答  电机电池低压

/*2017-1-22 加入红外遥控密码开锁

*************************************************************/

  

#include "intrins.h"

#include "IR.h"

#include <SERIAL.c>

#include <usartdrive.c>

#include "time0.h"  //定时器初始化   软件延时函数

#include "stc_ad.h"   //adc函数

/*****************************/
  
//51单片机的时钟晶振大小为11.0592Mhz
  
/****************************/
  
//typedef unsigned char uchar;
  
//typedef unsigned int uint;  

#define MAX 0x0e    //电机堵转电流

#define BatLow 176           //电池电压最低值

#define batVPin 3               //电池电压管脚

#define CurrPin 4              // 电机电流管脚

#define ClocsKey 0xFF       //红外锁门 按键代码

#define        btnOut P_IR_RX               //外部按钮和红外接收公用一脚

sfr P5 =  0xC8;   //xxxx,1111 端口5

sfr P0M0 = 0x94; //               0000,0000

sfr P0M1 = 0x93; //  

sfr P1M0 = 0x92; //               0000,0000

sfr P1M1 = 0x91; //    

sfr P3M0 = 0xB2;   //0000,0000 端口3模式寄存器0

sfr P3M1 = 0xB1;   //0000,0000 端口3模式寄存器1

sfr P5M0 = 0xCA;   //0000,0000 端口5模式寄存器0

sfr P5M1 = 0xC9;   //0000,0000 端口5模式寄存器1

//sfr WDT_CONTR   =  0xC1;   //0000,0000 看门狗控制寄存器

sfr ISP_CONTR=0xe7;



///////////////////管脚定义////////////////////////



//sbit btnOut=P3^3;//中断0 唤醒休眠用   /外部按钮和红外接收公用一脚

sbit btnIn=P3^2;  //中断1 唤醒休眠用  内部按钮

sbit btnSet=P1^5;  //设置指纹按下接地为0

sbit LedR=P3^7;                //门外灯

sbit LedG=P3^6;                //门内指示灯

sbit buzzer = P5^5;              //控制三极管 推动蜂鸣器

sbit power = P1^2;              //控制三极管 给除单片机外部件供电

sbit close=P1^1;                  //控制电机正反转

sbit open=P1^0;                            //  这四个脚需要强推挽

// 1.3 ADC 电池电压 1.4ADC 电机电流

  

////////////////  变量声明////////////////  


bit set1=0,set2=0,set3=0,set4=0   ,set5=0;   //按钮动作功能位  set1  指纹开锁  set2 录入指纹 set3 上锁  set4 清所有指纹          set5 直接开锁

bit    master=0; //管理员标志

bit    locked=0; //已锁标志

uchar current;   //电机电流          堵转 值0x0e

uint count=0;   //计数 10次 扫描按键动作

uchar j=0,i=0;

uint Num;

uint btnPressSum=0;          //按钮长按计数

long int t=0;     //time0 计时

uint mcuV ,batV; //1s电池电压   2s电池电压




//////////////函数声明//////////////////


void fengming(uint x,uint y);              //蜂鸣器发声

void buzz(uint No);                                           //蜂鸣器奏乐 参数 123   321   1 2 3    4(低音do)

void btnScan();   //按钮扫描

void fingerOpenLock();              //指纹开锁

void openLock();                          //直接开锁

void closeLock();                         //上锁反锁

void getFinger();                         //录入新指纹

void clearFinger();                      //清空指纹

void chkMaster();                       //检查管理员

void chkBat();              //检查电池电压

void IRopenLock();                      //红外密码开锁

void main()

{        

   InitADC();  

         power=0;   //打开降压供电模块

   Timer0Init();

         serial_init();

         Delay(500);

         P5M0|=   0x20;

         P5M1=    0x00;           //P5.5 强推挽

         P3M0=0xC0;    //P3.6 3.7  强推挽          1100 0000

         P3M1=    0x00;

         P1M0=0x07;    //                          //  P1.0 1.1 1.2 强推挽       0000 0111
  
         P1M1=    0x00;    

         open=0;close=0;      LedR=0;   LedG=0;buzzer=0;          
         chkBat();  //检查电池电压

         while(1)

     {
                   btnScan();

                   if(set1)

                   {  
                            buzz(3);
                            set1=0;
                            fingerOpenLock();

                   }

                   if(set2)

                   {
                            buzz(3);

                            set2=0;

                            getFinger();

                   }

                   if(set3)


                   {


                            set3=0;


                            closeLock();


                   }


                   if(set4)


                   {


                            set4=0;    


                            clearFinger();//删除所有指纹                                    


                   }


                   if(set5)
                   {
                            set5= 0;  
                            chkBat();  
                            openLock();//直接开锁  
                   }  
                   IRopenLock();  
         }
}

  

/////////按钮扫描////////////


void btnScan()
{
   count++;

         if(count==10)

         {

               count=0;

                   if(btnOut==0)Delay(50);   //消抖

                   while(btnOut==0&&B_IR_Press==0)       //是外部按键 并且不是红外按键

                   {

                            btnPressSum++;

                            Delay(10);

                            if(btnPressSum>200)

                            {
                                     break;  
                            }
                   }
  
                   if(btnPressSum>200)

                   {  
                            set3=1;
                   }

                   elseif(btnPressSum>10)

                   {

                            set1=1;

                   }

                   btnPressSum=0;

                   if(btnIn==0)Delay(50);

                   while(btnIn==0)

                   {

                            btnPressSum++;

                            Delay(10);

                            if(btnPressSum>200)

                            {
                                     break;

                            }
                   }
  
                   if(btnPressSum>200)

                   {
                            set3=1;

                   }

                   elseif(btnPressSum>10)

                   {  
                            set5=1;

                   }

                   btnPressSum=0;

                   if(btnSet==0)Delay(50);

                   while(btnSet==0)

                   {


                            btnPressSum++;


                            Delay(10);


                            if(btnPressSum>200)


                            {


                                     break;


                            }        


                   }


                   if(btnPressSum>200)


                   {


                            set4=1;


                   }


                   elseif(btnPressSum>50)


                   {


                            set2=1;


                   }


                   btnPressSum=0;      


     }


}





void openLock()


{


         buzz(123);t=0;


         open= 1;close=0 ; LedG = 1;


         Delay(500);                                                     //避开启动电流


         do


         {


                   if(t>48000)break;         //如果6秒还未检测到电机堵转 停电机


                   current= FliterADC(CurrPin);


//               putbyte(current);                        ADC  电机电流


         }while (current<MAX);


         open= 0; LedG = 0; locked = 0;


         buzz(123);


         Delay(2000);


         close= 1;


         Delay(300);//回锁舌


         close= 0;


}


void fingerOpenLock()


{


         //current=0;


         LedR=1;             t=0;


         if(指纹验证通过()==1)     //


         {


                   openLock();


         }


         else


         {        


                   buzz(4);


         }


         LedR=0;  


}





void closeLock()


{


         t=0;


         if(!locked)


         {


                   locked=1;


                   close=1;open=0;LedG=1;


                   buzz(321);


                   Delay(500);


         do


         {


                   if(t>48000)break;  


                   current= FliterADC(CurrPin);


                   //      putbyte(current);                        //ADC  电机电流


         }while (current<MAX);


                   close=0;LedG=0;              


         }


         buzz(321);


}








void getFinger()   //录入指纹


{


         LedR=1;    


         j=0;t=0;     //耗时长的操作,定时器清零,避免1分钟后休眠





         if(Num==0)                                             //如果指纹库为空,直接录入指纹


         {


                   master=1;


         }


         else


         {


                    chkMaster();


         }        


         if(master)                     //管理员


         {


                   LedG=1;


                   master=0;


                   j=0;            


                   while(j<5)


                   {


                            if(写入指纹==1)


                            {


                                     j++;


                                     Num++;


                                     buzz(3);                                


                            }


             }


                   if(写入指纹==1);


                   {





                            buzz(321);


                   }        


         }


         LedG=0;LedR=0;                                          


}


void clearFinger()        //清除所有指纹


{


         LedR=1;j=0;


         buzz(1);buzz(1);buzz(1);buzz(1);buzz(1);buzz(1);  //清指纹提醒


         chkMaster();


         if(master)


         {


                   LedG=1;


                   master=0;


                   if((清空指纹))  // 清空指纹


                   {


                            buzz(3);            


                   }


                   else


                   {


                            buzz(1);    


                   }        


         }


         LedG=0;LedR=0;


}





void chkMaster()        //验证管理员


{


         while(!master)


         {


                   if(j==5)


                   {


                            //LedG=1;LedR=1;


                            buzz(4);


                            break;


                   }


                   if(管理员验证成功)  //管理员验证成功


                   {


                            master=1;


                            buzz(123);


                   }


                   else


                   {        


                            buzz(4);


                   }


                   j++;  


         }


}


void chkBat()    //检查电池电压


{


         P1ASF= 0x00;              


         //                          //带隙电压  5V 为0x40(64)   3.3V 为0x 5F       3.0v为0x68


         mcuV=FliterADC(0);


//      putbyte(mcuV);        


         if(      mcuV>0x5f )                                   //mcu工作电压=5*64/带隙电压测量值  


         {


                   buzz(4);buzz(4);buzz(4);buzz(4);buzz(4);buzz(4);


         }  


         else


         {


                   buzz(1);


         }





         P1ASF= 0x18;


          //电池电压经20K 10K分压 ,测量点电压为电池电压1/3 2s锂电放电下限为6.6v ,分压后为2.2v


          //电池电压通道ADC的结果与mcu工作电压的关系   电池电压= mcu电压*adc测量值/256  


          //2.2v     时 adc/mcuv应>1.76


          batV= FliterADC(batVPin);


          batV=batV*100/mcuV;


//             putbyte(batV);


         if(batV<BatLow)                                  





         {


                   buzz(4);buzz(1); buzz(4); buzz(1);buzz(4); buzz(1);


         }


         else


         {


                   buzz(1);


         }                          





}


voidIRopenLock()   //红外密码验证


{


         if(B_IR_Press)           //有IR键按下


         {


                   LedR=1;Delay(10);LedR=0;buzz(1);


                   B_IR_Press= 0;        


                   if(B_IrUserErr==0)


                   {


                            if(IR_code==ClocsKey)      //如果是锁门按键 锁门


                            {


                                     set3=1;


                            }
                            else
                            {

                                     buf[k++]=IR_code;

                            }
                   }

                   if(k==passLen)

                   {

                            for(k=0;k<passLen;k++)

                            {

                                     if(buf[k]!=passChar[password[k]])

                                               break;

                            }

                            if(k==passLen)

                            {

                                      set5=1;

                                     //  putbytes("OK ");

                             }
                            else
                            {  
                                     buzz(4);buzz(4);

                            }

                            k=0;  
                   }  
         }
}


////////////////////////////////////


/*蜂鸣器函数 */


////////////////////////////////////


void fengming(uint x,uint y)       //x时长,y音调
  
{        
  
         uinti;


         for(i=0;i<x;i++)


         {


                   buzzer=~buzzer;


                   Delayus(y);


         }


}

void buzz(uint No)

{
         uinti=0;

         uintshengdiao[]={478,0451,0426,0402,0372};       //中1DO 523Hz0956us  中2RE 578 0842    中3M 659 0759
  
                                         //高1DO 10460478         #DO# 1109 0451    高2RE 1175 0426 #2RE#1245 0402          高3M 1318 0372
  
         switch(No)
  
         {        

                   case1:     for(i=0;i<3;i++)

                                     {
  
                                               fengming(62,478);            

                                      }
  
                                     break;

                   case2:     for(i=0;i<3;i++)

                                     {
                                               fengming(70,426);

                                     }

                                     break;

                   case3: for(i=0;i<3;i++)                       //高5SO 15680319  

                                     {

                                               fengming(94,319);
                                     }
                                     break;

                   case4: for(i=0;i<3;i++)

                                     {

                                               fengming(31,956);//低音do 错误用    

                                               Delayus(1000);      


                                     }

                                     break;        

                   case123: for(i=0;i<5;i++)  
                                     {  
                                               fengming(30000/shengdiao,shengdiao);          
  
                                               Delayus(500);
  
                                     }
  
                                       break;  

                   case321:for(i=5;i>0;i--)
  
                                     {

                                               fengming(30000/shengdiao,shengdiao);          

                                               Delayus(500);
                                     }

         }        

         buzzer=0;           //关蜂鸣器,省电
}

void Timer0() interrupt 1 using 1 //调用定时器0,自动重装载模式

{

         IR_RX_HT6121();                //红外接收函数//125um

   t++;                              

         if(t>480000)               //一分钟休眠 脚位清零  灭灯   关供电模块

         {

                   t=0;power=1;LedR=0;LedG=0;open=0;close=0 ;    buzzer =0;

                   PCON|= 0x02;

         }

//      TL0= 0x00;                //设置定时初值

//      TH0= 0x28;               //设置定时初值

}

void int0(void) interrupt 0

{    

         PCON&= 0xEF;

         power=0;                   //供电模块上电

}

void int1(void) interrupt 2

{    

  PCON &= 0xEF;     //按钮2唤醒

  power=0;                      //指纹模块上电

}

/*        这个函数无效果

void soft_reset(void)

{

((void (code *) (void)) 0x0000) ();

}                           */,

***************************************/


由于版权问题,不公开指纹模块驱动,和调用函数,如果购买模块厂家会提供。



如果要降低造价,可以不使用指纹模块,只使用红外密码开锁。

下面是红外接收子程序,STC官网提供,稍做修改,即可使用

随便找个遥控器,先通过以下程序读取设备码各按键码,然后挑两个放入password数组,就可以用这个遥控器开锁了。
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共12条打赏M币+130专家+3
12
离线kakarain

发帖
37
M币
607
专家
-1
粉丝
9
只看该作者 1楼 发表于: 2017-02-19
很厉害,方案程序解释的很清楚
向上吧少年
离线花谢花开

发帖
139
M币
3029
专家
7
粉丝
14
只看该作者 2楼 发表于: 2017-02-19
好厉害!感觉我自己和文盲没有区别了!
离线liuzxi

发帖
25
M币
2787
专家
8
粉丝
6
只看该作者 3楼 发表于: 2017-02-19
占楼,未完待续
在线wska

发帖
3393
M币
23270
专家
251
粉丝
256
只看该作者 4楼 发表于: 2017-02-19
马上要射精了,前排占位

内容来自Android手机客户端

离线欢庆

发帖
4
M币
-40
专家
-1
粉丝
2
只看该作者 5楼 发表于: 2017-02-19
萝丽群友前来顶贴!
离线liuzxi

发帖
25
M币
2787
专家
8
粉丝
6
只看该作者 6楼 发表于: 2017-02-19
你速度快,谢谢捧场
离线262583021

发帖
2931
M币
8698
专家
1
粉丝
5
只看该作者 7楼 发表于: 2017-02-19
萝丽群友前来顶贴!👍👍

发帖
883
M币
500
专家
1
粉丝
7
只看该作者 8楼 发表于: 2017-02-19
立马变成高端货
离线624585283

发帖
2050
M币
2218
专家
8
粉丝
46
只看该作者 9楼 发表于: 2017-02-19
厉害了,买个要一千多
嘎嘎 好东西