【雕爷学编程】Arduino动手做(141)---AS608光学指纹识别模块

发布时间 2023-06-30 12:06:38作者: 行者花雕

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

实验一百四十一:AS608光学指纹识别模块 智能锁/考勤门禁开发/指纹采集模块

 

 

知识点:指纹 (fingerprint)

也叫手印,即是表皮上突起的纹线。由于人的指纹是遗传与环境共同作用产生的,因而指纹人人皆有,却各不相同。由于指纹重复率极小,大约150亿分之一,故其称为“人体身份证”。指纹是人类手指末端指腹上由凹凸的皮肤所形成的纹路,指纹能使手在接触物件时增加摩擦力,从而更容易发力及抓紧物件,它是人类进化过程中自然形成的。伸出手,仔细观察,可以发现小小的指纹也分三种类型:有同心圆或螺旋纹线,看上去像水中漩涡的,叫斗形纹(whorl);有的纹线是一边开口的,即像簸箕似的,叫箕形纹(loop);有的纹形像弓一样,叫弓形纹(arch)。除总体形状不同之外,各人指纹纹形的多少、长短也不同。指纹在胎儿第三四个月便开始产生,到六个月左右就形成了。当婴儿长大成人,指纹也只不过放大增粗,纹样终生不会发生改变。

 

指纹形成基础

人的皮肤由表皮、真皮和皮下组织三部分组成。指纹就是表皮上突起的纹线。由于人的遗传特性。虽然指纹人人皆有,但各不相同。在皮肤发育过程中,虽然表皮、真皮以及基质层都在共同成长,柔软的皮下组织长得相对比坚硬的表皮快,因此会对表皮产生源源不断的上顶压力,迫使长得较慢的表皮向内层组织收缩塌陷,逐渐变弯打皱,以减轻皮下组织施加给它的压力。如此一来,一方面使劲向上攻,一方面被迫往下撤,导致表皮长得曲曲弯弯,坑洼不平,形成纹路。这种变弯打皱的过程随着内层组织产生的上层压力的变化而波动起伏,形成凹凸不平的脊纹或皱褶,直到发育过程中止,最终定型为至死不变的指纹。

 

各人的指纹除形状不同之外,纹形的多少、长短也不同。据说,全世界的五十多亿人中,还没有发现两个指纹完全相同的人呢。 目前尚无系统的指纹研究资料,中医的望诊,西医的皮纹学,涉及到掌纹的论述也只是只言片语。但是,生命科学的飞速发展,却为今天重新研究掌纹同生命体的有机联系提供了更广阔的视野。 目前发现,掌纹只在胎生的灵长类动物和人类中存在。而人类的手纹较灵长类动物更为丰富和多变,这至少预示着只从外界环境作用不能解释这种现象,而需从掌纹的形成同生命体的内在的关联性作进一步研究。

 

指纹学(dactylography)

运用皮肤学、生物化学、有机化学、高等数学、电子计算机等学科的知识和方法,研究掌面肤纹生理特征、纹理结构及其收集、显现、储存、分类与识别的原理和方法的科学。自17世纪开始,西方一些医生和人类学者就对指纹进行了长期的潜心探索。19世纪20年代,普鲁士布雷斯劳大学教授普金耶首先从解剖学的角度将指纹作了较为复杂的分类。1879年,苏格兰医生福尔茨利用自己研究的指纹术首次帮助日本各方查获了盗窃犯。1880年,福尔茨第一次提出了指纹“人各不同、终生不变”的特性。 1892 年,英国学者高尔顿的《指纹学》(1892),提出了三个影响重大的科学论点:1.指纹终生不变;2.指纹可识别;3.指纹可分类。1896年,亨利又进一步研究出一套指纹分析法,世人称为“高尔顿—亨利指纹分类系统”。该系统将指纹分为乎拱型、凸拱型、挠骨环状型、尸骨环状型、螺纹型五种类型。20世纪初,这种指纹分析方法相继为世界各国所采纳,并在此基础上,使指纹学逐渐形成一门独立的学科。

 

指纹结构
指纹,也称为手印,有广义狭义之分:狭义的指纹是指人的手指第一节手掌面皮肤上的乳突线花纹;广义的指纹则包括指头纹、指节纹和掌纹。指纹与指印在字面上有区别,即指纹是指手指第一节手掌面皮肤上的乳突线花纹,指印则是这个乳突线花纹留下的印痕,但是在司法实践中,约定俗成,指纹与指印的概念是通用的。留下印痕主要是由于在人的手指、手掌面的皮肤上,存在有大量的汗腺和皮脂腺(想想您紧张或激动时手心里的汗),只要生命活动存在,就不断地有汗液、皮脂液排出,有点像原子印章不断有油墨渗到印文表面,因此,只要手指、手掌接触到物体表面,就会象原子印章一样自动留下印痕。当然,这主要是说手指、手掌本身能留下指纹的原因。如果手指、手掌粘上其它液体样物质,如头面部的油脂(这是您最常要用的"印泥盒")、血液和按捺指纹的油墨等时,留下指纹的原理就更象盖普通印章。指纹的取证,包括指纹的搜寻和发现。指纹的搜寻范围:(1)犯罪活动中心;(2)现场的进出口及其周围;(3)犯罪分子可能接触过的物品;(4)犯罪分子遗留在现场上的各种凶器和物品。并且它们的复杂度足以提供用于鉴别的足够特征。指纹除了具有唯一性外,还具有遗传性和不变性。尚未发现有不同的人拥有相同的指纹,所以每个人的指纹也是不一样的。由于指纹是每个人独有的标记,近几百年来,罪犯在犯案现场留下的指纹,均成为警方追捕疑犯的重要线索。现今鉴别指纹方法已经电脑化,使鉴别程序更快更准。由于每个人的遗传基因均不同,故指纹也不同。然而,指纹的形成虽然主要受到遗传影响,但是也有环境因素(5%),当胎儿在母体内发育三至四个月时,指纹就已经形成,儿童在成长期间指纹会略有改变,直到青春期14岁左右时才会定型。在皮肤发育过程中,虽表皮、真皮,以及基质层都在共同成长,但柔软的皮下组织长得比相对坚硬的表皮快。 有人说骨髓移植后指纹会改变,那是不对的。除非是植皮或者深达基底层的损伤,否则指纹是不会变的。

 

