【目的】
驱动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 */
【实验效果】
上传代码到开发板后,打开串口助手,可以看到可以正确的识别了手势,并打印出来。