文章目录
1 简介2 主要器件3 实现效果5 部分实现代码6 最后1 简介
Hi,大家好,今天向大家介绍一个学长做的单片机项目
基于树莓派的指纹打卡器
大家可用于 课程设计 或 毕业设计
2 主要器件
树莓派一台指纹模块(AS608光学指纹识别模块)OLED液晶屏usb转TTL杜邦线3 实现效果
5 部分实现代码
树莓派驱动gpio接收指纹模块数据:
1 # -*-coding=utf8-*-2 3 import serial4 import serial.tools.list_ports5 6 import os, sys7 PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))8 sys.path.append(PATH)9 10 SureCore = {110x00: True, # 表示指令执行完毕或OK;120x01: 101, # 表示数据包接收错误;130x02: 102, # 表示传感器上没有手指;140x03: 103, # 表示录入指纹图像失败;150x06: 202, # 表示指纹图像太乱而生不成特征;160x07: 203, # 表示指纹图像正常,但特征点太少而生不成特征;170x15: 204, # 表示图像缓冲区内没有有效原始图而生不成图像;180x08: 302, # 表示指纹不匹配;190x09: 402, # 表示没搜索到;此时页码与得分为 0200x0a: 502, # 表示合并失败(两枚指纹不属于同一手指);210x0d: 802, # 表示指令执行失败;220x0f: 1002, # 表示不能发送后续数据包;23 }24 '''返回= 999 校验和错误'''25 26 27 class DealBuff:28"""切割收到的数据"""29HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]30 31def __init__(self, buff):32 self.buff = buff33 """处理读出的指纹数据用到"""34 self.tag = list() # 包标识35 self.data = list()36 self.check = list()37 pass38 39def read(self):40 buff = [x for x in bytes(self.buff)]41 check = self.slit(buff)42 return self.tag, self.data, check43 44def 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, buff52 pass53 54def slit(self, buff):55 """"选择数据"""56 # 初始化中间变量57 popList = list()58 check_Num = 059 check = list()60 head = list()61 62 if len(buff) < 6: # 判断是否有效数据63 return True64 65 head, buff = self.listCut(buff, 6) # 选择出头及判断66 for i in range(6):67 if head[i] != self.HEAD[i]:68 return False69 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 += i82 83 self.data.extend(popList) # 导入有用数据84 if check_Num % 65535 != check[0] + check[1]*256: # 检验校验和85 return False86 87 rec = self.slit(buff) # 得到是否正确分析完数据88 return rec89 pass90 91def write(self):92 """要写的数据打包"""93 pack = self.dataSeparate(self.buff, 128) # 将数据分成每组128个元素94 return pack95 pass96 97def 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 packData111 pass112 113def packData(self, buff, flage):114 num = len(buff) + 2115 senddata = [flage, int(num / 256), int(num % 256)] + buff116 sum = 0117 for i in senddata:118 sum += i119 senddata = self.HEAD + senddata120 senddata.append(int(sum / 256))121 senddata.append(int(sum % 256))122 return senddata123 pass124 125pass126 127 128 class DealFingeer:129"""和指纹模块交互"""130HEAD = [0xEF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF]131tag = list() # 包标识132cmd = list() #133data = list()134ser = serial.Serial()135def __init__(self, cmd, data=None, server=None):136 """初始化函数"""137 self.cmd = cmd138 self.data = data139 self.server = server140 pass141 142def run(self):143 if hasattr(self, self.cmd):144 func = getattr(self, self.cmd)145 return func(self.data)146 pass147 148def link(self):149 """连接串口"""150 self.ser.port = "COM5"151 self.ser.baudrate = 57600152 self.ser.bytesize = 8153 self.ser.parity = 'N'154 self.ser.xonxoff = 0155 self.ser.rtscts = 0156 self.ser.close()157 self.ser.open()158 pass159 160def 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 189def 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 pass205 206def 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, score219 pass220 221def 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, score237 pass238 239def getImage(self, data=None):240 """获取图像"""241 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x01, 0x00, 0x05] # 发送命令获取内容242 return self.isOk(cmd, 12)243 pass244 245def 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 pass254 255def match(self, data=None):256 """比较指纹特征"""257 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x03, 0x00, 0x07] # 发送命令获取内容258 return self.isOk(cmd, 14)259 pass260 261def regModel(self, data=None):262 """合成指纹特征值"""263 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x05, 0x00, 0x09] # 发送命令获取内容264 return self.isOk(cmd, 12)265 pass266 267def 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 pass277 278def 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 999286 return self.tag, self.data287 288def 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 pass298 299def downCharData(self, data):300 """下载特征值的数据"""301 self.writeRead(data, 0) # 发送数据 接收为0302 pass303 304 305def upImage(self, data=None):306 """上传图像检测"""307 cmd = self.HEAD + [0x01, 0x00, 0x03, 0x0a, 0x00, 0x0e] # 发送命令308 return self.isOk(cmd, 12, False)309 pass310 311def 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.data320 321def 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() # 接受完数据断开com328 return buff329 pass330 331def 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 999339 return self.check_code(self.data)340 pass341 342def check_code(self, data):343 """检验指令码"""344 return SureCore[data[0]]345 pass346 347pass348 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]