指纹特征(Fingerprint characteristics)
在人的指纹中包含大量的信息,这些信息称为指纹特征。包括有许多特征点,特征点提供了指纹唯一性的确认信息,这是进行指纹识别的基础。分为总体特征和局部特征,总体特征又包括了核心点(位于指纹纹路的渐进中心)、 三角点(位于从核心点开始的第一个分叉点或者断点,或者两条纹路会聚处、孤立点、折转处,或者指向这些奇异点)、纹数(指纹纹路的数量);局部特征是指纹的细节特征,在特征点处的方向、曲率、 节点的位置,这都是区分不同指纹的重要指标。

 

总体特征是指那些用人眼直接就可以观察到的特征。包括纹形、模式区、核心点、三角点和纹数等。
1、纹形,指纹专家在长期实践的基础上,根据脊线的走向与分布情况一般将指纹分为三大类——环型(loop,又称斗形)、弓形(arch)、螺旋形(whorl)。
2、模式区即指纹上包括了总体特征的区域,从此区域就能够分辨出指纹是属于哪一种类型的。有的指纹识别算法只使用模式区的数据,有的则使用所取得的完整指纹。
3、核心点位于指纹纹路的渐进中心,它在读取指纹和比对指纹时作为参考点。许多算法是基于核心点的,即只能处理和识别具有核心点的指纹。
4、三角点位于从核心点开始的第一个分叉点或者断点,或者两条纹路会聚处、孤立点、折转处,或者指向这些奇异点。三角点提供了指纹纹路的计数跟踪的开始之处。
5、纹数,即模式区内指纹纹路的数量。在计算指纹的纹路时,一般先连接核心点和三角点,这条连线与指纹纹路相交的数量即可认为是指纹的纹数。

局部特征指纹节点的特征。指纹的纹路并不是连续、平滑笔直的,经常会出现分叉、折转或中断。这些交叉点、折转点或断点称为"特征点",它们提供了指纹唯一性的确认信息。
1、方向:相对于核心点,特征点所处的方向。
2、曲率:纹路方向改变的速度。
3、位置:节点的位置坐标,通过x/y坐标来描述。它可以是绝对坐标,也可以是与三角点(或特征点)的相对坐标。

指纹识别(fingerprint identification)
读取指纹图象、提取特征、保存数据和比对。在一开始,通过指纹读取设备读取到人体指纹的图象,取到指纹图象之后,要对原始图象进行初步的处理,使之更清晰。接下来,指纹辨识软件建立指纹的数字表示——特征数据,一种单方向的转换,可以从指纹转换成特征数据但不能从特征数据转换成为指纹,而两枚不同的指纹不会产生相同的特征数据。指纹识别技术作为生物体特征识别技术之一在新世纪逐渐成熟,进入了人类的生产生活领域。

指纹识别技术是众多生物特征识别技术中的一种,所谓生物特征识别技术(biometrics ),系指利用人体所固有的 生理特征或行为特征来进行个人身份鉴定,由于生物识别所具有的便捷与安全等优点使得生物识别技术在身份认证识别和网络安全领域拥有广阔的应用前景,可用的生物特征识别技术有指纹、人脸、声纹、虹膜等,指纹是其中应用最为广泛的一种。从20世纪60年代起新型的电子计算机技术进人指纹鉴定领域,为指纹鉴定自动化开辟了新的途径。近几年, 指纹识别技术应用到智能手机上,成为支持手机解锁、在线支付的重要基础技术。在未来,基于FIDO等协议,指纹识别等生物特征识别技术将全面取代现有的密码体系。在指纹识别算法上,最初是对指纹分类技术的研究,以提高指纹档案检索的效率。目前主流的指纹识别算法则基于指纹纹线的端点、分叉点等细节特征。随着指纹识别技术在移动设备的应用,指纹采集芯片的尺寸日益小型化,基于汗孔、纹线形状等3级特征的识别算法受到日益重视。在指纹采集技术上, 首先出现的是油墨捺印方法。油墨捺印的指纹卡片通过扫描方式数字化后进行存储和后续处理。20世纪70年代以后,光学式指纹采集技术的出现和普及促进了指纹的现场快速采集和验证。移动设备上的应用则促进了小尺寸超薄指纹采集技术的快速发展。

 

