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

共8条 1/1 1 跳转至

【DIY手势翻页笔】过程帖:读取手势传感器PAJ7620U2数据

菜鸟
2024-06-22 20:51:50     打赏

手势传感器模块https://wiki.seeedstudio.com/Grove-Gesture_v1.0/

PAJ7620U2 Gesture Sensor是一款基于PAJ7620U2的手势识别模块,可直接识别9种基本手势,支持I2C接口,兼容3.3V/5V电平。

特点

基于PAJ7620U2传感器,可直接识别9种基本手势,支持手势中断输出

内置红外LED和光学镜头,能在低光和黑暗环境下工作

支持I2C接口通信,仅需两根信号脚即可控制

板载电平转换电路,可兼容3.3V/5V的逻辑电平

产品参数

工作电压:3.3V/5V

通信接口:I2C

识别距离:5CM ~ 15CM

识别手势:上、下、左、右、前、后、顺时针、逆时针、摇摆

速度:240HZ

识别视角:60° (对角线)

环境光免疫力:<100K LUX

产品尺寸:20MM × 20MM

过孔直径:2.0MM

应用场景:智能家居、办公室和教学;机器人交互、手势玩具、体感游戏装备

接口说明

引脚功能

引脚号    标识    管脚描述    

1    GND    电源地    

2    VCC    3.3V/5V电源正    

3    SDA    I2C数据线    

4    SCL    I2C时钟线    


选择开发板上的i2c1接口

111.png











stm32cube的配置

22.png驱动代码

#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

实现

/*****************************************************************************
* | File      	:   DEV_Config.c
* | Author      :   Waveshare team
* | Function    :   Hardware underlying interface
* | Info        :
*                Used to shield the underlying layers of each master 
*                and enhance portability
*----------------
* |	This version:   V1.0
* | Date        :   2018-11-22
* | Info        :

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to  whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#include "DEV_Config.h"
UWORD IIC_Addr_t = IIC_Addr; 


void DEV_Set_I2CAddress(UBYTE add_)
{
	IIC_Addr_t = add_;
}

/******************************************************************************
function:	
	I2C Write and Read
******************************************************************************/
void DEV_I2C_WriteByte(UBYTE add_, UBYTE data_)
{
	UBYTE Buf[1] = {0};
	Buf[0] = data_;
	HAL_I2C_Mem_Write(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 1, 0x10);
}

void DEV_I2C_WriteWord(UBYTE add_, UWORD data_)
{
	UBYTE Buf[2] = {0};
	Buf[0] = data_ >> 8; 
	Buf[1] = data_;
	HAL_I2C_Mem_Write(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 2, 0x10);
}

UBYTE DEV_I2C_ReadByte(UBYTE add_)
{
	UBYTE Buf[1]={add_};
	HAL_I2C_Mem_Read(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 1, 0x10);
	return Buf[0];
}

UWORD DEV_I2C_ReadWord(UBYTE add_)
{
    UBYTE Buf[2]={0, 0};
		HAL_I2C_Mem_Read(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 2, 0x10);
    return ((Buf[1] << 8) | (Buf[0] & 0xff));
}

主函数测试

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "memorymap.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "DEV_Config.h"
#include "PAJ7620U2.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
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;
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_MEMORYMAP_Init();
  MX_USART3_UART_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
	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 (int i = 0; i < Gesture_Array_SIZE; i++)
	{
		DEV_I2C_WriteByte(Init_Gesture_Array[i][0], Init_Gesture_Array[i][1]);//Gesture register initializes
	}
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      // HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
      //HAL_Delay(100);
      //printf("hello\n");
      		UWORD 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);
		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 3;
  RCC_OscInitStruct.PLL.PLLN = 62;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 4096;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_PCLK3;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


接线

44.jpg

效果

33.png


院士
2024-06-23 07:12:56     打赏
2楼

谢谢楼主的分享~!


高工
2024-06-23 09:52:16     打赏
3楼

谢谢楼主的分享


高工
2024-06-23 10:45:06     打赏
4楼

谢谢楼主的分享


专家
2024-06-23 12:57:01     打赏
5楼

学习学习!


专家
2024-06-24 06:31:26     打赏
6楼

学习一下


工程师
2024-06-25 06:00:18     打赏
7楼

谢谢楼主的分享


专家
2024-06-28 07:09:17     打赏
8楼

谢谢楼主的分享


共8条 1/1 1 跳转至

回复

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