一.概要

BE5100模块应用广泛,只要涉及到授权、管理、开关等方面的功能,均可用 BE5100模块的人脸识别功能来代替 IC 卡、密码、硬件开关等,适合从低端到高端的所有系统,比如:
门锁、保险柜、金融等安全领域。
门禁系统、工控机、 驾培、考勤等身份领域;
私人会所、管理软件、授权许可等管理领域;
医保领取、养老领取、人脸支付等金融领域。
在这里插入图片描述

二.BE5100模块主要技术指标

在这里插入图片描述

三.BE5100模块接线说明

在这里插入图片描述

在这里插入图片描述

BE5100模块与单片机只要4根线就能连接

单片机开发板 人脸识别模块
3.3V-----------------------VDD
GND----------------------GND
PA9------------------------RX
PA10----------------------TX

四.BE5100模块通讯协议介绍

串口通讯参数:
在这里插入图片描述
指令格式:
在这里插入图片描述

以下对指令包中各域进行说明。
1:同步域(SyncWord):作为指令包开头的字节,固定为 EF AA。
2:消息类别(MsgID):消息类别主要分成 3 类,命令消息(Command)、应答消息(Reply)和通知消息(Note)。
3:数据域字节数(Size):数据域包含的字节数。
4:数据域(Data):需要传输的具体数据,如确认码、参数等。若无数据传输,数据域可为空。
5: 校验域(Check):对 MsgID、Size、Data 这三个区域所有字节按位进行异或运算(XOR)。

消息类别MsgID主要定义如下:
在这里插入图片描述

单片机发给模块命令帧格式如下:
在这里插入图片描述

模块返回给单片机命令帧如下:
在这里插入图片描述

例如人脸识别模块的复位命令消息:

单片机发送的数据帧格式:
在这里插入图片描述
模块返回的数据帧格式:
在这里插入图片描述
串口通讯示例:
单片机Send:EF AA 10 00 00 10
单片机Recv:EF AA 00 00 02 10 00 12

五.人脸识别模块录入与识别流程

人脸录入操作流程:
在这里插入图片描述
在录入过程中,人脸锁算法模组不限制录入方向的顺序,用户可以任意组合录入方向的顺序,上图是以其中一种顺序为例进行说明。
当主控下达录入某个方向的人脸的指令后,模组开始工作,并实时地返回人脸的状态、位置、姿态等信息(以NOTE 消息的形式返回),用户可根据该信息提醒录入人进行姿态位置的调整,当录入成功后,模组将以 REPLY 消息的形式返回录入结果,如果录入不成功,模组也会相应地返回失败的原因。值得注意的是,当模组采集到的第一帧图像就录入成功时,将直接以 REPLY 消息的形式返回结果。录入过程中可通过 FACE RESET 指令终止录入,先前的录入状态也会清零。如果在录入过程中突然断电,之前录入的人脸也不会保存。

人脸验证操作流程:
在这里插入图片描述

六.STM32单片机与人脸识别模块录入与识别实验

1.硬件准备

STLINK接STM32F103C8T6开发板,STLINK接电脑USB口,5V USB线接板子的USB口。

指纹模块与单片机开发板接线:
103C8T6 开发板
5V --------------------------------------模块 V
PA10-----------------------------------模块 T
PA9 ------------------------------------模块 R
GND------------------------------------模块 G

在这里插入图片描述

2.软件工程

采用STM32F103C8T6标准库软件工程方式。
在这里插入图片描述

3.软件主要代码

串口数据接收相关代码

