理论上两节2000mah入门级18650能让这个指纹锁待机456年…
剩下的0.5uA就是锂电池充电板的待机电流了。
使用方法
先看PCB的正面和背面
注意背面有一排短接引脚,用于选择旋转角度(对于360度舵机来说)
一共5个短接点 0
1
2
3
4
这五个点按照从低到高的二进制来设定角度,下列表格中,数字代表短接,下划线代表不短接,则:
短接引脚组合 |
角度 |
0 _ _ _ _ |
45 |
_ 1 _ _ _ |
90 |
0 1 _ _ _ |
135 |
_ _ 2 _ _ |
180 |
0 _ 2 _ _ |
225 |
_ 1 2 _ _ |
270 |
0 1 2 _ _ |
315 |
那么最大可旋转角度为 (2^5-1)*45 = 1395度。
PCB中 需要注意以下几点:
其中 指纹传感器排线P1的引脚定义:
排线引脚 |
目标引脚 |
备注 |
1 |
指纹3.3V |
|
2 |
指纹Tx |
|
3 |
指纹Rx |
|
4 |
指纹GND |
|
5 |
指纹WAK |
|
6 |
指纹触摸3.3 |
|
7 |
指纹USB D+ |
|
8 |
指纹USB D- |
|
9 |
触发按钮P1 |
非自锁按钮, 建议藏到指纹传感器下方 |
10 |
触发按钮P2 |
这样每次触碰到指纹的时候都会触发 |
舵机排线P3就是正常的舵机引脚顺序 GND已标出
如果要录入指纹,就先按下P2^0的按钮(也就是正面的S1),再按下指纹传感器,触发按钮,就能进入录指纹模式。
退出此模式,再长按P2^0按钮就行了。
还有就是:
注意:其中的继电器是3.3V低压继电器!!!
注意:其中的继电器是3.3V低压继电器!!!
注意:其中的继电器是3.3V低压继电器!!!
如果采用上图中的PCB,那么所有元件选型尽量(或者必须)按照下列表格来选择。
元件表
为了降低焊接难度,让更多人都能使用上这个V2.0的设计,我就把所有元件都放到正面了,所以也导致了PCB面积超过了嘉立创的5元打样限制,5张PCB下来可能得30元。
如果想要自己缩小的话,那就自己画PCB。
原理图:
当然了, 上面只是一个截图 原理图源文件在下面
原理图&PCB文件
大致说一下工作原理吧:
- 指纹按下时,微动开关触发,给单片机和NPN三极管上电,继电器导通。
- 单片机上电 第一件事就是P1^0输出高电平接管NPN三极管,此时按钮是否导通无所谓了。
- 然后指纹识别和解锁。
- 全部工作流程完毕后,P1^0输出低电平,关闭继电器,关闭全部电源。
这样,整个系统在没有指纹按下的时候,所有元件都处在关机状态。
一些细节就是这样设计,如果你指纹一直按着,开关一直导通,那他就永远不会断电,但是这个时候继电器是归单片机管的,可以用来操作继电器进行声音提示。
其实这个用场效应管+STM32来做 会更稳定。
代码部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
| #include <reg52.h> #include <stdio.h> #include <string.h>
#define LEN 128 //可以减少 只要数据包长度低于这个值即可
sbit pwm = P1^1; //PWM信号输出,连舵机黄线 sbit Relay = P1^0; //继电器引脚 sbit sw = P2^0; //模式开关引脚
//角度选定引脚 sbit angle0 = P2^1; sbit angle1 = P2^2; sbit angle2 = P2^3; sbit angle3 = P2^4; sbit angle4 = P2^5;
unsigned char count; //0.5ms次数标识 unsigned char jd; //角度标识
unsigned char xdata Data_buff[LEN]; //初始化缓存
void delayms(unsigned int i) //延时 { unsigned int j,k; for(j=i; j>0; j--) for(k=110; k>0; k--); }
void Time0_Init() //定时器0初始化 { TH0 = (65536-440)/256; //1.0851us一个计数周期 TL0 = (65536-440)%256; //初始化中断器 TMOD = 0x01; //定时器0工作在方式1 IE = 0x82; //IE=0x82=1000 0010 等价于 EA=1 开总中断 ET0=1 开定时器0中断 TR0 = 1; //开定时器0 }
void Time0_Int() interrupt 1 //中断程序 { TH0 = (65536-440)/256; //1.0851us一个计数周期 TL0 = (65536-440)%256; //重新初始化中断器 if(count< jd) { pwm = 0; //高电平次数小于目标角度,PWM输出高电平(一次高电平输出0.5ms) count=(count+1); //总次数加1 count=count%40; //确保总次数始终保持低于40 即保持周期为20ms } else { pwm = 1; //高电平次数大于等于目标角度,PWM输出低电平 count=(count+1); //总次数加1 count=count%40; //确保总次数始终保持低于40 即保持周期为20ms } }
void UART_Init(void) //波特率已最高为57600,12T 晶振11.0592MHz { SCON = 0x50; TMOD &= 0x0f; TMOD = 0x20; PCON = 0x80; TH1 = 0xFF; TL1 = 0xFF; ET1 = 0; TR1 = 1; }
//******************************************* //函数名:Send_Bytes //功能:发送多个字节 //参数:*c:首地址 len:长度 //指令代码:无 //返回值: 无 //******************************************* void Send_Bytes(unsigned char *c,unsigned char len) { unsigned char i=0; for(i=0; i<len; i++) { SBUF = *(c+i); while(!TI); TI = 0; } }
//******************************************* //函数名:Receive_Bytes //功能:接收多个字节 //参数:*c:首地址 len:长度 //指令代码:无 //返回值: 无 //******************************************* char Receive_Bytes(unsigned char *c,unsigned char len) { unsigned char i=0; unsigned long time=33000; for(i=0; i<len; i++) { while(!RI && time--) { if(time==0) return -2; } *(c+i)=SBUF; RI=0; } return 0; }
//******************************************* //函数名:PS_GetImage //功能:从传感器上读入图像存于图像缓冲区 //参数:无 //指令代码:01H //返回值:有 //******************************************* char PS_GetImage() {
unsigned char *ps2= "\xef\x01\xff\xff\xff\xff\x01\x00\x03\x01\x00\x05"; //指令码
Send_Bytes(ps2,12); //发送指令码
if(Receive_Bytes(Data_buff,12)) //接收应答包 { return -1; }
if(Data_buff[9]==0x00&&Data_buff[11]==0x0a) //判断确认码是否成功 后面为校验和判断 { return 0; }
return -1; }
//******************************************* //函数名:PS_GenChar //功能:将 ImageBuffer(图像缓冲区) 中的原始图像生成指纹特征文件存于 CharBuffer1 或 CharBuffer2 //参数:BufferID(特征缓冲区号) //指令代码:02H //返回值:有 //******************************************* char PS_GenChar(unsigned char BufferID) {
unsigned char *ps1= "\xef\x01\xff\xff\xff\xff\x01\x00\x04\x02\x01\x00\x08"; //存放CharBuffer1的指令码 unsigned char *ps2= "\xef\x01\xff\xff\xff\xff\x01\x00\x04\x02\x02\x00\x09"; //存放CharBuffer1的指令码 if(BufferID==0x01) { Send_Bytes(ps1,13); //发送指令码 } else { Send_Bytes(ps2,13); //发送指令码 }
if(Receive_Bytes(Data_buff,12)) //接收应答包 { return -1; }
if(Data_buff[9]==0x00&&Data_buff[11]==0x0a) //判断确认码是否成功 后面为校验和判断 { return 0; }
return -1; }
//******************************************* //函数名:PS_Search //功能:以 CharBuffer1 或 CharBuffer2 中的特征文件搜索整个或部分指纹库。若搜索到,则返回页码 //参数:BufferID, (StartPage(起始页),PageNum(页数))(默认从0到300全局搜索) //指令代码:04H //返回值:确认码、页码(ID) //******************************************* char PS_Search(unsigned char BufferID) {
unsigned char *ps1= "\xef\x01\xff\xff\xff\xff\x01\x00\x08\x04\x01\x00\x00\x01\x2b\x00\x3a"; //存放CharBuffer1的指令码 unsigned char *ps2= "\xef\x01\xff\xff\xff\xff\x01\x00\x08\x04\x02\x00\x00\x01\x2b\x00\x3b";
if(BufferID==0x01) { Send_Bytes(ps1,17); //发送指令码 } else { Send_Bytes(ps2,17); //发送指令码 }
if(Receive_Bytes(Data_buff,16)) //接收应答包 { return -1; }
if(Data_buff[9]==0x00) //判断确认码是否成功 { return 0; }
return -1; }
//******************************************* //函数名:ReadAngle //功能:读取硬件上选定的旋转角度 //参数:无 //返回值:unsigned char类型的数值,单位为45度 //备注: 暂时懒得移植到180度上, 修改自己N年前的代码太折磨人了。 // 也懒得用寄存器连续读取IO了... //******************************************* unsigned char ReadAngle() { unsigned char sum; unsigned char temp; //计算角度 angle0 = 1; temp = angle0; sum += (1 - temp); angle0 = 0; angle1 = 1; temp = angle1; sum += (1 - temp)*2; angle1 = 0; angle2 = 1; temp = angle2; sum += temp*4; angle2 = 0; angle3 = 1; temp = angle3; sum += (1 - temp)*8; angle3 = 0; angle4 = 1; temp = angle4; sum += (1 - temp)*16; angle4 = 0; return sum; }
/********************************************/ //360度舵机 // 0.5ms高电平 -> 最高速度正转 -> jd = 1 // 2.5ms高电平 -> 最高速度反转 -> jd = 5 // //最高速度时: // 0.1秒 -> 45度 当然 只是理论上是这样 具体自己调 /********************************************/ void unlock() { unsigned char angle; angle = ReadAngle(); delayms(100); Time0_Init(); count = 0; jd = 1; delayms(angle*200); jd = 3; delayms(3000); jd = 5; delayms(angle*200); Relay = 0; }
/********************************************/ //180度舵机 // 1.0ms高电平 -> 0度 // 2.5ms高电平 -> 180度 /********************************************/ /* void unlock() { delayms(100); Time0_Init(); count=0; jd = 5; delayms(3000); count=0; jd = 2; delayms(1000); Relay = 0; } */
int main() { char status; Relay = 1; sw = 1; status = sw; while (!status) { delayms(3000); sw = 1; if(sw == 0) Relay = 0; } RI=0; while(1) { UART_Init(); if(PS_GetImage() == 0) { if(PS_GenChar(0x01) == 0) { if(PS_Search(0x01) == 0) { unlock(); } else { while(1) { Relay = 0; delayms(300); Relay = 1; delayms(300); } } } else Relay = 0; } else Relay = 0; } }
|
外壳部分
这回改进了下指纹传感器,藏了一个小微动开关在指纹传感器下面,每次指纹识别都会触发按钮,也不用每次都特意的额外的按下按钮
然后又给指纹传感器设计了个外壳,方便安装和放置微动开关
侧边的小凹槽是用来安装自锁扎带的,就是这种↓
可以用来帮到门把手之类的地方,实在不行就直接把整个外壳用热熔胶粘到门上
更新日志
2020-02-15
解决了无法进入录指纹模式的bug 优化了1字节的Rom空间
指纹锁V2.0基本上就要进入过去式了 因为物联网的V3要出了
2020-07-31
好多网友自己手焊都翻车了 然后我就直接做一个PCB文件吧,需要的自己去打样。
不过这个PCB的新特性我还没写相关代码。
因为为了照顾绝大多数小白,我把PCB分为了两个版本,一个版本是单面焊接纯直插原件的,一个是双面全贴片的。
不过为了降低难度,单面全直插的PCB体积超过了嘉立创的10*10cm的优惠限制..可能会贵一点..
上面说的物联网的V3 程序写好了,一直懒得焊电路调试…
2020-08-17
还是好多人来问。。于是我就重写了一遍文档。
以后打死也不碰这个坑爹51了。
Video
emmm暂时还没上传 先别急蛤。
DownLoad
外壳设计图
PCB文件