这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【手势翻页笔】过程贴

共4条 1/1 1 跳转至

【手势翻页笔】过程贴

高工
2024-06-17 17:38:53     打赏

   PAJ7620U2是一款由PixArt(原相科技)公司开发的手势识别传感器模块。以下是关于PAJ7620U2的详细介绍:


  


3.jpg

  1. 基本特性

    • 手势识别:PAJ7620U2支持多达9种不同方向的手势识别,包括上、下、左、右、前、后、顺时针旋转、逆时针旋转和挥动。

    • 工作电压:工作电压范围为3.3V至5.0V,适用于多种电源环境。

    • 手势速度:在正常模式下,手势识别速度可达60°/S至600°/S;而在游戏模式下,速度更是提升至60°/S至1200°/S。

    • 环境光免疫力:具备强大的环境光免疫力,能在小于100K Lux的环境光下正常工作。

    • 工作电流:工作电流在3mA至10mA之间,功耗较低。

    • 尺寸:模块尺寸小巧,仅为20mm*15mm,方便集成到各种设备中。

  2. 工作原理

    • PAJ7620U2基于红外线反射和类似微软Kinect的深度视觉技术实现手势识别。

    • 它使用一个由红外发光二极管(IR-LED)和一对红外光传感器(IR photodiode)组成的衍射贴片(Diffraction Gratings)矩阵来发射和接收红外光信号。

    • 当用户的手或其他物体在传感器的有效距离内移动时,它们会反射红外光信号。传感器通过计算这些反射光信号的强度和相位变化来识别不同的手势并跟踪其运动轨迹。

  3. 应用场景

    • PAJ7620U2的手势识别传感器可用于多种非接触式控制场景,如非接触式鼠标、智能家居、汽车设备控制、机器人交互等。

    • 它能够提供方便、舒适和卫生的交互方式,同时不受环境光、皮肤颜色等因素的干扰,适用于室内、室外等不同场景。

  4. 接口与通信

    • PAJ7620U2使用IIC(I2C)接口进行通信,通信速率可达400KHz。这使得它可以方便地与各种微控制器(MCU)进行连接和通信。

  5. 模块结构

    • PAJ7620U2模块包括电源正极输入口(VCC)、电源负极输入口(GND)、IIC时钟端口(SCL)、IIC数据端口(SDA)和中断输出端口(INT)。这些引脚允许用户与传感器进行各种交互和配置。

      4.png原理参考:

      1.png

关于STM32 H5

2.jpg

      STM32H5系列的IIC(Inter-Integrated Circuit)是一个用于连接微控制器及其外围设备的两线式串行总线。STM32H5是一款高性能的微控制器(MCU),基于运行频率高达250 MHz的32位Arm® Cortex®-M33内核。

1. I²C接口特点
  • 半双工同步通信方式:I²C支持半双工通信,即数据可以在一个时刻内仅沿一个方向传输。

  • 简单性和有效性:I²C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。

  • 多主控(multimastering):I²C总线允许多主机存在,任何能够进行发送和接收的设备都可以成为主总线。但在任何时间点上只能有一个主控。

  • 传输速率:I²C支持多种传输速率模式,包括标准模式(100kbit/s)、快速模式(400kbit/s)和高速模式(可达3.4Mbit/s)。

2. I²C接口物理层
  • 信号线:I²C总线有两根信号线,一根是双向的数据线SDA(Serial Data Line),另一根是时钟线SCL(Serial Clock Line)。

  • 连接方式:在STM32H5与外设(如MPU6050陀螺仪)连接时,通常使用I²C接口中的SCL和SDA两条线。例如,在连接MPU6050时,可以使用STM32H5的某个I²C接口的PC2引脚作为SCL,PC3引脚作为SDA。

3. I²C通信过程
  • 起始信号和终止信号:当SCL为高电平时,SDA从高电平跳变到低电平表示起始信号;当SCL为高电平时,SDA从低电平跳变到高电平表示终止信号。

  • 应答信号:主机每发送一个字节(8个bit),就在第9个时钟脉冲期间释放SDA线,由从机反馈一个应答信号。应答信号为低电平时表示有效应答(ACK),为高电平时表示非应答(NACK)。