//接收标志函数,返回0说明没收据接收,返回1说明有数据收到
uint8_t Uart_RecvFlag(void)
{
		if(UartRxOKFlag==0x55)
		{
			UartRxOKFlag=0;
			UartRxLen=UartIntRxLen;
			memcpy(Usart1Data.Uart_RxBuff,UartIntRxbuf,UartIntRxLen);//把缓冲区的数据,放入需要解析的数组
			UartIntRxLen=0;
			Usart1Data.Rx_Len  = UartRxLen; //取出最后的接收长度
			Usart1Data.receive_flag = SET; //进定时器就是接收完成 设置完成标志位。
			return 1;
		}
		return 0;
}
//串口2在1字节接收完成回调函数
void HAL_UART_RxCpltCallback(void)
{
		UartRxFlag=0x55;//接收标志置位
		UartIntRxbuf[UartRxIndex]=USART_ReceiveData(USART1);//数据写入缓冲区
		UartRxIndex++;//记载数目加1
		if(UartRxIndex>=sizeof(UartIntRxbuf))//缓冲区是10字节,如果存满,归零
		{
			UartRxIndex=0;
		}
		  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//接收中断打开
}
//1ms调用一次,用来判断是否收完一帧
void UART_RecvDealwith(void)
{
	if(UartRxFlag==0x55)
	{
		if(UartIntRxLen<UartRxIndex)//UartIntRxLen小于UartRxIndex,说明有收到新的数据,把接收长度增加
		{
		UartIntRxLen=UartRxIndex;
		}else
		{
			UartRxTimer++;
			if(UartRxTimer>=50)//50ms,等待,没收到新数据,说明已经收完一帧
			{
				UartRxTimer=0;
				UartRxFlag=0;
				UartRxOKFlag=0x55;
				UartRxIndex=0;
			}
		}
	}
}

/*以上是串口 的通用接收 判断 回调  接收完成等函数*/

main函数代码