指纹识别采集技术
1、光学识别技术
属于第一代指纹识别技术,借助光学技术采集指纹是历史最久远、使用最广泛的技术。将手指放在光学镜片上,手指在内置光源照射下,用棱镜将其投射在电荷耦合器件(CCD) 上,进而形成脊线(指纹图像中具有一定宽度和走向的纹线)呈黑色、谷线(纹线之间的凹陷部分)呈白色的数字化的、可被指纹设备算法处理的多灰度指纹图像。
2、温差感应式识别技术
它的优点是可在0.1s内获取指纹图像,而且传感器体积和面积最小,即通常所说的滑动式指纹识别仪就是采用该技术。缺点是:受制于温度局限,时间一长,手指和芯片就处于相同的温度了。
3、半导体硅感技术(电容式技术)
第二代电容式传感器,根据指纹的嵴和峪与半导体电容感应颗粒形成的电容值大小不同,来判断什么位置是嵴什么位置是峪。其工作过程是通过对每个像素点上的电容感应颗粒预先充电到某一参考电压。当手指接触到半导体电容指纹表现上时,因为嵴是凸起、峪是凹下,根据电容值与距离的关系,会在嵴和峪的地方形成不同的电容值。然后利用放电电流进行放电。因为嵴和峪对应的电容值不同,所以其放电的速度也不同。嵴下的像素(电容量高)放电较慢,而处于峪下的像素(电容量低)放电较快。根据放电率的不同,可以探测到嵴和峪的位置,从而形成指纹图像数据。
4、生物射频指纹识别技术
发展到今天,出现第三代生物射频指纹识别技术(射频原理真皮指纹核心技术(线型采集器)),射频传感器技术是通过传感器本身发射出微量射频信号,穿透手指的表皮层去控测里层的纹路,来获得最佳的指纹图像。因此对汗手指,干手指等困难手指通过可高达99%,防伪指纹能力强,指纹敏感器的识别原理只对人的真皮皮肤有反应,从根本上杜绝了人造指纹的问题,宽温区:适合特别寒冷或特别酷热的地区。因为射频传感器产生高质量的图像,因此射频技术是最可靠,最有力的解决方案。除此之外,高质量图像还允许减小传感器,无需牺牲认证的可靠性,从而降低成本并使得射频传感器思想的应用到可移动和大小不受拘束的任何领域中。

 

技术特点
指纹识别技术的主要优点为:
1、指纹是人体独一无二的特征,并且它们的复杂度足以提供用于鉴别的足够特征;
2、如果要增加可靠性,只需登记更多的指纹、鉴别更多的手指,最多可以多达十个,而每一个指纹都是独一无二的;
3、扫描指纹的速度很快,使用非常方便;
4、读取指纹时,用户必需将手指与指纹采集头相互接触,与指纹采集头直接;
5、接触是读取人体生物特征最可靠的方法;
6、指纹采集头可以更加小型化,并且价格会更加的低廉;
指纹识别技术的主要缺点为:
1、某些人或某些群体的指纹指纹特征少,难成像;
2、过去因为在犯罪记录中使用指纹,使得某些人害怕“将指纹记录在案”。
3、实际上指纹鉴别技术可以不存储任何含有指纹图像的数据,而只是存储从指纹中得到的加密的指纹特征数据;
4、每一次使用指纹时都会在指纹采集头上留下用户的指纹印痕,而这些指纹痕迹存在被用来复制指纹的可能性。
5、指纹是用户的重要个人信息,某些应用场合用户担心信息泄漏。

 

 

AS608 系列芯片
芯片内置 DSP 运算单元,集成了指纹识别算法,能高效快速采集图像并识别指纹特征。AS608基于 ARM Cortex-M 系列内核开发的高性能 32 位微控制器,集成4K 字节指令 Cache,工作频率可达 144MHz,内嵌 Flash 容量可达 512K 字节,SRAM 容量可达 128K 字节,最大可扩展 16M 字节外部 SQI Flash。内嵌 Flash 具有 MPU 保护,能够有效保护用户代码的安全。

AS608 系列芯片具有丰富的片上外设,1 个 USB2.0 全速设备接口、2 个 SPI 主接口、1 个 SPI 从接口、2 个 UART 接口、1 个 I2C 接口、1 个光学 CMOS 传感器接口(LOCSC)、1 个智能卡主接口(SCI)、1 个语音 PWM 输出接口(VPWM)、1 个 ISO7816 收发控制器(ISO7816)、1 个 SWPS 接口,具有多达 48 个 GPIO,并且每个 GPIO 都具有中断功能。

AS608 系列芯片内嵌了多种加解密算法,支持 DES、AES、RSA、ECC 以及多种 HASH 算法。AS608 系列芯片采用模数混合技术设计,内部集成多种功能的模拟模块,减少外围电路设计,有效降低板级系统的成本。内部集成了 3 个用于电源转换的 LDO:1 个用于 5V 转 3.3V 的 LDO5033、1 个用于 3.3V 转 1.8V 的LDO3318、1 个用于 1.8V 转 1.2V 的 LDO1812,这些 LDO 为芯片内部各功能模块提供相应工作电源的同时,也可为其外围电路提供适当的电流。内部还集成了 2 个环振:1 个可输出高达 144MHz 的高频环振 HFROSC,经过出厂校准后,精度可达±1.5%;1 个输出频率约为 32KHz 的低频环振 LFROSC,可用于提供休眠模式时钟。

 

AS608指纹模块
集成了光路和指纹处理部分的一体化指纹处理模块,具有体积小、功耗低、接口简单的特点,可靠性高、识别速度快、干湿手指适应性好,指纹搜索速度快。模块配备了串口、USB 通讯接口,用户无需研究复杂的图像处理及指纹识别算法,只需通过简单的串口、USB 按照通讯协议便可控制模块。模块可应用于各种考勤机、保险箱柜、指纹门禁系统、指纹锁等场合。

 

模块参考电原理图