4. STM32H5 I²C配置与使用
  • 配置IO口:将STM32H5的某个GPIO口配置为I²C功能,并设置其模式为GPIO_Mode_AF_OD(复用开漏输出)。

  • 选择I²C模式:配置I²C的工作模式(如主模式或从模式)、通信速度等。

  • 初始化流程:包括配置IO口、选择I²C模式、设置传输速率等步骤。

  • 读写操作:STM32H5的I²C读写操作与标准I²C总线类似,包括发送设备地址、等待应答、发送/接收数据等步骤。

    Cube配置:

    66.png

    ——回复可见内容——

  • #include "i2c.h"
    I2C_HandleTypeDef hi2c1;
    /* I2C1 init function */
    void MX_I2C1_Init(void)
    {
      /* USER CODE BEGIN I2C1_Init 0 */
    
      /* USER CODE END I2C1_Init 0 */
    
      /* USER CODE BEGIN I2C1_Init 1 */
    
      /* USER CODE END I2C1_Init 1 */
      hi2c1.Instance = I2C1;
      hi2c1.Init.Timing = 0x60808CD3;
      hi2c1.Init.OwnAddress1 = 0;
      hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
      hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
      hi2c1.Init.OwnAddress2 = 0;
      hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
      hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
      hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
      if (HAL_I2C_Init(&hi2c1) != HAL_OK)
      {
        Error_Handler();
      }
    
      /** Configure Analogue filter
      */
      if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
      {
        Error_Handler();
      }
    
      /** Configure Digital filter
      */
      if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN I2C1_Init 2 */
    
      /* USER CODE END I2C1_Init 2 */
    
    }
    
    void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
      if(i2cHandle->Instance==I2C1)
      {
      /* USER CODE BEGIN I2C1_MspInit 0 */
    
      /* USER CODE END I2C1_MspInit 0 */
    
      /** Initializes the peripherals clock
      */
        PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
        PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
        if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
        {
          Error_Handler();
        }
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**I2C1 GPIO Configuration
        PB6     ------> I2C1_SCL
        PB7     ------> I2C1_SDA
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        /* I2C1 clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();
      /* USER CODE BEGIN I2C1_MspInit 1 */
    
      /* USER CODE END I2C1_MspInit 1 */
      }
    }
    
    void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
    {
    
      if(i2cHandle->Instance==I2C1)
      {
      /* USER CODE BEGIN I2C1_MspDeInit 0 */
    
      /* USER CODE END I2C1_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_I2C1_CLK_DISABLE();
    
        /**I2C1 GPIO Configuration
        PB6     ------> I2C1_SCL
        PB7     ------> I2C1_SDA
        */
        HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
    
        HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
    
      /* USER CODE BEGIN I2C1_MspDeInit 1 */
    
      /* USER CODE END I2C1_MspDeInit 1 */
      }
    }

PAJ7620U2.h 配置文件
#ifndef _PAJ7620U2_
#define _PAJ7620U2_

//i2c address
#define PAJ7620U2_I2C_ADDRESS		0x73<<1
//Register Bank select
#define PAJ_BANK_SELECT			0xEF		/*Bank0=0x00,Bank1=0x01*/
//Register Bank 0
#define PAJ_SUSPEND			 	0x03		/*I2C suspend command (Write 0x01 to enter suspend state). I2C wake-up command is slave ID wake-up. Refer to topic “I2C Bus Timing Characteristics and Protocol”*/
#define PAJ_INT_FLAG1_MASK		0x41		/*Gesture detection interrupt flag mask*/
#define PAJ_INT_FLAG2_MASK		0x42		/*Gesture/PS detection interrupt flag mask*/
#define PAJ_INT_FLAG1		    0x43		/*Gesture detection interrupt flag*/
#define PAJ_INT_FLAG2			0x44		/*Gesture/PS detection interrupt flag*/
#define PAJ_STATE				0x45		/*State indicator for gesture detection (Only functional at gesture detection mode)*/
#define PAJ_PS_HIGH_THRESHOLD	0x69		/*PS hysteresis high threshold (Only functional at proximity detection mode)*/		
#define PAJ_PS_LOW_THRESHOLD	0x6A		/*PS hysteresis low threshold (Only functional at proximity detection mode)*/
#define PAJ_PS_APPROACH_STATE	0x6B		/*PS approach state,  Approach = 1 , (8 bits PS data >= PS high threshold),  Not Approach = 0 , (8 bits PS data <= PS low threshold)(Only functional at proximity detection mode)*/
#define PAJ_PS_DATA				0x6C		/*PS 8 bit data(Only functional at gesture detection mode)*/
#define PAJ_OBJ_BRIGHTNESS		0xB0		/*Object Brightness (Max. 255)*/
#define PAJ_OBJ_SIZE_L			0xB1		/*Object Size(Low 8 bit)*/		
#define PAJ_OBJ_SIZE_H			0xB2		/*Object Size(High 8 bit)*/	

