一.简介:
1.内置光源和环境光抑制滤波器集成的 LED,镜头和手势感测器在一个小的立方体模组,能在黑暗或低光环境下工作

2.PAJ7620U2 的特点包括:
①IIC 接口,支持高达 400Khz 通信速率。
②内置 9 个手势类型(上、下、左、右、前、后、顺时针旋转、逆时针旋转、挥动),
支持输出中断。
③支持接近检测功能,检测物体体积大小和亮度
3.PAJ7620U2 内部自带 LED 驱动器传感器感应阵列目标信息提取阵列和手势识别阵列

二.工作原理:
PAJ7620U2 工作时通过内部 LED 驱动器,驱动红外 LED向外发射红外线信号,当传感器阵列在有效的距离中探测到物体时,目标信息提取阵列会对探测目标进行特征原始数据的获取,获取数据会存在寄存器中,同时手势识别阵列会对原始数据进行识别处理,最后将手势结果存到寄存器中,用户可根据 I2C 接口对原始数据和手势识别的结果进行读取

python识别手势 mediapipe 手势识别 csdn_寄存器


三.模块常用寄存器简介

1.在 PAJ7620U2 的内部有两个 BANK 寄存器区域,分别是 BANK0BANK12.想访问其中的 BANK 区域下的寄存器,需在访问前发送控制指令进入该寄存器区域,具体控制指令如表 1.3.1 所示:

python识别手势 mediapipe 手势识别 csdn_寄存器_02


进入 BANK0 区域往传感器 0xEF 地址写 0x00 数值,而 BANK1 区域往传感器 0xEF 地址写 0x01 数值① PAJ7620U2 使能工作寄存器在BANK1

地址0x72

python识别手势 mediapipe 手势识别 csdn_手势识别_03


只关心 bit0 位,设置为 1,则使能PAJ7620 工作,设置为 0,则失能 PAJ7620U2 工作BANK0 下的挂起管理寄存器

地址0x03

python识别手势 mediapipe 手势识别 csdn_寄存器_04


使能和挂起操作

python识别手势 mediapipe 手势识别 csdn_手势识别_05

要进入挂起状态,首先通过写寄存器Bank 1, ADDR Ox72 with Oxoo禁用PAJ7620U2,然后通过写寄存器Bank O, ADDR Ox03 with Ox01处理IC suspend命令。

要退出挂起状态,首先通过写入从ID(参考主题“12C总线时序特征和协议”)处理I2C唤醒命令,然后通过使用Ox01写入寄存器Bank 1, ADDR 0x72启用PAJ7620U2

退出挂起到唤醒工作,则需执行 3 个步骤:

python识别手势 mediapipe 手势识别 csdn_初始化_06


python识别手势 mediapipe 手势识别 csdn_手势识别_07


③检测手势寄存器

BANK0 下的手势检测输出中断使能寄存器 1

地址0x41

python识别手势 mediapipe 手势识别 csdn_寄存器_08


bit0 位为“上”、bit1 位为“下”、bit2 位为“左”、bit3 位为“右”、bit4 位为

“前”、bit5 位为“后”、bit6 位为“顺时针旋转”、而 bit7 位为“逆时针旋转”

对应位设置为 1,则使能,当检测到对应的手势识别时,会输出对应手势识别结果中断BANK0 下的手势检测输出中断使能寄存器 2

地址0x42

该寄存器保留7:1位

bit0 为用于使能手势识别“挥动”的输出中断

python识别手势 mediapipe 手势识别 csdn_寄存器_09


④标志寄存器:当 PAJ7620U2 检测到内置的手势,则对应的寄存器手势标志会置 1,读取标志可清除对应的中断标志位。用户根据读取对应的状态,可知道当前手势识别

的结果

BANK0 的手势识别中断标志寄存器 2

地址0x43

python识别手势 mediapipe 手势识别 csdn_寄存器_10


BANK0 的手势识别中断标志寄存器 2

地址0x44

python识别手势 mediapipe 手势识别 csdn_初始化_11

5.BANK0 的检测物体亮度寄存器

地址0xb0

python识别手势 mediapipe 手势识别 csdn_手势识别_12


当物体在 PAJ7620U2 的有效检测距离内,读取该寄存器能获得物体的亮度,亮度值为 0~2556.BANK0 的检测物体体积大小寄存器

地址0XB2,0XB1

python识别手势 mediapipe 手势识别 csdn_初始化_13


0XB2 寄存器的低四位值和 0XB1寄存器八位值

体积值为 0~900

四.开发板实验

  1. 流程图

    模块初始化:上电初始化
    手势识别测试:需要先手势初始化
    接近检测测试:需要先接近检测初始化
    所谓初始化就是把商家提供的配置组写入BANK0