光学指纹模块工作原理
是指利用光的折摄和反射原理,将手指放在光学镜片上,手指在内置光源照射下,光从底部射向三棱镜,并经棱镜射出,射出的光线在手指表面指纹凹凸不平的线纹上折射的角度及反射回去的光线明暗就会不一样。用棱镜将其投射在电荷耦合器件上CMOS或者CCD上,进而形成脊线(指纹图像中具有一定宽度和走向的纹线)呈黑色、谷线(纹线之间的凹陷部分)呈白色的数字化的、可被指纹设备算法处理的多灰度指纹图像。其优点主要表现为经历长期实用检验、系统稳定性较好、成本亦较低、能提供分辨力为500 dpi( dot per inch)的图像。特别是能实现较大区域的指纹图像采集,有效克服大面积半导体指纹传感器价格昂贵缺点。该传感器局限性主要体现于潜在指印方面,不但会降低指纹图像的质量,严重时,还可能导致两个指印重叠,显然难以满足实际应用需要。此外,台板涂层及CCD阵列会随时间推移产生损耗,可能导致采集的指纹图像质量下降。随着光学技术发展,一些新颖的技术手段亦已应用于指纹图像的采集,这样能显着减小光学指纹传感器的体积。

指纹识别过程
分为两个次要过程,分为四个部分。两个次要的过程是指纹记录和交叉核对过程。指纹记录过程由四个部分组成:指纹采集、指纹预处理、指纹检查和指纹模板采集。指纹比对过程还包括四个部分:指纹采集、指纹预处理、指纹特征比对和匹配。在这两个过程中,指纹图像的前处理都存在,但指纹图像的取值和指纹 特征的值似乎有相同的名称,但它们的内在算法和性质是完全不同的。在引入指纹的过程中,更频繁地获得指纹图像,而单值提取部分的算法更多地关注一些特征值的辨析和获取过程。

指纹识别的第一步是指纹图像的获取,目前已经有多种指纹图像的获取方式,主要有光学指纹采集技术、电容式传感器指纹采集、温度传感指纹获取技术、超声波指纹采集技术、电磁波指纹采集技术,获得图像后进行预处理加工,要实现图像的灰度变换、分割、均衡化、增强、 细化等预处理步骤。首先要把指纹从整个图案上分割出来, 背景图和指纹分布图的灰度是不同的,这就确定了两者强度的区别, 利用梯度这个概念就能将指纹从背景图中很好的分离开;均衡化是预 处理中的重要一步,在提取时根据环境的不同得到的指纹图像不同区域的像素分布点是不同的,均衡化就是将不同区域分布的像素进行均值划分得到亮度分布均衡的图像;为了便于特征的提取,在几步加工后的图像还要智能化增强,Daugmann实现了利用Gabor小波逼近的方法使指纹图像的纹路线条更加清晰,即白的部分更白,黑的部分更黑,线条的边缘分布更加平滑。

对于处理好的指纹图像,指纹的纹路已经十分清晰,要进行指纹识别必须要进行特征提取,分离出那些具体的特征点来代替不同的纹路,首先提取指纹的特征端点和叉点,将端点叉点图像进行九宫格分割,利用指纹特征分布的灰度值是不同的这个特性,将指纹图像的端点和叉点分离出来,对于奇异点的提取利用Poincare公式,利用这个公式提取方向场周围剧烈变化的点,我们在计算机中使用不同的算法分别实现各个特征点的提取过程。

最后将识别的指纹分类操作,指纹的分类是用采集的指纹特征与数据库中保存的指纹特征相比较,判断是否属于同一指纹,首先根据指纹的纹形进行粗匹配,进而利用指纹形态和细节特征进行精确匹配给出相比较指纹的相似性程度。根据应用的不同,对指纹的相似性得分进行排序或给出是否为同一指纹的判决结果,指纹对比有两种方式: 一对一比对是根据用户从数据库中检索出待对比的用户指纹,再与新采集的指纹比对;一对多比对是新采集的指纹和数据库中的所有指纹逐一比对。

AS608光学指纹识别模块接口

采用 8 芯 1.25 mm 间距单排插座,模块内部内置了手指探测电路,用户可读取状态引脚TCH(WAK)判断有无手指按下。

引脚号  名称  类型      功能描述

1        Vi          In      模块电源正输入端+3.3V(请勿接3.3V以上电源,否则烧毁模块!)      

2        TX        Out      串行数据输出,接MCU或TTL串口的RX。

3        RX        In      串行数据输入,接MCU或TTL串口的TX。

4      GND        -      信号地。内部与电源地连接。

5      TCH      Out      感应信号输出,默认高电平有效

6      UA        In      触摸感应电源输入端,3.3v供电

7      D+        -      USB D+

8      D-        -        USB D-

(7脚,8脚为USB信号线,使用串口控制模块时可以悬空不用)

 

 

实验之一:Adafruit指纹传感器,更改密码示例
安装库:IDE—工具—管理库—搜索Adafruit-Fingerprint-Sensor-Library—安装
实验接线:
Vi      +3.3V(请勿接3.3V以上电源,否则烧毁模块!)         
TX      2     
RX      3
GND    GND

 

 

Arduino实验开源代码

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十一:AS608光学指纹识别模块 智能锁/考勤门禁开发/指纹采集模块

  实验之一:Adafruit指纹传感器,更改密码示例

  安装库:IDE—工具—管理库—搜索Adafruit-Fingerprint-Sensor-Library—安装

  实验接线:

  Vi    +3.3V(请勿接3.3V以上电源,否则烧毁模块!)

  TX    2

  RX    3

  GND  GND

*/



#include <Adafruit_Fingerprint.h>

// On Leonardo/Micro or others with hardware serial, use those! #0 is green wire, #1 is white

// uncomment this line:

// #define mySerial Serial1

// For UNO and others without hardware serial, we must use software serial...