//主函数,采用外部8M晶振,72M系统主频,可以在void SetSysClock(void)函数中选择主频率设置
int main(void)
 {	
	int i;
	delay_init();	    	//延时函数初始化,通过Systick中断实现1ms延时功能  
	RCC_Configuration();//USART1时钟使能,GPIO时钟使能
	NVIC_Configuration();//中断接收使能
	GPIO_Config_Init();	//USART1管脚PA9,PA10初始化
	USART_Config_Init();//USART1配置,波特率115200,8位数据,1位停止位,无校验
	OLED_Init();//OLED初始化  
	OLED_Clear();//OLED清屏 
	OLED_ShowCHinese(18,0,0);//显示中文(光)
	OLED_ShowCHinese(36,0,1);//显示中文(子)
	OLED_ShowCHinese(54,0,2);//显示中文(物)
	OLED_ShowCHinese(72,0,3);//显示中文(联)
	OLED_ShowCHinese(90,0,4);//显示中文(网)
	OLED_ShowString(6,3,(uint8_t *)"Face Detection");//显示字符
	OLED_ShowString(6,6,(uint8_t *)"STM32F103 Demo");//显示字符  

	Uart1_Send_Reset();//模组复位命令。

  while (1)
  {
		OLED_DISPLAY();//显示函数
		KEY_SCAN();	//按键扫描函数。
		Uart1_Deal();//与人脸识别模块通讯 
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
	
 }

人脸识别配置相关

/**复位命令。。。*/
void Uart1_Send_Reset(void)      
{
	uint8_t i;
	i = 0;
	Usart1Data.Uart_TxBuff[i++] = 0xEF;   //固定的消息开头同步字 0xEF 0xAA
	Usart1Data.Uart_TxBuff[i++] = 0xAA;		//固定的消息开头同步字 0xEF 0xAA
	Usart1Data.Uart_TxBuff[i++] = 0x10;		//消息 ID   0X10复位信息
	Usart1Data.Uart_TxBuff[i++] = 0x00;		//数据大小 几个字节。高8位 数据位 高字节
	Usart1Data.Uart_TxBuff[i++] = 0x00;		//数据大小 几个字节。低8位   后边没数据位了  数据位低字节。
	Usart1Data.Uart_TxBuff[i++] = 0x10;		//没有数据位了 这位就是校验位
	UART1_Send(i);
//delay_ms(100); //删除等待
}

/**核实发送识别。**/
void Uart1_Send_Verify(void)   //串口1给 屏幕识别的信息 。  解锁 开始 识别人脸 开始比对。  开始识别。。。。
{
	uint8_t i;
	i = 0;
	Usart1Data.Uart_TxBuff[i++] = 0xEF;//固定的消息开头同步字 0xEF 0xAA
	Usart1Data.Uart_TxBuff[i++] = 0xAA;//固定的消息开头同步字 0xEF 0xAA
	Usart1Data.Uart_TxBuff[i++] = 0x12;//消息 ID   0X12复位信息, 解锁。 解锁后断电。?????
	Usart1Data.Uart_TxBuff[i++] = 0x00; //数据大小 高8位
	Usart1Data.Uart_TxBuff[i++] = 0x02;//数据大小 低8位
	Usart1Data.Uart_TxBuff[i++] = 0x00; //数据
	Usart1Data.Uart_TxBuff[i++] = 0x05;	//数据 超时时间
	Usart1Data.Uart_TxBuff[i++] = 0x15;  //异或校验   异或校验是 从 EF AA 的后边 开始的  最后一位是异或校验
	UART1_Send(i);

}
/*删除人员的ID*/ //这个是删除指定人员的ID
void Uart1_Send_Delete_User_ID(uint16_t  ID)
{
	uint8_t i;
	i = 0;
	Usart1Data.Uart_TxBuff[i++] = 0xEF;
	Usart1Data.Uart_TxBuff[i++] = 0xAA;
	Usart1Data.Uart_TxBuff[i++] = 0x20;  //删除用户   //删除指定的用户。
	Usart1Data.Uart_TxBuff[i++] = 0x00;		//数据长度高字节
	Usart1Data.Uart_TxBuff[i++] = 0x02;		//数据长度低字节
	Usart1Data.Uart_TxBuff[i++] = (ID >> 8) &0XFF;  //取高8位
	Usart1Data.Uart_TxBuff[i++] = ID & 0XFF;				//取低8位
	Usart1Data.Uart_TxBuff[i++] = Check_Sum_Xor(&Usart1Data.Uart_TxBuff[2],5);
	
	UART1_Send(i);

}

/**读取模组内所有的 ID的命令协议不同单独处理。**/
void Uart1_Send_Get_All_User_ID(void) //读取模组内部所有用户数量和用户ID列表  
{
	uint8_t i;
	i = 0;
	Usart1Data.Uart_TxBuff[i++] = 0xEF;
	Usart1Data.Uart_TxBuff[i++] = 0xAA;
	Usart1Data.Uart_TxBuff[i++] = 0x24; //读取模组内部所有用户数量和用户ID列表,
	Usart1Data.Uart_TxBuff[i++] = 0x00; //高字节
	Usart1Data.Uart_TxBuff[i++] = 0x01; //低字节 
	Usart1Data.Uart_TxBuff[i++] = 0x00; //低字节  
	Usart1Data.Uart_TxBuff[i++] = 0x25;  //异或校验。。。。。。
	UART1_Send(i);
}


//**删除所有命令。
void	Uart1_Delete_all_User_ID(void)
{
	uint8_t i;
	i = 0;
	Usart1Data.Uart_TxBuff[i++] = 0xEF;
	Usart1Data.Uart_TxBuff[i++] = 0xAA;
	Usart1Data.Uart_TxBuff[i++] = 0x21; //读取模组内部所有用户数量和用户ID列表,
	Usart1Data.Uart_TxBuff[i++] = 0x00; //高字节
	Usart1Data.Uart_TxBuff[i++] = 0x00; //低字节  
	Usart1Data.Uart_TxBuff[i++] = 0x21;  //异或校验。。。。。。
	UART1_Send(i);
	
}


///***删除指定人员的ID 
void Uart1_Send_Delete_Point_User_ID(uint8_t H_D,uint8_t L_D)
{
	uint8_t i;
	i = 0;
	Usart1Data.Uart_TxBuff[i++] = 0xEF;
	Usart1Data.Uart_TxBuff[i++] = 0xAA;
	Usart1Data.Uart_TxBuff[i++] = 0x20;  //删除用户   //删除指定的用户。
	Usart1Data.Uart_TxBuff[i++] = 0x00;		//数据长度高字节
	Usart1Data.Uart_TxBuff[i++] = 0x02;		//数据长度低字节
	Usart1Data.Uart_TxBuff[i++] = H_D;//取高8位
	Usart1Data.Uart_TxBuff[i++] =	L_D;//取低8位
	Usart1Data.Uart_TxBuff[i++] = Check_Sum_Xor(&Usart1Data.Uart_TxBuff[2],5);
	
	UART1_Send(i);
}



/**手动单帧 添加人脸命令**/
void Uart1_Send_EnrollSingleWithID_Point_User_ID(void)
{
	uint8_t i;
	i = 0;
	Usart1Data.Uart_TxBuff[i++] = 0xEF;
	Usart1Data.Uart_TxBuff[i++] = 0xAA;
	Usart1Data.Uart_TxBuff[i++] = 0x1D;  //录入用户。
	Usart1Data.Uart_TxBuff[i++] = 0x00;		//数据长度高字节
	Usart1Data.Uart_TxBuff[i++] = 0x23;		//数据长度低字节
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] = 0x00;
	Usart1Data.Uart_TxBuff[i++] =	0x0A;
	Usart1Data.Uart_TxBuff[i++] = Check_Sum_Xor(&Usart1Data.Uart_TxBuff[2],Usart1Data.Uart_TxBuff[4]+3);
	UART1_Send(i);
}
if(Usart1Data.receive_flag == SET) //接收完成标志位。   在中断里设置的接收完备
	{
		Usart1Data.receive_flag = RESET; //重新复位
//接收判断是什么状态。
		switch(Usart1Data.Uart_RxBuff[5]) //收到模块发送了过来的数据
		{
			case 0x10:    //这个是异或校验值。  
			{//复位成功
				///复位命令  
				Usart1Data.Uart_RxBuff[5] = 0;
				break;
			}
			case 0x01:    
			{//通知包
				/////*****/////备用未使用
				Usart1Data.Uart_RxBuff[5] = 0;
		
				
				break;
			}
			case 0x12: //识别
			{
				if(Usart1Data.Uart_RxBuff[6] == 0x00 &&((Usart1Data.Uart_RxBuff[7] << 8) + Usart1Data.Uart_RxBuff[8]) < 101) //ID最大的值是1----100   //识别成功后有数据。   
					{/*识别成功后的ID*/
						Face_ID =	Usart1Data.Uart_RxBuff[7]<<8 |Usart1Data.Uart_RxBuff[8];
						
						Display_Cmd = 0x02;//识别成功
						////人脸识别成功   // 显示人脸识别成功。
						//去显示识别成功
					}
					else if(Usart1Data.Uart_RxBuff[6] == 0x08 && Usart1Data.Uart_RxBuff[7] == 0x18) //没有已录入的用户  未检测到人脸  
					{
						Display_Cmd = 0x04;//显示未注册

					}
					//如果都不是识别到的数据。都不是识别到的ID
					else  ///    EF AA 00 00 26 12 08 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3C  
							//对应的识别失败。Uart_RxBuff[7]  Uart_RxBuff[8]  是 FF FF 就是识别失败 成功会返回识别到的正确ID。
					{//识别失败
						Display_Cmd = 0x03;//显示识别失败
						
					}
					break;   //正常switch识别到然后退出。。。。
				//去显示识别成功。
			}
			case 0x1D:	 //这个是 添加人脸特征值返回的数据。
			{
				if(Usart1Data.Uart_RxBuff[6] == 0x00)//注册成功
					{
						Face_ID =	Usart1Data.Uart_RxBuff[7]<<8 |Usart1Data.Uart_RxBuff[8];//添加成功后返回添加的ID值是多少。
						
						Display_Cmd = 0x07;//去显示录入成功
					
					}			
				else if(Usart1Data.Uart_RxBuff[6]==0x0A) //杭州模组不适用。
					{
						Display_Cmd = 0x08;
					}
				else if(Usart1Data.Uart_RxBuff[6]==0x0D) //杭州模组录入超时  录入的时候没有人脸的情况下。
					{
						Display_Cmd = 0x09;//显示录入失败
					
					}
					else
					{
						Display_Cmd = 0x09;//显示录入失败
					}
				break;
			}
	
			case 0x21:  // 删除所有人脸 回复命令  
				{	
					Display_Cmd = 0x0A; //显示清除人脸中 然后显示清除成功。
				break;
				}
			default:
			{	
			break;
			}
		}

3.实验效果

按下 KEY 按键,1 秒松手,液晶上提示“开始识别”
在这里插入图片描述
第一次使用,还未录入人脸,液晶上会提示“未注册”
在这里插入图片描述
按住 KEY 按键,10 秒~19 秒之间时效即可,松手,液晶上会提示“录入人脸中”
在这里插入图片描述
拿起人脸识别模块,对准人脸,进行录入。人脸识别模块上的指示灯会闪烁红灯,直到指示灯停止闪烁,液晶上会显示“录入成功 Face_ID: 1”

在这里插入图片描述

按下 KEY 按键,1 秒松手,液晶上提示“开始识别”,把人脸识别模块对准已录入过的人脸,模块上的指示灯会闪烁一下,然后液晶上会提示“识别成功 Face_ID: 1”。
在这里插入图片描述

七.小结

学会人脸识别模块编程,可以很方便应用到实际项目中,如门禁系统和考勤管理,可以实现人脸识别和打卡功能。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