在 PAJ7620U2 的初始化中,需配置多个寄存器,而有些寄存器手册没提及到,不过幸好的是手册上有提供配置数组给用户,我们直接调用就可以了。
同样手势识别和接近检测手册也有提供初始化配置数组,我们也是调用就可以了
2. 硬件连接

python识别手势 mediapipe 手势识别 csdn_寄存器_14


python识别手势 mediapipe 手势识别 csdn_手势识别_15

模块通过 IIC 接口与外部进行通信,上电时,默认的 IIC 从机地址为:0X73(使用时需
左移一位)
3.软件实现
新建 paj7620u2.c、paj7620u2.h、paj7620u2_iic.c、
paj7620u2_iic.h、paj7620u2_cfg.h 共 5 个文件

paj7620u2.c 文件为手势识别和接近检测的驱动
paj7620u2_iic 文件为底层的 IIC 驱动
paj7620u2_cfg.h 文件为存放上电初始化手势
识别初始化
、以及接近检测初始化配置数组

a.在 paj7620u2_cfg.h 中


python识别手势 mediapipe 手势识别 csdn_寄存器_16

python识别手势 mediapipe 手势识别 csdn_手势识别_17


python识别手势 mediapipe 手势识别 csdn_寄存器_18


在这三个数组里包含上电,接近检测,手势识别数组,是二维数组,每个数组的第一个字节为寄存器号(也就是寄存器地址),第二个字节为要设置的值

b.在 paj7620u2_iic.c 文件
该文件包括 PAJ7620U2 的 IIC 底层驱动读写函数引脚 IO 初始化以及唤醒命令的函数
唤醒命令的函数
//PAJ7620U2 唤醒命令
void GS_WakeUp(void)
{
GS_IIC_Start();//开始
GS_IIC_Send_Byte(PAJ7620_ID);//发写命令
GS_IIC_Stop();//释放总线
}
在该函数中直接写命令,不用等待PAJ回应

c.在paj7620u2.c 文件
该文件包括手势识别和接近检测等代码

  1. paj7620u2_selectBank()函数,该函数实现选择 BANK 区域,通过 bank 的入口参数选择要进入 BANK 的区域
