首先要感谢EEPW给这次学习的机会。
本次学习PAJ7620U2手势识别,并通过手势控制继电器开关灯。
识别手势:上、下、左、右、靠近、远离、顺时针旋转、逆时针旋转、挥动。
控制灯:上开左右灯、下关左右灯、左开左灯、右开右灯、靠近左灯闪烁、远离右灯闪烁、挥动左右灯闪烁。
课程1中已经搭建串口等环境,本次只需要在课程1基础上增加I2C通讯和继电器控制IO口即可。
课程1:https://forum.eepw.com.cn/thread/382646/1
一、准备工作
1、NUCLEO-H503RB开发板套件:这里就不做过多介绍;
2、PAJ7620U2手势识别小板;
3、继电器小板;
4、灯:临时手焊搭建LED灯。
二、硬件配置
1、I2C接口:使用PB6/PB7。
PAJ7620U2手势识别小板为I2C通讯,供电为3.3V,接至CN10。由于开发板CN10没有3.3V电源,所以采样飞线将第一脚接至3.3V,方便杜邦线接线。
2、继电器:使用PC10/PC11。
继电器使用IO控制,供电为5V,接至CN6。
3、灯:调试采用LED指示灯,共阳极,控制阴极亮灭。
总体接线图如下:
三、软件配置
代码在课程1的基础上增加I2C(PB6/PB7)和控制继电器IO(PC10/PC11)。
1、I2C配置
a.点击课程1工程,打开。
b.使能I2C1,并重新配置IO口PB6/PB7为I2C1。
c.设置I2C1的IO口为上拉/输出高速。
d.导出代码,并打开工程。(若工程已经打开,可直接关闭,Keil5会自动更新代码)
e.若不行用户代码被替换,需要将新增代码写在用户区。
四、代码编写
PAJ7620U2代码比较简单,但是有点值得注意的是,PAJ7620U2必须要先初始化才能正常使用。很多博主在编写代码时,都自动跳过这节介绍。这里重点说一下。
也可参考:https://blog.csdn.net/qq_57178105/article/details/136558564
1、PAJ7620初始化定义
#include "stdio.h" //PAJ7620地址寄存器定义 #define PAJ7620_I2C_ADDRESS 0x73<<1 //paj7620的i2c地址,7bit #define PAJ_BANK_SELECT 0xEF //寄存器页选择寄存器:Bank0=0x00, Bank1=0x01 #define PAJ_INT_FLAG1 0x43 //检测结果数据低八位数据所在地址 #define PAJ_INT_FLAG2 0x44 //检测结果数据高八位数据所在地址 //手势状态 #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 //挥动 //继电器控制灯IO定义 #define LED0_ON HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_SET); #define LED0_OFF HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_RESET); #define LED0_TOG HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_10); #define LED1_ON HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_SET); #define LED1_OFF HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_RESET); #define LED1_TOG HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_11);
2、PAJ7620U2初始化写入寄存器数组,219组。
//PAJ7620初始化寄存器数组:219个 uint8_t Paj7620Init_Reg_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}, }; //继电器控制灯状态 uint8_t LED_Status = 0; uint8_t paj7620_init(void); //PAJ7620U2初始化函数 void getGesture(void); //PAJ7620U2获取手势识别函数 void user_function_gesture(uint8_t status); //手势控制继电器开关灯函数 /* 串口重定义 */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; }
3、编写PAJ7620U2初始化函数
//PAJ7620U2初始化,返回0则初始化失败 uint8_t paj7620_init(void) { uint8_t i,State,n; State = 0; while(HAL_OK != HAL_I2C_Mem_Write(&hi2c1, PAJ7620_I2C_ADDRESS, PAJ_BANK_SELECT, I2C_MEMADD_SIZE_8BIT, &State, 1, 500)) { HAL_Delay(5); printf("paj7620_init err: 1 \r\n"); } for(i=0; i<219; i++) { while(HAL_OK != HAL_I2C_Mem_Write(&hi2c1, PAJ7620_I2C_ADDRESS, Paj7620Init_Reg_Array[i][0], I2C_MEMADD_SIZE_8BIT, &Paj7620Init_Reg_Array[i][1], 1, 500)) { HAL_Delay(5); printf("paj7620_init err: 2 \r\n"); } HAL_Delay(5); } while(HAL_OK != HAL_I2C_Mem_Write(&hi2c1, PAJ7620_I2C_ADDRESS, PAJ_BANK_SELECT, I2C_MEMADD_SIZE_8BIT,&State,1,500)) { HAL_Delay(5); printf("paj7620_init err: 3 \r\n"); } HAL_Delay(5); while(HAL_OK != HAL_I2C_Mem_Read(&hi2c1, PAJ7620_I2C_ADDRESS, 0x32, I2C_MEMADD_SIZE_8BIT, &n, 1, 500)) { HAL_Delay(5); printf("paj7620_init err: 4 \r\n"); } if(n != 0x29) { return 0; } return 1; }
4、编写手势识别函数
//检测手势并输出 void getGesture(void) { uint8_t Data[2]={0,0}; uint16_t Gesture_Data; HAL_I2C_Mem_Read(&hi2c1, PAJ7620_I2C_ADDRESS, PAJ_INT_FLAG1, I2C_MEMADD_SIZE_8BIT, &Data[0], 1, 500); HAL_Delay(5); HAL_I2C_Mem_Read(&hi2c1, PAJ7620_I2C_ADDRESS, PAJ_INT_FLAG2, I2C_MEMADD_SIZE_8BIT, &Data[1], 1, 500); HAL_Delay(5); Gesture_Data = (Data[1]<<8) | Data[0]; //printf("\n %x \r\n", Gesture_Data); if(Gesture_Data != 0) { //printf("\n %x \r\n", Gesture_Data); switch(Gesture_Data) { case PAJ_UP: printf("Up\r\n"); LED_Status=1; break; case PAJ_DOWN: printf("Down\r\n"); LED_Status=2; break; case PAJ_LEFT: printf("Left\r\n"); LED_Status=3; break; case PAJ_RIGHT: printf("Right\r\n"); LED_Status=4; break; case PAJ_FORWARD: printf("Forward\r\n"); LED_Status=5; break; case PAJ_BACKWARD: printf("Backward\r\n"); LED_Status=6; break; case PAJ_CLOCKWISE: printf("Clockwise\r\n"); LED_Status=7; break; case PAJ_COUNT_CLOCKWISE: printf("AntiClockwise\r\n"); LED_Status=8; break; case PAJ_WAVE: printf("Wave\r\n"); LED_Status=9; break; default: break; } Gesture_Data = 0; } }
5、编写控制继电器开关灯函数
//手势控制继电器开关灯 void user_function_gesture(uint8_t status) { switch(status) { case 1: //PAJ_UP LED0_ON; LED1_ON; //printf("LED_Status: 1 \r\n"); break; case 2: //PAJ_DOWN LED0_OFF; LED1_OFF; //printf("LED_Status: 2 \r\n"); break; case 3: //PAJ_LEFT LED0_ON; LED1_OFF; //printf("LED_Status: 3 \r\n"); break; case 4: //PAJ_RIGHT LED0_OFF; LED1_ON; //printf("LED_Status: 4 \r\n"); break; case 5: //PAJ_FORWARD LED0_TOG; //printf("LED_Status: 5 \r\n"); break; case 6: //PAJ_BACKWARD LED1_TOG; //printf("LED_Status: 6 \r\n"); break; case 7: //PAJ_CLOCKWISE //printf("LED_Status: 7 \r\n"); break; case 8: //PAJ_COUNT_CLOCKWISE //printf("LED_Status: 8 \r\n"); break; case 9: //PAJ_WAVE LED0_TOG; LED1_TOG; //printf("LED_Status: 9 \r\n"); break; default: break; } }
6、main函数实现
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_USART3_UART_Init(); MX_I2C1_Init(); /* USER CODE BEGIN 2 */ printf("hello eepw! hello stm32h503! \r\n"); HAL_Delay(1000); printf("PAJ7620U2 Gesture Sensor Test Program ...\r\n"); if(!paj7620_init()) { printf("Gesture Sensor Error \r\n"); return 0; } printf("PAJ7620U2 Gesture Sensor OK \r\n"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ getGesture(); user_function_gesture(LED_Status); HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); HAL_Delay(500); } /* USER CODE END 3 */ }
五、结果输出
完结!共进!