毕业设计 - 基于树莓派的指纹打卡器


1 简介

Hi,大家好,今天向大家介绍一个学长做的单片机项目

基于树莓派的指纹打卡器

大家可用于 课程设计 或 毕业设计

2 主要器件

  • 树莓派一台
  • 指纹模块(AS608光学指纹识别模块)
  • OLED液晶屏
  • usb转TTL
  • 杜邦线

3 实现效果

在这里插入图片描述

5 部分实现代码

树莓派驱动gpio接收指纹模块数据:

1 # -*-coding=utf8-*-
  2 
  3 import serial
  4 import serial.tools.list_ports
  5 
  6 import os, sys
  7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  8 sys.path.append(PATH)
  9 
 10 SureCore = {
 11     0x00: True,  # 表示指令执行完毕或OK;
 12     0x01: 101,  # 表示数据包接收错误;
 13     0x02: 102,  # 表示传感器上没有手指;
 14     0x03: 103,  # 表示录入指纹图像失败;
 15     0x06: 202,  # 表示指纹图像太乱而生不成特征;
 16     0x07: 203,  # 表示指纹图像正常,但特征点太少而生不成特征;
 17     0x15: 204,  # 表示图像缓冲区内没有有效原始图而生不成图像;
 18     0x08: 302,  # 表示指纹不匹配;
 19     0x09: 402,  # 表示没搜索到;此时页码与得分为 0
 20     0x0a: 502,  # 表示合并失败(两枚指纹不属于同一手指);
 21     0x0d: 802,  # 表示指令执行失败;
 22     0x0f: 1002,  # 表示不能发送后续数据包;
 23 }
 24 '''返回= 999 校验和错误'''
 25 
 26 
 27 class DealBuff:
 28     """切割收到的数据"""
 29     HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
 30 
 31     def __init__(self, buff):
 32         self.buff = buff
 33         """处理读出的指纹数据用到"""
 34         self.tag = list()  # 包标识
 35         self.data = list()
 36         self.check = list()
 37         pass
 38 
 39     def read(self):
 40         buff = [x for x in bytes(self.buff)]
 41         check = self.slit(buff)
 42         return self.tag, self.data, check
 43 
 44     def listCut(self, buff, num):
 45         """切割数组"""
 46         rec = list()
 47         for i in range(num):
 48             bytes_buf = (buff.pop(0))
 49             # rec.append(buff.pop(0))
 50             rec.append(bytes_buf)
 51         return rec, buff
 52         pass
 53 
 54     def slit(self, buff):
 55         """"选择数据"""
 56         # 初始化中间变量
 57         popList = list()
 58         check_Num = 0
 59         check = list()
 60         head = list()
 61 
 62         if len(buff) < 6:  # 判断是否有效数据
 63             return True
 64 
 65         head, buff = self.listCut(buff, 6)  # 选择出头及判断
 66         for i in range(6):
 67             if head[i] != self.HEAD[i]:
 68                 return False
 69 
 70         popList, buff = self.listCut(buff, 1)  # 取出包标识
 71         self.tag.append(popList)
 72         check_Num += popList[0]  # 计算校验和
 73 
 74         popList, buff = self.listCut(buff, 2)  # 取出包长度
 75         check_Num += popList[0] + popList[1]  # 计算校验和
 76 
 77         popList, buff = self.listCut(buff, popList[0] * 16 + popList[1])  # 取出包数据
 78         check.append(popList.pop())  # 取出校验数据
 79         check.append(popList.pop())
 80         for i in popList:  # 计算校验和
 81             check_Num += i
 82 
 83         self.data.extend(popList)  # 导入有用数据
 84         if check_Num % 65535 != check[0] + check[1]*256:  # 检验校验和
 85             return False
 86 
 87         rec = self.slit(buff)  # 得到是否正确分析完数据
 88         return rec
 89         pass
 90 
 91     def write(self):
 92         """要写的数据打包"""
 93         pack = self.dataSeparate(self.buff, 128)   # 将数据分成每组128个元素
 94         return pack
 95         pass
 96 
 97     def dataSeparate(self, buff, numPart):
 98         """把数据分组打包"""
 99         num = int(len(buff) / numPart)
