FPM383C指纹模块超详解 附驱动
0. 本人使用环境介绍
0.1 硬件环境
- ESP32-C3
- FPM383C指纹模块
- 一根破旧的usb数据线
0.2 软件环境
- Clion2024.2.2
- ESP-IDF5.3.1
- Clion插件ESP-IDF
1. 硬件接口说明
1.1 UART
-
UART 缺省波特率为 57.6Kbps,数据格式:8 位数据位,2 位停止位,无校验位;
-
UART 波特率可以通过指令进行设置,范围从 9600 至 115200;
-
如果主控是 MCU(3.3V),则直接与 UART_TD 和 UART_RD 连接;如果主控是 PC,则需要挂接RS232 电平转换设备。
1.2 USB
-
标准 USB 接口,内嵌 USB 通讯协议;
-
兼容 USB2.0,工作在 Full Speed;
-
默认 VID=0x2109;默认 PID=0x7638;
1.3 UART 与 USB 协同工作
-
主控即可通过 UART 或 USB 与指纹模组通讯;
-
两个接口只能单独工作,不支持同时工作;
-
两个接口执行相同的协议和命令;
-
两个接口共享同一个数据缓冲区;
2. 业务类指令集
2.1 通用指令集
2.1.1 验证用获取图像PS_GetImage
2.1.1 代码实现
/*** 从指纹传感器获取图像** 该函数通过UART向指纹传感器发送指令,请求获取当前图像,并接收传感器的响应* 根据响应中的状态码判断图像获取是否成功,以及图像质量是否符合要求** @return uint8_t 返回状态码:* - 0: 获取图像成功* - 1: 图像不清晰,请重新采集* - 2: 获取图像失败或其他错误*/uint8_t Finger_GetImage() {// 准备发送给指纹传感器的数据包uint8_t sent_data[13] = {0xEF, 0x01, // 包头0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址0x01, // 包标识0x00, 0x03, // 包长度0x01, // 指令码0x00, // 参数0x00, 0x5 // 校验和};// 通过UART发送数据包uart_write_bytes(UART_NUM_0, sent_data, 13);// 准备接收指纹传感器的响应数据uint8_t get_data[64];// 读取UART接收到的数据,等待最多100msint st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);// 检查读取状态if (st >= 0) {// 根据响应数据中的状态码判断图像获取结果if (get_data[6] == 0x07 && get_data[10] == 0x00) {printf("获取图像成功\r\n");return 0;} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {printf("图像不清晰,请重新采集\r\n");return 1;}}// 如果读取失败或响应数据不符合预期,则返回错误码return 2;
}
2.1.2 生成特征PS_GenChar
2.1.2 代码实现
/*** 生成指纹特征** 本函数通过UART向指纹模块发送指令,生成指纹特征** @param buffer 指纹数据缓冲区* @return uint8_t* - 0: 特征生成成功* - 1: 特征生成失败* - 2: UART读写错误*/
uint8_t Finger_GenChar(uint8_t buffer) {// 构造发送数据包uint8_t sent_data[13] = {0xEF, 0x01, // 包头0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址0x01, // 包标识0x00, 0x04, // 包长度0x02, // 指令码'\0', // 参数'\0', '\0' // 校验和};// 将缓冲区数据放入发送数据包中sent_data[10] = buffer;// 计算校验和uint16_t sum = sent_data[6] + sent_data[7] + sent_data[8] + sent_data[9] + sent_data[10];// 将校验和放入发送数据包中sent_data[11] = sum >> 8;sent_data[12] = sum;// 通过UART发送数据包uart_write_bytes(UART_NUM_0, sent_data, 13);// 接收指纹模块返回的数据uint8_t get_data[64];int st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);// 根据返回数据判断特征生成结果if (st >= 0) {if (get_data[6] == 0x07 && get_data[10] == 0x00) {printf("生成特征成功\r\n");return 0;} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {printf("生成特征失败\r\n");return 1;}}// 如果读写错误,返回2return 2;
}
2.1.3 搜索指纹PS_Search
2.1.3 代码实现
/*** 搜索指纹指令* * 本函数通过UART向指纹模块发送搜索指令,并接收搜索结果* 搜索指令是一个固定格式的字节序列,通过UART发送给指纹模块* 接收到的数据显示搜索结果,包括成功、收包错误或搜索失败* * @return uint8_t 返回0表示搜索成功,返回1表示搜索失败或通信错误*/
uint8_t FINGER_Search(void)
{// 搜索指纹的指令序列,包含必要的指令码和参数uint8_t command[17]={0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x04,0x01,0x00,0x00,0xFF,0xFF,0x02,0x0C};// 通过UART发送搜索指令uart_write_bytes(UART_NUM_1,command,17);// 接收指纹模块返回的数据uint8_t recv_data[64]={0};int len=uart_read_bytes(UART_NUM_1,recv_data,64,500/portTICK_PERIOD_MS);// 检查接收到的数据长度if(len>0){// 根据接收数据的内容判断搜索结果if(recv_data[6]==0x07 && recv_data[9]==0x00){printf("搜索成功\r\n");return 0;}else if(recv_data[6]==0x07 && recv_data[9]==0x01){printf("收包错误\r\n");}else if(recv_data[6]==0x07 && recv_data[9]==0x09){printf("搜索失败\r\n");}}// 如果没有接收到数据或接收到的数据不匹配任何条件,则返回1return 1;
}
2.1.4 合并特征 PS_RegModel
2.1.4 代码实现
/*** 注册指纹模型** 本函数通过串口发送指令以注册指纹模型,并根据返回结果判断注册是否成功** @return uint8_t 返回注册状态码:* 0 - 合并成功* 1 - 收包错误* 2 - 合并失败* 3 - 通信失败或其他错误*/
uint8_t Finger_RegModel() {// 准备发送的数据包,包含包头、设备地址、包标识、包长度、指令码、参数和校验和uint8_t sent_data[13] = {0xEF, 0x01, // 包头0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址0x01, // 包标识0x00, 0x03, // 包长度0x05, // 指令码0x00, // 参数0x00, 0x09 // 校验和};// 通过UART发送数据包uart_write_bytes(UART_NUM_0, sent_data, 13);// 准备接收数据缓冲区uint8_t get_data[64];// 通过UART读取返回数据,设置超时时间为100msint st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);// 检查读取状态if (st >= 0) {// 根据返回数据判断注册结果if (get_data[6] == 0x07 && get_data[10] == 0x00) {printf("合并成功\r\n");return 0;} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {printf("收包错误\r\n");return 1;} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {printf("合并失败\r\n");return 2;}}// 如果通信失败或其他错误,返回3return 3;
}
2.1.5 储存模板PS_StoreChar
2.1.5 代码实现
/*** 函数: Finger_StoreChar** 描述: 将一个字符的数据存储到指定的页面ID中。** 参数:* - buffer: 要存储的字符数据。* - pageID: 目标页面的ID。** 返回值:* - 0: 存储成功。* - 1: 收包错误。* - 2: 超出指纹库范围。* - 3: 通信失败或其他错误。*/
uint8_t Finger_StoreChar(uint8_t buffer, uint16_t pageID) {// 构造要发送的数据包uint8_t sent_data[15] = {0xEF, 0x01, // 包头0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址0x01, // 包标识0x00, 0x03, // 包长度0x06, // 指令码'\0', // 缓冲区'\0', '\0', //位置号'\0', '\0' // 校验和};// 将要存储的字符数据放入数据包中sent_data[10] = buffer;// 计算数据包的校验和uint16_t sum =sent_data[6] + sent_data[7] + sent_data[8] + sent_data[9] + sent_data[10] + sent_data[11] + sent_data[12];sent_data[11] = pageID >> 8;sent_data[12] = pageID;sent_data[13] = sum >> 8;sent_data[14] = sum;// 通过UART发送数据包uart_write_bytes(UART_NUM_0, sent_data, 15);// 接收响应数据uint8_t get_data[64];int st = uart_read_bytes(UART_NUM_0, get_data, 64, 100 / portTICK_PERIOD_MS);// 根据响应数据判断存储结果if (st >= 0) {if (get_data[6] == 0x07 && get_data[10] == 0x00) {printf("储存成功\r\n");return 0;} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {printf("收包错误\r\n");return 1;} else if (get_data[6] == 0x07 && get_data[10] == 0x01) {printf("超出指纹库范围\r\n");return 2;}}return 3;
}
2.1.6 搜索指纹PS_Search
2.1.6 代码实现
/*** 搜索指纹指令** 本函数通过UART向指纹模块发送搜索指令,并接收搜索结果* 搜索指令是一个固定格式的字节序列,通过UART发送给指纹模块* 接收到的数据显示搜索结果,包括成功、收包错误或搜索失败** @return uint8_t 返回0表示搜索成功,返回1表示搜索失败或通信错误*/
uint8_t FINGER_Search(void)
{// 搜索指纹的指令序列,包含必要的指令码和参数uint8_t command[17]={0xEF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x08,0x04,0x01,0x00,0x00,0xFF,0xFF,0x02,0x0C};// 通过UART发送搜索指令uart_write_bytes(UART_NUM_1,command,17);// 接收指纹模块返回的数据uint8_t recv_data[64]={0};int len=uart_read_bytes(UART_NUM_1,recv_data,64,500/portTICK_PERIOD_MS);// 检查接收到的数据长度if(len>0){// 根据接收数据的内容判断搜索结果if(recv_data[6]==0x07 && recv_data[9]==0x00){printf("搜索成功\r\n");return 0;}else if(recv_data[6]==0x07 && recv_data[9]==0x01){printf("收包错误\r\n");}else if(recv_data[6]==0x07 && recv_data[9]==0x09){printf("搜索失败\r\n");}}// 如果没有接收到数据或接收到的数据不匹配任何条件,则返回1return 1;
}
2.1.7 休眠指令PS_Sleep
2.1.7 代码实现
/*** @brief 控制指纹模块进入休眠模式* * 该函数通过UART向指纹模块发送休眠指令,使模块进入低功耗状态。* 主要包括以下几个步骤:* 1. 组装休眠指令的数据包。* 2. 通过UART发送指令包。* 3. 等待并接收指纹模块的响应。* 4. 解析响应,判断休眠指令是否执行成功。* * @return uint8_t * - 0: 指纹模块休眠成功* - 1: 指纹模块休眠失败*/
uint8_t Driver_Finger_Sleep()
{// 组装发送给指纹模块的休眠指令包uint8_t command[12] = {0xEF, 0x01, // 包头0xFF, 0xFF, 0xFF, 0xFF, // 默认设备地址0x01, // 包标识0x00, 0x03, // 包长度0x33, // 指令码0x00, 0x37 // 校验和};// 通过UART发送休眠指令包uart_write_bytes(UART_NUM_1, command, 12);// 初始化接收缓冲区uint8_t recv_data[64] = {0};// 等待并接收指纹模块的响应int len =uart_read_bytes(UART_NUM_1, recv_data, 64, 100 / portTICK_PERIOD_MS);// 判断接收到的响应长度是否大于0if (len > 0){// 检查响应中的特定字段,判断休眠指令是否执行成功if (recv_data[6] == 0x07 && recv_data[9] == 0x00){// 休眠成功printf("指纹模块休眠成功\r\n");return 0;}}// 休眠失败printf("指纹模块休眠失败\r\n");return 1;
}
通用指令更到这 待更新后续!!!
相关文章:

