【目的】
驱动PAJ7620U2,实现对手势的识别
【手势传感器介绍】
PAJ7620U2将手势识别功能与通用识别9个手势,包括向上移动,向~下移动,向左移动,向右移动,向前移动,向后移动,顺时针旋转,逆时针旋转和波动。可以通过12C总线简单地访问这些手势信息。PAJ7620U2还提供内置接近检测功能
用于检测接近或离开的物体。PAJ76202在节电机制方面具有极大的灵活性。
【实现步骤】
1、使用stm32cubeMAX新建工程,开启i2c1与串口2
2、生成mdk工程,并打开工程。
3、移植PAJ7620U2驱动,编写驱动如下:
PAJ7620U2.h
/*
******************************************************************************
* @file ( фаил ): PAJ7620U2.h
* @brief ( описание ):
******************************************************************************
* @attention ( внимание ): author: Golinskiy Konstantin e-mail: golinskiy.konstantin@gmail.com
******************************************************************************
*/
#ifndef _PAJ7620U2_H
#define _PAJ7620U2_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------*/
#include "main.h"
// num i2c ---------------------------------------------
#define PAJ7620U2_I2C hi2c1
//------------------------------------------------------
extern I2C_HandleTypeDef PAJ7620U2_I2C;
#define DEV_Delay_ms(__xms) HAL_Delay(__xms)
/*-----------------------------------------------------------------------------*/
//i2c address
#define PAJ7620U2_I2C_ADDRESS (0x73<<1)
//Register Bank select
#define PAJ_BANK_SELECT 0xEF //Bank0=0x00,Bank1=0x01
//Register ID ( read only )
#define PAJ_PART_ID_L 0x00 // result 0x20
#define PAJ_PART_ID_H 0x01 // result 0x76
#define PAJ_VERSION_ID 0x02 // result 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_NONE 0x0000 // отсутствует
#define PAJ_UP 0x0001 // вверх
#define PAJ_DOWN 0x0002 // вниз
#define PAJ_LEFT 0x0004 // влево
#define PAJ_RIGHT 0x0008 // вправо
#define PAJ_FORWARD 0x0010 // вперед
#define PAJ_BACKWARD 0x0020 // назад
#define PAJ_CLOCKWISE 0x0040 // по часовой стрелке
#define PAJ_ANTI_CLOCKWISE 0x0080 // против часовой стрелки
#define PAJ_WAVE 0x0100 // волна
#define PAJ_PARTID 0x7620
//Power up initialize array
extern const uint8_t Init_Register_Array[][2];
//Initialize array size
#define Init_Array sizeof(Init_Register_Array)/2
//Bank 0 or 1
typedef enum:uint8_t{
PAJ_BANK_0, //Bank0 = 0x00
PAJ_BANK_1 //Bank1 = 0x01
}Paj_Bank_Num;
/* Functions prototypes ----------------------------------------------*/
uint16_t PAJ7620U2_init(void);
uint16_t PAJ7620U2_Gesture_ReadData(void);
uint8_t PAJ7620U2_PS_ReadObjBrightness(void);
uint16_t PAJ7620U2_PS_ReadObjSize(void);
//------------------------------------------------------------------------------------
#ifdef __cplusplus
}
#endif
#endif /* _PAJ7620U2_H */
/************************ (C) COPYRIGHT GKP *****END OF FILE****/PAJ7620U2.c代码如下:
/*
******************************************************************************
* @file ( фаил ): PAJ7620U2.c
* @brief ( описание ):
******************************************************************************
* @attention ( внимание ): author: Golinskiy Konstantin e-mail: golinskiy.konstantin@gmail.com
******************************************************************************
*/
/* Includes ----------------------------------------------------------*/
#include "PAJ7620U2.h"
//Power up initialize array
const uint8_t Init_Register_Array[][2] = {
{0xEF,0x00},
{0x32,0x29},
{0x33,0x01},
{0x34,0x00},
{0x35,0x01},
{0x36,0x00},
{0x37,0x07},
{0x38,0x17},
{0x39,0x06},
{0x3A,0x12},
{0x3F,0x00},
{0x40,0x02},
{0x41,0xFF},
{0x42,0x01},
{0x46,0x2D},
{0x47,0x0F},
{0x48,0x3C},
{0x49,0x00},
{0x4A,0x1E},
{0x4B,0x00},
{0x4C,0x20},
{0x4D,0x00},
{0x4E,0x1A},
{0x4F,0x14},
{0x50,0x00},
{0x51,0x10},
{0x52,0x00},
{0x5C,0x02},
{0x5D,0x00},
{0x5E,0x10},
{0x5F,0x3F},
{0x60,0x27},
{0x61,0x28},
{0x62,0x00},
{0x63,0x03},
{0x64,0xF7},
{0x65,0x03},
{0x66,0xD9},
{0x67,0x03},
{0x68,0x01},
{0x69,0xC8},
{0x6A,0x40},
{0x6D,0x04},
{0x6E,0x00},
{0x6F,0x00},
{0x70,0x80},
{0x71,0x00},
{0x72,0x00},
{0x73,0x00},
{0x74,0xF0},
{0x75,0x00},
{0x80,0x42},
{0x81,0x44},
{0x82,0x04},
{0x83,0x20},
{0x84,0x20},
{0x85,0x00},
{0x86,0x10},
{0x87,0x00},
{0x88,0x05},
{0x89,0x18},
{0x8A,0x10},
{0x8B,0x01},
{0x8C,0x37},
{0x8D,0x00},
{0x8E,0xF0},
{0x8F,0x81},
{0x90,0x06},
{0x91,0x06},
{0x92,0x1E},
{0x93,0x0D},
{0x94,0x0A},
{0x95,0x0A},
{0x96,0x0C},
{0x97,0x05},
{0x98,0x0A},
{0x99,0x41},
{0x9A,0x14},
{0x9B,0x0A},
{0x9C,0x3F},
{0x9D,0x33},
{0x9E,0xAE},
{0x9F,0xF9},
{0xA0,0x48},
{0xA1,0x13},
{0xA2,0x10},
{0xA3,0x08},
{0xA4,0x30},
{0xA5,0x19},
{0xA6,0x10},
{0xA7,0x08},
{0xA8,0x24},
{0xA9,0x04},
{0xAA,0x1E},
{0xAB,0x1E},
{0xCC,0x19},
{0xCD,0x0B},
{0xCE,0x13},
{0xCF,0x64},
{0xD0,0x21},
{0xD1,0x0F},
{0xD2,0x88},
{0xE0,0x01},
{0xE1,0x04},
{0xE2,0x41},
{0xE3,0xD6},
{0xE4,0x00},
{0xE5,0x0C},
{0xE6,0x0A},
{0xE7,0x00},
{0xE8,0x00},
{0xE9,0x00},
{0xEE,0x07},
{0xEF,0x01},
{0x00,0x1E},
{0x01,0x1E},
{0x02,0x0F},
{0x03,0x10},
{0x04,0x02},
{0x05,0x00},
{0x06,0xB0},
{0x07,0x04},
{0x08,0x0D},
{0x09,0x0E},
{0x0A,0x9C},
{0x0B,0x04},
{0x0C,0x05},
{0x0D,0x0F},
{0x0E,0x02},
{0x0F,0x12},
{0x10,0x02},
{0x11,0x02},
{0x12,0x00},
{0x13,0x01},
{0x14,0x05},
{0x15,0x07},
{0x16,0x05},
{0x17,0x07},
{0x18,0x01},
{0x19,0x04},
{0x1A,0x05},
{0x1B,0x0C},
{0x1C,0x2A},
{0x1D,0x01},
{0x1E,0x00},
{0x21,0x00},
{0x22,0x00},
{0x23,0x00},
{0x25,0x01},
{0x26,0x00},
{0x27,0x39},
{0x28,0x7F},
{0x29,0x08},
{0x30,0x03},
{0x31,0x00},
{0x32,0x1A},
{0x33,0x1A},
{0x34,0x07},
{0x35,0x07},
{0x36,0x01},
{0x37,0xFF},
{0x38,0x36},
{0x39,0x07},
{0x3A,0x00},
{0x3E,0xFF},
{0x3F,0x00},
{0x40,0x77},
{0x41,0x40},
{0x42,0x00},
{0x43,0x30},
{0x44,0xA0},
{0x45,0x5C},
{0x46,0x00},
{0x47,0x00},
{0x48,0x58},
{0x4A,0x1E},
{0x4B,0x1E},
{0x4C,0x00},
{0x4D,0x00},
{0x4E,0xA0},
{0x4F,0x80},
{0x50,0x00},
{0x51,0x00},
{0x52,0x00},
{0x53,0x00},
{0x54,0x00},
{0x57,0x80},
{0x59,0x10},
{0x5A,0x08},
{0x5B,0x94},
{0x5C,0xE8},
{0x5D,0x08},
{0x5E,0x3D},
{0x5F,0x99},
{0x60,0x45},
{0x61,0x40},
{0x63,0x2D},
{0x64,0x02},
{0x65,0x96},
{0x66,0x00},
{0x67,0x97},
{0x68,0x01},
{0x69,0xCD},
{0x6A,0x01},
{0x6B,0xB0},
{0x6C,0x04},
{0x6D,0x2C},
{0x6E,0x01},
{0x6F,0x32},
{0x71,0x00},
{0x72,0x01},
{0x73,0x35},
{0x74,0x00},
{0x75,0x33},
{0x76,0x31},
{0x77,0x01},
{0x7C,0x84},
{0x7D,0x03},
{0x7E,0x01}
};
/******************************************************************************
function:
I2C Write and Read
******************************************************************************/
static void DEV_I2C_WriteByte(uint8_t add_, uint8_t data_)
{
uint8_t Buf[1] = {0};
Buf[0] = data_;
HAL_I2C_Mem_Write(&PAJ7620U2_I2C, PAJ7620U2_I2C_ADDRESS, add_, I2C_MEMADD_SIZE_8BIT, Buf, 1, 500);
}
static void DEV_I2C_WriteWord(uint8_t add_, uint16_t data_)
{
uint8_t Buf[2] = {0};
Buf[0] = data_ >> 8;
Buf[1] = data_;
HAL_I2C_Mem_Write(&PAJ7620U2_I2C, PAJ7620U2_I2C_ADDRESS, add_, I2C_MEMADD_SIZE_8BIT, Buf, 2, 500);
}
static uint8_t DEV_I2C_ReadByte(uint8_t add_)
{
uint8_t Buf[1]={add_};
HAL_I2C_Mem_Read(&PAJ7620U2_I2C, PAJ7620U2_I2C_ADDRESS, add_, I2C_MEMADD_SIZE_8BIT, Buf, 1, 500);
return Buf[0];
}
static uint16_t DEV_I2C_ReadWord(uint8_t add_)
{
uint8_t Buf[2]={0, 0};
HAL_I2C_Mem_Read(&PAJ7620U2_I2C, PAJ7620U2_I2C_ADDRESS, add_, I2C_MEMADD_SIZE_8BIT, Buf, 2, 500);
return ((Buf[1] << 8) | (Buf[0] & 0xff));
}
static uint16_t PAJ7620U2_GetPartID(void)
{
uint8_t data[2] = {0, };
data[0] = DEV_I2C_ReadByte(PAJ_PART_ID_L);
data[1] = DEV_I2C_ReadByte(PAJ_PART_ID_H);
return ((uint16_t)data[1]<<8) | data[0];
}
//----------------------------------------------------------------------------------
// при инициализации возвращает ( если соединение с датчиком удачное ) значение 0x7620 либо 0 если датчик не увидел
uint16_t PAJ7620U2_init(void)
{
uint16_t ID = PAJ7620U2_GetPartID();
if( ID == PAJ_PARTID ){
DEV_I2C_WriteByte(PAJ_BANK_SELECT, PAJ_BANK_0);
for (uint8_t i = 0; i < Init_Array; i++ )
{
DEV_I2C_WriteByte(Init_Register_Array[i][0], Init_Register_Array[i][1]);//Power up initialize
}
DEV_I2C_WriteByte(PAJ_BANK_SELECT, PAJ_BANK_0);
return ID;
}
return 0;
}
//----------------------------------------------------------------------------------
// запрашиваем номер движения ( если движения небыло вернет 0 ) если было то его номер
uint16_t PAJ7620U2_Gesture_ReadData(void)
{
return DEV_I2C_ReadWord(PAJ_INT_FLAG1);
}
//----------------------------------------------------------------------------------
// Object Brightness (Max. 255)
uint8_t PAJ7620U2_PS_ReadObjBrightness(void)
{
return DEV_I2C_ReadByte(PAJ_OBJ_BRIGHTNESS);
}
//----------------------------------------------------------------------------------
// Object Size (Max. 900)
uint16_t PAJ7620U2_PS_ReadObjSize(void)
{
return DEV_I2C_ReadWord(PAJ_OBJ_SIZE_L);
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
/************************ (C) COPYRIGHT GKP *****END OF FILE****/3、在main.c中先定义初始化变量:
/* USER CODE BEGIN PTD */ int Gesture_Data = 0; uint8_t OBJ_BRIGHTNESS = 0; // Object Brightness (Max. 255) uint16_t OBJ_SIZE = 0; // Object Size (Max. 900) /* USER CODE END PTD */
4、添加PAJ7620U2的init函数。并在while循环中检测是否有手势,如果有,通过case分别给予打印到串口中。
uint16_t ID = PAJ7620U2_init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
Gesture_Data = PAJ7620U2_Gesture_ReadData();
// если движение было то
if( Gesture_Data != PAJ_NONE )
{
switch (Gesture_Data)
{
case PAJ_UP:
HAL_UART_Transmit(&huart2,"Up -> Data\n",sizeof("Up -> Data\n"),100);
break;
case PAJ_DOWN:
HAL_UART_Transmit(&huart2,"Down -> Data\n",sizeof("Down -> Data\n"),100);
break; // вниз
case PAJ_LEFT:
HAL_UART_Transmit(&huart2,"Left -> Data\n",sizeof("Left -> Data\n"),100);
break; // влево
case PAJ_RIGHT:
HAL_UART_Transmit(&huart2,"Right -> Data\n",sizeof("Right -> Data\n"),100);
break; // вправо
case PAJ_FORWARD:
HAL_UART_Transmit(&huart2,"Forward -> Data\n",sizeof("Forward -> Data\n"),100);
break; // вперед
case PAJ_BACKWARD:
HAL_UART_Transmit(&huart2,"Backward -> Data\n",sizeof("Backward -> Data\n"),100);
break; // назад
case PAJ_CLOCKWISE:
HAL_UART_Transmit(&huart2,"Clockwise -> Data\n",sizeof("Clockwise -> Data\n"),100);
break; // по часовой стрелке
case PAJ_ANTI_CLOCKWISE:
HAL_UART_Transmit(&huart2,"AntiClockwise -> Data\n",sizeof("AntiClockwise -> Data\n"),100);
break; // против часовой стрелки
case PAJ_WAVE:
HAL_UART_Transmit(&huart2,"Wave -> Data\n",sizeof("Wave -> Data\n"),100);
break; // волна
default: break;
}
}
Gesture_Data = 0;
// запрашиваем размер и освященность обьекта перед датчиком
OBJ_BRIGHTNESS = PAJ7620U2_PS_ReadObjBrightness(); // Object Brightness (Max. 255)
OBJ_SIZE = PAJ7620U2_PS_ReadObjSize(); // Object Size (Max. 900)
HAL_Delay(50);
/* USER CODE END WHILE */【实验效果】
上传代码到开发板后,打开串口助手,可以看到可以正确的识别了手势,并打印出来。

我要赚赏金