// pin #2 is IN from sensor (GREEN wire)

// pin #3 is OUT from arduino  (WHITE wire)

// comment these two lines if using hardware serial

SoftwareSerial mySerial(2, 3);

// Using sensor without password

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

// Using sensor with password

//Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial, 1337);

void setup()

{

  while (!Serial);  // For Yun/Leo/Micro/Zero/...

  Serial.begin(9600);

  Serial.println("Adafruit fingerprint sensor, change password example");

  // set the data rate for the sensor serial port

  finger.begin(19200);

  if (finger.verifyPassword()) {

  Serial.println("Found fingerprint sensor!");

  } else {

  Serial.println("Did not find fingerprint sensor ");

  while (1);

  }

  Serial.print("Set password... ");

  uint8_t p = finger.setPassword(1337);

  if (p == FINGERPRINT_OK) {

  Serial.println("OK"); // Password is set

  } else {

  Serial.println("ERROR"); // Failed to set password

  }

}

void loop()

{

}

  

实验串口返回情况

找不到指纹传感器

 

Arduino实验开源代码之二

 

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十一:AS608光学指纹识别模块 智能锁/考勤门禁开发/指纹采集模块

  实验之二:输入序号,注册指纹示例

  安装库:IDE—工具—管理库—搜索Adafruit-Fingerprint-Sensor-Library—安装

  实验接线:

  Vi    +3.3V(请勿接3.3V以上电源,否则烧毁模块!)

  TX    2

  RX    3

  GND  GND

*/



#include <Adafruit_Fingerprint.h>

// On Leonardo/Micro or others with hardware serial, use those! #0 is green wire, #1 is white

// uncomment this line:

// #define mySerial Serial1

// For UNO and others without hardware serial, we must use software serial...

// pin #2 is IN from sensor (GREEN wire)

// pin #3 is OUT from arduino  (WHITE wire)

// comment these two lines if using hardware serial

SoftwareSerial mySerial(2, 3);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

uint8_t id;



void setup()  {

  Serial.begin(9600);

  while (!Serial);  // For Yun/Leo/Micro/Zero/...

  delay(100);

  Serial.println("\n\nAdafruit Fingerprint sensor enrollment");

  // 设置传感器串行端口的数据速率

  finger.begin(57600);

  if (finger.verifyPassword()) {

  Serial.println("Found fingerprint sensor!");

  } else {

  Serial.println("Did not find fingerprint sensor ");

  while (1) { delay(1); }

  }

}

uint8_t readnumber(void) {

  uint8_t num = 0;

  while (num == 0) {

  while (! Serial.available());

  num = Serial.parseInt();

  }

  return num;

}

void loop()              // 循环执行

{

  Serial.println("Ready to enroll a fingerprint!");

  Serial.println("lease type in the ID # (from 1 to 127) you want to save this finger as...");

  id = readnumber();

  if (id == 0) {// ID #0 not allowed, try again!

    return;

  }

  Serial.print("Enrolling ID #");

  Serial.println(id);

  while (!  getFingerprintEnroll() );

}