FPM383C指纹模块超详解 附驱动
0. 本人使用环境介绍 0.1 硬件环境 ESP32-C3FPM383C指纹模块一根破旧的usb数据线 0.2 软件环境 Clion2024.2.2ESP-IDF5.3.1Clion插件ESP-IDF 1. 硬件接口说明 1.1 UART UART 缺省波特率为 57.6Kbps,数据格式:8 位数据位,2 位停止位&am…...

若依框架篇-若依集成 X-File-Storage 框架(实现图片上传阿里云 OSS 服务器)、EasyExcel 框架(实现 Excel 数据批量导入功能)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 实现使用 Excel 文件批量导入 1.1 导入功能的前端具体实现 1.2 导入功能的后端具体实现 1.3 使用 EasyExcel 框架实现 Excel 读、写功能 1.4 将 Easy Excel 集成到…...

.rmallox勒索病毒肆虐:如何有效防范与应对
引言 在当今这个数字化时代,网络安全已成为一个不可忽视的重要议题。随着信息技术的飞速发展,网络空间的安全威胁也日益复杂多变。病毒、木马、勒索软件等恶意程序层出不穷,比如.rmallox勒索病毒。它们利用先进的技术手段,如代码…...
人工智能能否影响未来生活:一场深刻的社会与技术变革
随着人工智能技术的不断发展,我们已经目睹了它在各行各业掀起的巨大变革浪潮。从医疗行业的病例诊断、药物研发,到企业运营的数据分析、智能决策,再到日常生活中的智能语音助手、自动驾驶汽车、智能家居,人工智能正以前所未有的速…...

