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文档形式的公文及合同的情况,并且需要上级对下级的公文进行批注等操作,或者不同部门的人需要签字审核,这就需要用到文档流转功能,如何用猿大师办公助手实现…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