//Register Bank 1
#define PAJ_PS_GAIN				0x44		/*PS gain setting (Only functional at proximity detection mode)*/
#define PAJ_IDLE_S1_STEP_L		0x67		/*IDLE S1 Step, for setting the S1, Response Factor(Low 8 bit)*/
#define PAJ_IDLE_S1_STEP_H		0x68		/*IDLE S1 Step, for setting the S1, Response Factor(High 8 bit)*/	
#define PAJ_IDLE_S2_STEP_L		0x69		/*IDLE S2 Step, for setting the S2, Response Factor(Low 8 bit)*/
#define PAJ_IDLE_S2_STEP_H		0x6A		/*IDLE S2 Step, for setting the S2, Response Factor(High 8 bit)*/
#define PAJ_OPTOS1_TIME_L		0x6B		/*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 state(Low 8 bit)*/	
#define PAJ_OPTOS2_TIME_H		0x6C		/*OPtoS1 Step, for setting the OPtoS1 time of operation state to standby 1 stateHigh 8 bit)*/	
#define PAJ_S1TOS2_TIME_L		0x6D		/*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 state(Low 8 bit)*/	
#define PAJ_S1TOS2_TIME_H		0x6E		/*S1toS2 Step, for setting the S1toS2 time of standby 1 state to standby 2 stateHigh 8 bit)*/	
#define PAJ_EN					0x72		/*Enable/Disable PAJ7620U2*/
//Gesture detection interrupt flag
#define PAJ_UP				    0x01 
#define PAJ_DOWN			    0x02
#define PAJ_LEFT			    0x04 
#define PAJ_RIGHT			    0x08
#define PAJ_FORWARD			    0x10 
#define PAJ_BACKWARD		    0x20
#define PAJ_CLOCKWISE			0x40
#define PAJ_COUNT_CLOCKWISE		0x80
#define PAJ_WAVE				0x100
//Initialize array size
#define Init_Array sizeof(Init_Register_Array)/2
#define PS_Array_SIZE sizeof(Init_PS_Array)/2
#define Gesture_Array_SIZE sizeof(Init_Gesture_Array)/2
//Power up initialize array
const unsigned char Init_Register_Array[][2] = {
	{0xEF,0x00},
	{0x37,0x07},
	{0x38,0x17},
	{0x39,0x06},
	{0x41,0x00},
	{0x42,0x00},
	{0x46,0x2D},
	{0x47,0x0F},
	{0x48,0x3C},
	{0x49,0x00},
	{0x4A,0x1E},
	{0x4C,0x20},
	{0x51,0x10},
	{0x5E,0x10},
	{0x60,0x27},
	{0x80,0x42},
	{0x81,0x44},
	{0x82,0x04},
	{0x8B,0x01},
	{0x90,0x06},
	{0x95,0x0A},
	{0x96,0x0C},
	{0x97,0x05},
	{0x9A,0x14},
	{0x9C,0x3F},
	{0xA5,0x19},
	{0xCC,0x19},
	{0xCD,0x0B},
	{0xCE,0x13},
	{0xCF,0x64},
	{0xD0,0x21},
	{0xEF,0x01},
	{0x02,0x0F},
	{0x03,0x10},
	{0x04,0x02},
	{0x25,0x01},
	{0x27,0x39},
	{0x28,0x7F},
	{0x29,0x08},
	{0x3E,0xFF},
	{0x5E,0x3D},
	{0x65,0x96},
	{0x67,0x97},
	{0x69,0xCD},
	{0x6A,0x01},
	{0x6D,0x2C},
	{0x6E,0x01},
	{0x72,0x01},
	{0x73,0x35},
	{0x74,0x00},
	{0x77,0x01},
};
//Approaches register initialization array
const unsigned char Init_PS_Array[][2] = {
	{0xEF,0x00},
	{0x41,0x00},
	{0x42,0x00},
	{0x48,0x3C},
	{0x49,0x00},
	{0x51,0x13},
	{0x83,0x20},
	{0x84,0x20},
	{0x85,0x00},
	{0x86,0x10},
	{0x87,0x00},
	{0x88,0x05},
	{0x89,0x18},
	{0x8A,0x10},
	{0x9f,0xf8},
	{0x69,0x96},
	{0x6A,0x02},
	{0xEF,0x01},
	{0x01,0x1E},
	{0x02,0x0F},
	{0x03,0x10},
	{0x04,0x02},
	{0x41,0x50},
	{0x43,0x34},
	{0x65,0xCE},
	{0x66,0x0B},
	{0x67,0xCE},
	{0x68,0x0B},
	{0x69,0xE9},
	{0x6A,0x05},
	{0x6B,0x50},
	{0x6C,0xC3},
	{0x6D,0x50},
	{0x6E,0xC3},
	{0x74,0x05},
};