cmu 15-445学习笔记-3 存储引擎
03 Database Storage-Part Ⅰ 数据库存储上半部分 数据库分层划分结构图: Disk Manager:存储引擎,管理磁盘上的文件Bufferpool Manager:管理内存的缓存池Access Methods:访问方法Operator Execution:执行…...

[linux]和windows间传输命令scp 执行WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!错误解决
[linux]和windows间传输命令scp 执行WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!错误解决. 现象: 原因: 接收方服务器系统做了某些更改,导致登录时会报错。主要因为接收方服务器对登录过它的主机都会把该主机登录标识证书记录下来&a…...

C++ | Leetcode C++题解之第518题零钱兑换II
题目: 题解: class Solution { public:int change(int amount, vector<int>& coins) {vector<int> dp(amount 1), valid(amount 1);dp[0] 1;valid[0] 1;for (int& coin : coins) {for (int i coin; i < amount; i) {valid[…...
高并发-负载均衡
负载均衡在微服务架构中是一个重要的组成部分,旨在优化资源利用、提高服务可用性和确保系统的高可扩展性。以下是对微服务中的负载均衡的详细介绍,包括其原理、类型、实现方式以及相关的技术。 一、负载均衡的原理 负载均衡的基本原理是将进入系统的请…...

Docker 常用命令全解析:提升对雷池社区版的使用经验
Docker 常用命令解析 Docker 是一个开源的容器化平台,允许开发者将应用及其依赖打包到一个可移植的容器中。以下是一些常用的 Docker 命令及其解析,帮助您更好地使用 Docker。 1. Docker 基础命令 查看 Docker 版本 docker --version查看 Docker 运行…...

基于 Postman 和 Elasticsearch 测试乐观锁的操作流程
鱼说,你看不到我眼中的泪,因为我在水中。水说,我能感觉到你的泪,因为你在我心中。 -村上春树 在分布式系统中,多个并发操作对同一资源的修改可能导致数据不一致。为了解决这种问题,Elasticsearch 提供了乐观…...

如何从PPT中导出600dpi的高清图
Step1. 修改PPT注册表 具体过程,参见如下链接:修改ppt注册表,导出高分辨率图片 Step2. 打开PPT,找到自己想要保存的图,选中图像,查看图像尺寸并记录 Step3. 重新新建一个PPT,并根据记录的图片…...

day01-ElasticStack+Kibana
ElasticStack-数据库 #官网https://www.elastic.co/cn/ #下载7.17版环境准备 主机名IP系统版本VMware版本elk110.0.0.91Ubuntu 22.04.417.5.1elk210.0.0.92Ubuntu 22.04.417.5.1elk310.0.0.93Ubuntu 22.04.417.5.1 单机部署ES 1.下载ES软件包,放到/usr/local下 […...
HTML 约束验证
HTML5引入了表单相关的一些新机制:它为<input>元素和约束验证增加了一些新的语义类型,使得客户端检查表单内容变得容易。基本上,通过设置一些新的属性,常用的约束条件可以无需 JavaScript 代码而检测到;对于更复…...

vue3项目开发一些必备的内容,该安装安装,该创建创建
重新整理了一下项目开发必备的一些操作,以后直接复制黏贴运行,随着项目开发,后期会陆续补充常用插件或组件等 如果你是还没有安装过的新人,建议从《通过安装Element UI/Plus来学习vue之如何创建项目、搭建vue脚手架、npm下载、封装…...
2D拓扑图
2D拓扑图主要指的是在二维平面上表示物体形状和关系的一种图形表示方法。 一、基本概念 2D网格拓扑结构:在二维平面上,由一系列的节点(node)和边(edge)组成。每个节点代表一个具体的位置或坐标点…...
大数据面试题整理——Hive
系列文章目录 大数据面试题专栏点击进入 文章目录 系列文章目录Hive 面试知识点全面解析一、函数相关(一)函数分类与特点(二)concat和concat_ws的区别 二、SQL 的书写和执行顺序(一)书写顺序(二…...
Python实现图像(边缘)锐化:梯度锐化、Roberts 算子、Laplace算子、Sobel算子的详细方法
目录 Python实现图像(边缘)锐化:梯度锐化、Roberts算子、Laplace算子、Sobel算子的详细方法引言一、图像锐化的基本原理1.1 什么是图像锐化?1.2 边缘检测的基本概念 二、常用的图像锐化算法2.1 梯度锐化2.1.1 实现步骤 2.2 Robert…...

【电机控制】相电流重构——单电阻采样方案
【电机控制】相电流重构——单电阻采样方案 文章目录 [TOC](文章目录) 前言一、基于单电阻采样电流重构技术原理分析1.1 单电阻采样原理图1.2 基本电压矢量与电流采样关系 二、非观测区2.1 扇区过渡区2.2 低压调制区 三、非观测区补偿——移相法四、参考文献总结 前言 使用工具…...

#基础算法
1 差分练习 1 模板题 代码实现: import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();int m sc.nextInt();int num sc.nextInt();long[][] arr new long[n 2][m …...

如何用猿大师办公助手实现OA系统中Word公文/合同在线编辑及流转?
在OA系统或者合同管理系统中,我们会经常遇到网页在线编辑Word文档形式的公文及合同的情况,并且需要上级对下级的公文进行批注等操作,或者不同部门的人需要签字审核,这就需要用到文档流转功能,如何用猿大师办公助手实现…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...

在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...