1.  //选择 PAJ7620U2 BANK 区域
 void paj7620u2_selectBank(bank_e bank)
 {
 switch(bank)
 {
 case BANK0: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK0);break;
 //BANK0 寄存器区域
 case BANK1: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK1);break;
 //BANK1 寄存器区域
 } }2. paj7620u2_wakeup()函数,该函数实现对 PAJ7620U2 唤醒
 //PAJ7620U2 唤醒
 u8 paj7620u2_wakeup(void)
 {
 u8 data=0x0a;
 GS_WakeUp();//唤醒 PAJ7620U2
 delay_ms(5);//唤醒时间>700us
 GS_WakeUp();//唤醒 PAJ7620U2
 delay_ms(5);//唤醒时间>700us
 paj7620u2_selectBank(BANK0);//进入 BANK0 寄存器区域
 data = GS_Read_Byte(0x00);//读取状态
 if(data!=0x20) return 0; //唤醒失败
 return 1;
 }
 在发送唤醒命令后需等待大于 700us 的时间,然后切换到 BANK0 区域,读取 0x00 寄存器,判断读取的值是否为 0x20,若是则唤醒成功,否则唤醒失败3.paj7620u2_init()函数,该函数实现对 PAJ7620U2 初始化
 //PAJ7620U2 初始化
 //返回值:0:失败 1:成功
 u8 paj7620u2_init(void)
 {
 u8 i;
 u8 status;
 GS_i2c_init();//IIC 初始化
 status = paj7620u2_wakeup();//唤醒 PAJ7620U2
 if(!status) return 0;
 paj7620u2_selectBank(BANK0);//进入 BANK0 寄存器区域
 for(i=0;i<INIT_SIZE;i++)
 {
 GS_Write_Byte(init_Array[i][0],init_Array[i][1]);//初始化 PAJ7620U2
 }
 paj7620u2_selectBank(BANK0);//切换回 BANK0 寄存器区域
 return 1;
 }
 先对 IIC 通信的 IO 引脚初始化,然后调用paj7620u2_wakeup()函数对 PAJ7620U2 进行唤醒,唤醒成功后,由于后面要调用 init_Array初始化数组,初始化时是从 BANK0 区域开始的,所以这里先选择进入 BANK0 区域,初始化数组配置完毕后,又切换回 BANK0 区域,这时 PAJ7620U2 初始化完成4.Gesrure_test()函数,该函数实现手势识别功能
 一开始先对 PAJ7620U2 手势识别检测进行初始化,配置其gesture_arry 数组的参数值,该数组有使能 9 个手势识别的中断标志输出的配置,初始化完毕后,在 while 循环中一直读取手势中断标志寄存器,当识别到相应的手势,手势标志会置 1,读取寄存器标志会自动清 0
 //手势识别测试-手势初始化
 void Gesture_test(void)
 {
 u8 i;
 u8 status;
 u8 key;
 u8 data[2]={0x00};
 u16 gesture_data;
 u8 ledflash=0;
//该部分为初始化手势检测
paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
for(i=0;i<GESTURE_SIZE;i++)
{
	GS_Write_Byte(gesture_arry[i][0],gesture_arry[i][1]);//手势识别模式初始化
}
paj7620u2_selectBank(BANK0);//切换回BANK0寄存器区域
/******************************/
 i=0;
 POINT_COLOR=BLUE;//设置字体为蓝色
 LCD_Fill(30,170,300,300,WHITE);
 LCD_ShowString(30,180,200,16,16,“KEY_UP: Exit the test”);
 LCD_ShowString(30,210,200,16,16,“Gesture test”);
 POINT_COLOR=RED;//设置字体为蓝色
 while(1)
 {
 //按键关闭检测
 key = KEY_Scan(0);
 if(key==WKUP_PRES)
 {
 GS_Write_Byte(PAJ_SET_INT_FLAG1,0X00);//关闭手势识别中断输出
 GS_Write_Byte(PAJ_SET_INT_FLAG2,0X00);
 break;
 } 
 //读取手势标志位 
 status = GS_Read_nByte(PAJ_GET_INT_FLAG1,2,&data[0]);//读取手势状态 
 if(!status)
 {
 gesture_data =(u16)data[1]<<8 | data[0];
 if(gesture_data)
 {
 switch(gesture_data)
 {
 case GES_UP: LCD_ShowString(110,250,200,16,24,"UP ");
 printf(“Up\r\n”); ledflash=1; break; //向上
 case GES_DOWM: LCD_ShowString(100,250,200,16,24,"Dowm ");
 printf(“Dowm\r\n”); ledflash=1; break; //向下
 case GES_LEFT: LCD_ShowString(100,250,200,16,24,"Left ");
 printf(“Left\r\n”); ledflash=1; break; //向左
 case GES_RIGHT: LCD_ShowString(100,250,200,16,24,"Right ");
 printf(“Right\r\n”); ledflash=1; break; //向右
 case GES_FORWARD: LCD_ShowString(80,250,200,16,24,"Forward ");
 printf(“Forward\r\n”); ledflash=1; break; //向前
 case GES_BACKWARD: LCD_ShowString(80,250,200,16,24,"Backward ");
 printf(“Backward\r\n”); ledflash=1; break; //向后
 case GES_CLOCKWISE: LCD_ShowString(70,250,200,16,24,"Clockwise ");
 printf(“Clockwise\r\n”); ledflash=1; break; //顺时针
 case GES_COUNT_CLOCKWISE: LCD_ShowString(50,250,200,16,24,“AntiClockwise”);
 printf(“AntiClockwise\r\n”); ledflash=1; break; //逆时针
 case GES_WAVE: LCD_ShowString(100,250,200,16,24,"Wave ");
 printf(“Wave\r\n”); ledflash=1; break; //挥动
 default: ledflash=0; break;
}	
            if(ledflash)//DS1闪烁
			{   
				LED1=0;delay_ms(80);LED1=1;delay_ms(80);
				LED1=0;delay_ms(80);LED1=1;delay_ms(80);
				LCD_ShowString(40,250,200,16,24,"                        ");
				ledflash=0;
			}						
		}
		
	}
	delay_ms(50);
	i++;
	if(i==5)
	{
		LED0=!LED0;//提示系统正在运行	
		i=0;
	}		   
}

}
在该函数里不断读取手势中断标志位从而识别是何种手势

附:IIC协议

PAJ7620U2地址是0X73,7位寻址即左移一位

以下协议包含时序:

单写时序

单读时序

唤醒PAJ7620U2协议

python识别手势 mediapipe 手势识别 csdn_寄存器_19


全部寄存器

python识别手势 mediapipe 手势识别 csdn_初始化_20


python识别手势 mediapipe 手势识别 csdn_初始化_21


IIC中应答问题:应答目的是提醒发送端数据我这边已经接收完成
主机发数据给从机需要从机应答
主机读从机数据需要主机应答

IIC是按字节来传输的,当每传输完一个字节的数据,后面必须紧跟一个校验位,这个校验位是接收端通过控制SDA(数据线)来实现的,以提醒发送端数据我这边已经接收完成。
(SDA=0为ACK 接收完成 SDA=1为NACK 繁忙中)
主机应答: 传输完一个字节数据以后(数据传输方向:从机—>主机),主机控制(此时是接收端)SDA来提醒从机(发送端)我这边接受完成
从机应答: 传输完一个字节数据以后(数据传输方向:主机—>从机),从机控制(此时是接收端)SDA来提醒主机(发送端)我这边接受完成