//Gesture register initializes array
const unsigned char Init_Gesture_Array[][2] = {
	{0xEF,0x00},
	{0x41,0x00},
	{0x42,0x00},
	{0xEF,0x00},
	{0x48,0x3C},
	{0x49,0x00},
	{0x51,0x10},
	{0x83,0x20},
	{0x9F,0xF9},
	{0xEF,0x01},
	{0x01,0x1E},
	{0x02,0x0F},
	{0x03,0x10},
	{0x04,0x02},
	{0x41,0x40},
	{0x43,0x30},
	{0x65,0x96},
	{0x66,0x00},
	{0x67,0x97},
	{0x68,0x01},
	{0x69,0xCD},
	{0x6A,0x01},
	{0x6B,0xB0},
	{0x6C,0x04},
	{0x6D,0x2C},
	{0x6E,0x01},
	{0x74,0x00},
	{0xEF,0x00},
	{0x41,0xFF},
	{0x42,0x01},
};

#endif

主函数:

unsigned char PAJ7620U2_init()
{
	unsigned char i,State;
	DEV_Set_I2CAddress(PAJ7620U2_I2C_ADDRESS);
	DEV_Delay_ms(5);
	State = DEV_I2C_ReadByte(0x00);												//Read State
	if (State != 0x20) 
		return 0;																						//Wake up failed
	DEV_I2C_WriteByte(PAJ_BANK_SELECT, 0);								//Select Bank 0
	for (i=0;i< Init_Array;i++)
	{
		 DEV_I2C_WriteByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
	}
	return 1;
}
 MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_I2C1_Init();
	printf("Gesture Sensor Test Program ...\r\n");
	if(!PAJ7620U2_init())
	{	printf("\nGesture Sensor Error\r\n");
		return 0;
	}
		printf("\nGesture Sensor OK\r\n");
	DEV_I2C_WriteByte(PAJ_BANK_SELECT, 0);																	//Select Bank 0
	for (i = 0; i < Gesture_Array_SIZE; i++)
	{
		DEV_I2C_WriteByte(Init_Gesture_Array[i][0], Init_Gesture_Array[i][1]);//Gesture register initializes
	}
  while (1)
  {
		Gesture_Data = DEV_I2C_ReadWord(PAJ_INT_FLAG1);
		if (Gesture_Data)
		{
			switch (Gesture_Data)
			{
				case PAJ_UP:			  			  printf("Up\r\n");				break;
				case PAJ_DOWN:							printf("Down\r\n");				break;
				case PAJ_LEFT:							printf("Left\r\n");				break;
				case PAJ_RIGHT:							printf("Right\r\n"); 			break;
				case PAJ_FORWARD:						printf("Forward\r\n");			break;
				case PAJ_BACKWARD:					printf("Backward\r\n"); 		break;
				case PAJ_CLOCKWISE:					printf("Clockwise\r\n"); 		break;
				case PAJ_COUNT_CLOCKWISE:		printf("AntiClockwise\r\n"); 	break;
				case PAJ_WAVE:							printf("Wave\r\n"); 			break;
				default: break;
			}
			Gesture_Data=0;
			DEV_Delay_ms(50);
		}
  }

识别.png非常灵敏的


高工
2024-06-18 12:57:34     打赏
2楼

谢谢分享


高工
2024-06-18 13:17:58     打赏
3楼

谢谢分享


高工
2024-06-24 06:54:38     打赏
4楼

谢谢分享


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]