uint8_t getFingerprintEnroll() {

  int p = -1;

  Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);

  while (p != FINGERPRINT_OK) {

  p = finger.getImage();

  switch (p) {

  case FINGERPRINT_OK:

    Serial.println("Image taken");

    break;

  case FINGERPRINT_NOFINGER:

    Serial.println(".");

    break;

  case FINGERPRINT_PACKETRECIEVEERR:

    Serial.println("Communication error");

    break;

  case FINGERPRINT_IMAGEFAIL:

    Serial.println("Imaging error");

    break;

  default:

    Serial.println("Unknown error");

    break;

  }

  }

  // OK success!

  p = finger.image2Tz(1);

  switch (p) {

  case FINGERPRINT_OK:

    Serial.println("Image converted");

    break;

  case FINGERPRINT_IMAGEMESS:

    Serial.println("Image too messy");

    return p;

  case FINGERPRINT_PACKETRECIEVEERR:

    Serial.println("Communication error");

    return p;

  case FINGERPRINT_FEATUREFAIL:

    Serial.println("Could not find fingerprint features");

    return p;

  case FINGERPRINT_INVALIDIMAGE:

    Serial.println("Could not find fingerprint features");

    return p;

  default:

    Serial.println("Unknown error");

    return p;

  }

  

  Serial.println("Remove finger");

  delay(2000);

  p = 0;

  while (p != FINGERPRINT_NOFINGER) {

  p = finger.getImage();

  }

  Serial.print("ID "); Serial.println(id);

  p = -1;

  Serial.println("lace same finger again");

  while (p != FINGERPRINT_OK) {

  p = finger.getImage();

  switch (p) {

  case FINGERPRINT_OK:

    Serial.println("Image taken");

    break;

  case FINGERPRINT_NOFINGER:

    Serial.print(".");

    break;

  case FINGERPRINT_PACKETRECIEVEERR:

    Serial.println("Communication error");

    break;

  case FINGERPRINT_IMAGEFAIL:

    Serial.println("Imaging error");

    break;

  default:

    Serial.println("Unknown error");

    break;

  }

  }

  // OK success!

  p = finger.image2Tz(2);

  switch (p) {

  case FINGERPRINT_OK:

    Serial.println("Image converted");

    break;

  case FINGERPRINT_IMAGEMESS:

    Serial.println("Image too messy");

    return p;

  case FINGERPRINT_PACKETRECIEVEERR:

    Serial.println("Communication error");

    return p;

  case FINGERPRINT_FEATUREFAIL:

    Serial.println("Could not find fingerprint features");

    return p;

  case FINGERPRINT_INVALIDIMAGE:

    Serial.println("Could not find fingerprint features");

    return p;

  default:

    Serial.println("Unknown error");

    return p;

  }

  

  // OK converted!

  Serial.print("Creating model for #");  Serial.println(id);

  

  p = finger.createModel();

  if (p == FINGERPRINT_OK) {

  Serial.println("rints matched!");

  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {

  Serial.println("Communication error");

  return p;

  } else if (p == FINGERPRINT_ENROLLMISMATCH) {

  Serial.println("Fingerprints did not match");

  return p;

  } else {

  Serial.println("Unknown error");

  return p;

  }  

  

  Serial.print("ID "); Serial.println(id);

  p = finger.storeModel(id);

  if (p == FINGERPRINT_OK) {

  Serial.println("Stored!");

  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {

  Serial.println("Communication error");

  return p;

  } else if (p == FINGERPRINT_BADLOCATION) {

  Serial.println("Could not store in that location");

  return p;

  } else if (p == FINGERPRINT_FLASHERR) {

  Serial.println("Error writing to flash");

  return p;

  } else {

  Serial.println("Unknown error");

  return p;

  }  

}

  

Adafruit指纹传感器注册

找到指纹传感器!

准备注册指纹!

请键入要将此手指另存为……

 

 

注册ID#1
等待有效手指注册为1
.
.
.
……拍摄的图像
图像转换
取下手指
身份证1
再次放置同一个手指
……拍摄的图像
图像转换
为1创建模型
指纹匹配!
身份证1
存储!
等待有效手指注册为1

补充:安装Adafruit指纹传感器库
使用Arduino控制指纹传感器模块的最简单方法是使用该传感器的Adafruit库。按照下面的说明安装库:
传感器的Adafruit库下载地址(含eroll文件)
https://github.com/IT-XIAOXIAO/Adafrui
 
首先下载Adafruit指纹传感器库。下载完成后,您将得到一个.zip文件;
解压缩.zip文件,你会看到一个Adafruit-Fingerprint-Sensor-Library-master文件夹;
将Adafruit-Fingerprint-Sensor-Library-master文件夹重命名为Adafruit_Fingerprint_Sensor_Library文件夹;
将文件夹移动到您的Arduino IDE安装库文件夹;
最后,重新打开Arduino IDE。

Arduino实验开源代码之三

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十一:AS608光学指纹识别模块 智能锁/考勤门禁开发/指纹采集模块

  实验之三:查找一个匹配的指纹

  安装库:IDE—工具—管理库—搜索Adafruit-Fingerprint-Sensor-Library—安装

  实验接线:

  Vi    +3.3V(请勿接3.3V以上电源,否则烧毁模块!)

  TX    2

  RX    3

  GND  GND

*/



#include <Adafruit_Fingerprint.h>

// On Leonardo/Micro or others with hardware serial, use those! #0 is green wire, #1 is white

// uncomment this line:

// #define mySerial Serial1

// For UNO and others without hardware serial, we must use software serial...

// pin #2 is IN from sensor (GREEN wire)

// pin #3 is OUT from arduino  (WHITE wire)

// comment these two lines if using hardware serial

SoftwareSerial mySerial(2, 3);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

void setup()  

{

  Serial.begin(9600);

  while (!Serial);  // For Yun/Leo/Micro/Zero/...

  delay(100);

  Serial.println("\n\nAdafruit finger detect test");

  // set the data rate for the sensor serial port

  finger.begin(57600);

  delay(5);

  if (finger.verifyPassword()) {

  Serial.println("Found fingerprint sensor!");

  } else {

  Serial.println("Did not find fingerprint sensor ");

  while (1) { delay(1); }

  }

  finger.getTemplateCount();

  Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");

  Serial.println("Waiting for valid finger...");

}

void loop()              // run over and over again

{

  getFingerprintIDez();

  delay(50);        //don't ned to run this at full speed.

}

uint8_t getFingerprintID() {

  uint8_t p = finger.getImage();

  switch (p) {

  case FINGERPRINT_OK:

    Serial.println("Image taken");

    break;

  case FINGERPRINT_NOFINGER:

    Serial.println("No finger detected");

    return p;

  case FINGERPRINT_PACKETRECIEVEERR:

    Serial.println("Communication error");

    return p;

  case FINGERPRINT_IMAGEFAIL:

    Serial.println("Imaging error");

    return p;

  default:

    Serial.println("Unknown error");

    return p;

  }

  // OK success!

  p = finger.image2Tz();

  switch (p) {

  case FINGERPRINT_OK:

    Serial.println("Image converted");

    break;

  case FINGERPRINT_IMAGEMESS:

    Serial.println("Image too messy");

    return p;

  case FINGERPRINT_PACKETRECIEVEERR:

    Serial.println("Communication error");

    return p;

  case FINGERPRINT_FEATUREFAIL:

    Serial.println("Could not find fingerprint features");

    return p;

  case FINGERPRINT_INVALIDIMAGE:

    Serial.println("Could not find fingerprint features");

    return p;

  default:

    Serial.println("Unknown error");

    return p;

  }

  // OK converted!

  p = finger.fingerFastSearch();

  if (p == FINGERPRINT_OK) {

  Serial.println("Found a print match!");

  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {

  Serial.println("Communication error");

  return p;

  } else if (p == FINGERPRINT_NOTFOUND) {

  Serial.println("Did not find a match");

  return p;

  } else {

  Serial.println("Unknown error");

  return p;

  }  

  // found a match!

  Serial.print("Found ID #"); Serial.print(finger.fingerID);

  Serial.print(" with confidence of "); Serial.println(finger.confidence);

  return finger.fingerID;

}

// returns -1 if failed, otherwise returns ID #

int getFingerprintIDez() {

  uint8_t p = finger.getImage();

  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();

  if (p != FINGERPRINT_OK)  return -1;

  p = finger.fingerFastSearch();

  if (p != FINGERPRINT_OK)  return -1;

  // found a match!

  Serial.print("Found ID #"); Serial.print(finger.fingerID);

  Serial.print(" with confidence of "); Serial.println(finger.confidence);

  return finger.fingerID;

}

已注册手指指纹检测试验
找到指纹传感器!
传感器包含2个模板
正在等待有效的手指……

找到ID#1,置信度为236
找到ID#1,置信度143
找到ID#1   置信度为151
找到ID#2,置信度为100
找到ID#2,置信度为95
找到ID#2,置信度为131
找到ID#1,置信度为69

 

Arduino实验开源代码

实验之四:读取指纹库并列表

 

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十一:AS608光学指纹识别模块 智能锁/考勤门禁开发/指纹采集模块

  实验之四:读取指纹库并列表

  安装库:IDE—工具—管理库—搜索Adafruit-Fingerprint-Sensor-Library—安装

  实验接线:

  Vi    +3.3V(请勿接3.3V以上电源,否则烧毁模块!)

  TX    2

  RX    3

  GND  GND

*/



#include <Adafruit_Fingerprint.h>

int getFingerprintIDez();

// pin #2 is IN from sensor (GREEN wire)

// pin #3 is OUT from arduino  (WHITE wire)

SoftwareSerial mySerial(2, 3);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

void setup()  {

  while(!Serial);

  Serial.begin(9600);

  Serial.println("Fingerprint template extractor");

  // set the data rate for the sensor serial port

  finger.begin(57600);

  if (finger.verifyPassword()) {

  Serial.println("Found fingerprint sensor!");

  } else {

  Serial.println("Did not find fingerprint sensor ");

  while (1);

  }

  // Try to get the templates for fingers 1 through 10

  for (int finger = 1; finger < 10; finger++) {

  downloadFingerprintTemplate(finger);

  }

}

uint8_t downloadFingerprintTemplate(uint16_t id)

{

  Serial.println("------------------------------------");

  Serial.print("Attempting to load #"); Serial.println(id);

  uint8_t p = finger.loadModel(id);

  switch (p) {

  case FINGERPRINT_OK:

    Serial.print("Template "); Serial.print(id); Serial.println(" loaded");

    break;

  case FINGERPRINT_PACKETRECIEVEERR:

    Serial.println("Communication error");

    return p;

  default:

    Serial.print("Unknown error "); Serial.println(p);

    return p;

  }

  // OK success!

  Serial.print("Attempting to get #"); Serial.println(id);

  p = finger.getModel();

  switch (p) {

  case FINGERPRINT_OK:

    Serial.print("Template "); Serial.print(id); Serial.println(" transferring:");

    break;

  default:

    Serial.print("Unknown error "); Serial.println(p);

    return p;

  }

  // one data packet is 267 bytes. in one data packet, 11 bytes are 'usesless'

  uint8_t bytesReceived[534]; // 2 data packets

  memset(bytesReceived, 0xff, 534);

  uint32_t starttime = millis();

  int i = 0;

  while (i < 534 && (millis() - starttime) < 20000) {

    if (mySerial.available()) {

      bytesReceived[i++] = mySerial.read();

    }

  }

  Serial.print(i); Serial.println(" bytes read.");

  Serial.println("Decoding packet...");

  uint8_t fingerTemplate[512]; // the real template

  memset(fingerTemplate, 0xff, 512);

  // filtering only the data packets

  int uindx = 9, index = 0;

  while (index < 534) {

    while (index < uindx) ++index;

    uindx += 256;

    while (index < uindx) {

      fingerTemplate[index++] = bytesReceived[index];

    }

    uindx += 2;

    while (index < uindx) ++index;

    uindx = index + 9;

  }

  for (int i = 0; i < 512; ++i) {

    //Serial.print("0x");

    printHex(fingerTemplate, 2);

    //Serial.print(", ");

  }

  Serial.println("\ndone.");

  /*

  uint8_t templateBuffer[256];

  memset(templateBuffer, 0xff, 256);  //zero out template buffer

  int index=0;

  uint32_t starttime = millis();

  while ((index < 256) && ((millis() - starttime) < 1000))

  {

  if (mySerial.available())

  {

    templateBuffer[index] = mySerial.read();

    index++;

  }

  }

  Serial.print(index); Serial.println(" bytes read");

  //dump entire templateBuffer.  This prints out 16 lines of 16 bytes

  for (int count= 0; count < 16; count++)

  {

  for (int i = 0; i < 16; i++)

  {

    Serial.print("0x");

    Serial.print(templateBuffer[count*16+i], HEX);

    Serial.print(", ");

  }

  Serial.println();

  }*/

}

void printHex(int num, int precision) {

  char tmp[16];

  char format[128];

  sprintf(format, "%%.%dX", precision);

  sprintf(tmp, format, num);

  Serial.print(tmp);

}

void loop()

{}

  

指纹模板提取器

找到指纹传感器!

------------------------------------

试图加载1

加载模板1

试图获取1

模板1传输:

读取534字节。

正在解码数据包……

 

试图加载3
未知错误12
------------------------------------
试图加载4
未知错误12
------------------------------------
试图加载#5
未知错误12
------------------------------------
试图加载#6
未知错误12
------------------------------------
试图加载7
未知错误12
------------------------------------
试图加载#8
未知错误12
------------------------------------
试图加载#9
未知错误12

Adafruit光学指纹传感器相关资料
https://learn.adafruit.com/adafr ... int-sensor/overview

我们喜欢这种特殊的传感器,因为它不仅易于使用,而且还配备了相当简单的Windows软件,使模块的测试变得简单-您甚至可以使用该软件进行注册,并在计算机屏幕上查看指纹的图像。但是,当然,我们不会给您数据表和“好运”!- 我们编写了完整的Arduino库,因此您可以在10分钟内开始运行。图书馆可以注册和搜索,因此非常适合任何项目。我们还编写了有关接线和使用的详细教程。这是迄今为止您可以获得的最好的指纹传感器。
电源电压: 3.6-6.0VDC
工作电流:最大120mA
峰值电流:最大150mA
指纹成像时间: <1.0秒
窗口面积: 14mm x 18mm
签名文件: 256字节
模板文件: 512字节
存储容量: 162个模板
安全等级(1-5从低到高安全)
错误接受率: <0.001%(安全级别3)
错误拒绝率: <1.0%(安全级别3)
接口: TTL串行
波特率: 9600、19200、28800、38400、57600(默认为57600)
工作温度等级: -20C至+ 50C
工作湿度: 40%-85%RH
完整尺寸: 56 x 20 x 21.5mm
暴露的尺寸(放在盒子中时):21mm x 21mm x 21mm三角形
重量: 20克

指纹模块Adafruit-Fingerprint-Sensor-Library库的示例列表

chanpassword 更改密码示例
enroll 注册一个新的指纹 示例
emptyDatabase 删除所有指纹模板
delete 输入序号,删除指定指纹模板
fingerprint 找到一个匹配的指纹(核对指纹)
show_fingerprint_templates读取指纹库并列表

 

Arduino实验开源代码

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十一:AS608光学指纹识别模块 智能锁/考勤门禁开发/指纹采集模块

  安装AS608库:IDE—工具—管理库—搜索Adafruit-Fingerprint-Sensor-Library—安装

  安装OLED库:IDE—工具—管理库—搜索Adafruit_SSD1306—安装

  安装OLED库:IDE—工具—管理库—搜索Adafruit_GFX—安装

  实验程序之十三:识别指纹ID,OLED显示识别人名

  AS608模块实验接线

  Vi    +3.3V(请勿接3.3V以上电源,否则烧毁模块!)

  TX    2

  RX    3

  GND  GND

  OLED 屏幕实验接线

  oled模块  Ardunio Uno

  GND---------GND接地线

  VCC---------5V 接电源

  SDA---------A4

  SCL ------- A5

*/



#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define OLED_RESET 4

Adafruit_SSD1306 display(OLED_RESET);

#include <Adafruit_Fingerprint.h>

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);

Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

int fingerprintID = 0;

String IDname;

void setup() {

  //Fingerprint sensor module setup

  Serial.begin(9600);

  // set the data rate for the sensor serial port

  finger.begin(57600);

  if (finger.verifyPassword()) {

  Serial.println("Found fingerprint sensor!");

  }

  else {

  Serial.println("Did not find fingerprint sensor ");



  while (1) {

    delay(1);

  }

  }

  //OLED display setup

  Wire.begin();

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  //displays main screen

  displayMainScreen();

}

void loop() {

  displayMainScreen();

  fingerprintID = getFingerprintIDez();

  delay(50);

  if (fingerprintID == 1 || fingerprintID == 3) {

  IDname = "huadiao";

  displayUserGreeting(IDname);

  }

  else if (fingerprintID == 2) {

  IDname = "zhanghaoze";

  displayUserGreeting(IDname);

  }

}

// returns -1 if failed, otherwise returns ID #

int getFingerprintIDez() {

  uint8_t p = finger.getImage();

  if (p != FINGERPRINT_OK)  return -1;

  p = finger.image2Tz();

  if (p != FINGERPRINT_OK)  return -1;

  p = finger.fingerFastSearch();

  if (p != FINGERPRINT_OK)  return -1;

  // found a match!

  Serial.print("Found ID #");

  Serial.print(finger.fingerID);

  Serial.print(" with confidence of ");

  Serial.println(finger.confidence);

  return finger.fingerID;

}

void displayMainScreen() {

  display.clearDisplay();

  display.setTextSize(1);

  display.setTextColor(WHITE);

  display.setCursor(7, 5);

  display.println("Waiting fingerprint");

  display.setTextSize(1);

  display.setTextColor(WHITE);

  display.setCursor(52, 20);

  display.println("...");

  display.display();

  delay(2000);

}

void displayUserGreeting(String Name) {

  display.clearDisplay();

  display.setTextColor(WHITE);

  display.setTextSize(2);

  display.setCursor(0, 0);

  display.print("Hello");

  display.setCursor(0, 15);

  display.print(Name);

  display.display();

  delay(5000);

  fingerprintID = 0;

}

 

本实验案例中,通过程序之二enroll,注册了“huadaio”的二个指纹1#和3号,注册了“zhanghaoze”一个指纹2#。识别指纹ID后,在串口显示匹配的信心值,在OLED屏显示匹配的招呼语。

Found fingerprint sensor!
找到指纹传感器!

OLED显示

Waiting fingerprint
等待指纹

 

串口显示识别的三个指纹ID

 

OLED屏显示识别1#指纹“huadaio”

 

 

OLED屏显示识别2#指纹“zhanghaoze”

 

手头还有二个不同型号的指纹模块,目前不敢动,相关资料太少了......