手势传感器模块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接口

stm32cube的配置
驱动代码
#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 */接线

效果

我要赚赏金