100         newData = list()
101         for i in range(num):
102             newData.append(buff[i * numPart:(i+1) * numPart])
103 
104         packData = list()
105         for i in range(num-1):
106             data = self.packData(newData[i], 0x02)  # 数据包没结束
107             packData.extend(data)
108 
109         packData.extend(self.packData(newData[num-1], 0x08))  # 数据包结束
110         return packData
111         pass
112 
113     def packData(self, buff, flage):
114         num = len(buff) + 2
115         senddata = [flage, int(num / 256), int(num % 256)] + buff
116         sum = 0
117         for i in senddata:
118             sum += i
119         senddata = self.HEAD + senddata
120         senddata.append(int(sum / 256))
121         senddata.append(int(sum % 256))
122         return senddata
123         pass
124 
125     pass
126 
127 
128 class DealFingeer:
129     """和指纹模块交互"""
130     HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
131     tag = list()  # 包标识
132     cmd = list()  #
133     data = list()
134     ser = serial.Serial()
135     def __init__(self, cmd, data=None, server=None):
136         """初始化函数"""
137         self.cmd = cmd
138         self.data = data
139         self.server = server
140         pass
141 
142     def run(self):
143         if hasattr(self, self.cmd):
144             func = getattr(self, self.cmd)
145             return func(self.data)
146         pass
147 
148     def link(self):
149         """连接串口"""
150         self.ser.port = "COM5"
151         self.ser.baudrate = 57600
152         self.ser.bytesize = 8
153         self.ser.parity = 'N'
154         self.ser.xonxoff = 0
155         self.ser.rtscts = 0
156         self.ser.close()
157         self.ser.open()
158         pass
159 
160     def finger(self, data):
161         self.link()
162         check = self.getImage()  # 检测获取图像
163         if check is not True:
164             return check, []
165 
166         self.link()
167         check = self.genChar(data)  # 检测生成特征值
168         if check is not True:
169             return check, []
170         # ================= 生成特征值时图像会清除,所以要重新采集 ========================== #
171         self.link()
172         check = self.getImage()  # 检测获取图像
173         if check is not True:
174             return check, []
175 
176         if self.server is not None:
177             self.server.send("True".encode("utf8"))  # 发送数据说明准备好了
178 
179         self.link()
180         check = self.upImage()  # 上传图像
181         if check is not True:    # 校验和错误
182             return check, []
183         self.tag, self.data = self.getUpImage()
184 
185         if len(self.tag) is 0 and len(self.data) is 0:  # 得到数据错误
186             return False, []
187         return True, []
188 
189     def save(self, data=None):
190         self.link()
191         check = self.regModel()
192         if check is not True:    # 校验和错误
193             return check, []
194 
195         self.link()
196         check = self.upChar(data)  # 上传特征值
197         if check is not True:  # 校验和错误
198             return check, []
199         self.tag, self.data = self.getUpChar()
200 
201         if len(self.tag) is 0 and len(self.data) is 0:  # 得到数据错误
202             return False, []
203         return True, []
204         pass
205 
206     def check(self, data=None):
207         """检验指纹, 生成特征值"""
208         self.link()
209         check = self.match()   # 比较指纹特征
210         if check is not True:
211             return check, []
212         score = self.data[1]*255 + self.data[2]  # 返回的分数值
213 
214         self.link()
215         check = self.regModel()  # 合成指纹特征值
216         if check is not True:
217             return check, []
218         return True, score
219         pass
220 
221     def isFinger(self, data=None):
222         """判断现在的指纹和下载的指纹是否相同"""
223         self.link()
224         check = self.downCharCheck()
225         if check is not True:    # 判断是否可以发送数据
226             return check, []
227         """下载指纹"""
228         self.link()
229         self.downCharData(data)
230         """检验指纹"""
231         self.link()
232         check = self.match()
233         if check is not True:
234             return check, []
235         score = self.data[1] * 255 + self.data[2]  # 返回的分数值
236         return True, score
237         pass
238 
239     def getImage(self, data=None):
240         """获取图像"""
241         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05]   # 发送命令获取内容
242         return self.isOk(cmd, 12)
243         pass
244 
245     def genChar(self, data=None):
246         """生成特征文件"""
247         if data == "1":
248             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x01, 0x00, 0x08]  # 发送命令
249             return self.isOk(cmd, 12)  # 图像接收数据 12 大小
250         elif data == "2":
251             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x02, 0x02, 0x00, 0x09]  # 发送命令
252             return self.isOk(cmd, 12)  # 图像接收数据 12 大小
253         pass
254 
255     def match(self, data=None):
256         """比较指纹特征"""
257         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x03, 0x00, 0x07]   # 发送命令获取内容
258         return self.isOk(cmd, 14)
259         pass
260 
261     def regModel(self, data=None):
262         """合成指纹特征值"""
263         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09]   # 发送命令获取内容
264         return self.isOk(cmd, 12)
265         pass
266 
267     def upChar(self, data=None):
268         """上传特征模块检测"""
269         buff = bytes()
270         if data == "1":
271             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x01, 0x00, 0x0e]  # 发送命令
272             return self.isOk(cmd, 12, False)
273         elif data == "2":
274             cmd = self.HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0F]  # 发送命令
275             return self.isOk(cmd, 12, False)
276         pass
277 
278     def getUpChar(self, data=None):
279         """上传特征模块数据"""
280         buff = self.ser.read(834)
281         self.ser.close()
282         subpackage = DealBuff(buff)   # 分割内容
283         self.tag, self.data, check = subpackage.read()
284         if check is not True:    # 校验和错误
285             return 999
286         return self.tag, self.data
287 
288     def downCharCheck(self, data=None):
289         """
290         下载特征值检测
291         先要初始化,发送获取图像命令
292         """
293         self.getImage()
294         self.link()
295         cmd = self.HEAD + [0x01, 0x00, 0x04, 0x09, 0x02, 0x00, 0x10]  # 发送命令 下载的数据放在buff2中
296         return self.isOk(cmd, 12)
297         pass
298 
299     def downCharData(self, data):
300         """下载特征值的数据"""
301         self.writeRead(data, 0)  # 发送数据 接收为0
302         pass
303 
304 
305     def upImage(self, data=None):
306         """上传图像检测"""
307         cmd = self.HEAD + [0x01, 0x00, 0x03, 0x0a, 0x00, 0x0e]  # 发送命令
308         return self.isOk(cmd, 12, False)
309         pass
310 
311     def getUpImage(self, data=None):
312         """获取后续的图像数据"""
313         buff = self.ser.read(40032)
314         self.ser.close()
315         subpackage = DealBuff(buff)   # 分割内容
316         self.tag, self.data, check = subpackage.read()
317         if check is not True:    # 校验和错误
318             return [], []
319         return self.tag, self.data
320 
321     def writeRead(self, cmd, length, close=True):
322         """发送命令读取原始字节"""
323         cmd = bytes(cmd)
324         self.ser.write(cmd)
325         buff = self.ser.read(length)   # 图像接收数据
326         if close:
327             self.ser.close()    # 接受完数据断开com
328         return buff
329         pass
330 
331     def isOk(self, cmd, length, close=True):
332         """判断数据是否合格"""
333         buff = self.writeRead(cmd, length, close)  # 图像接收数据 12 大小
334         subpackage = DealBuff(buff)   # 分割内容
335         self.tag, self.data, check = subpackage.read()
336         # 检验数据是否可靠
337         if check is not True:   # 校验和错误
338             return 999
339         return self.check_code(self.data)
340         pass
341 
342     def check_code(self, data):
343         """检验指令码"""
344         return SureCore[data[0]]
345         pass
346 
347     pass
348 
349 
350 if __name__ == "__main__":
351     # HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]
352     # data = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x03, 0x0A, 0x00, 0x0E]
353     # data = HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05]
354     # data = HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09]
355     # data = HEAD + [0x01, 0x00, 0x04, 0x08, 0x02, 0x00, 0x0f]
(篇幅有限,其他代码暂不更新,有需要联系学长)

6 最后

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值