一、系统设计
项目是基于PAJ7620U2手势识别模块作为主要传感器,以继电器和蜂鸣器作为执行单元。设计的最主要功能是USB HID控制,该款手势识别传感器的检测类型丰富,所以可以组成很丰富的控制,从而达到"魔法棒"的功能。
整个系统的供电由STLINK接口所用的USB提供,采用USB HID协议经过USB HUB与PC通信,实现设备模拟。
二、电路原理图
为了方便板子与传感器以及执行器的连接,我以Demo板的结构经过测量和调整绘制了一块集成板,可以通过简单的连接器实现电气属性的接触而避免繁琐的接线,也保护了易弯折的Demo板的PIN脚。
有需要的可以联系我,由于过于简单,并未在开源广场公开。
三、运行测试
板子上电即可运行,可以看到鼠标和其他指针设备在使用后会多一个设备。该设备即为我们USB HID协议搭建的鼠标模拟设备,可以实现模拟鼠标功能。
功能:
1.可以翻页,模拟滚轮滚动功能,可以实现PPT翻页、网页下滑等滚轮功能
2.可以移动鼠标,但是变动量固定,由于手上可使用的按键只有一个,只能作为翻页和鼠标的切换,所以变速的功能就不具备设计条件了。
3.有靠近警报功能,当物体靠近会触发警报,直到物体离开,用于作为接近开关使用
4.旋转激活继电器功能,可以通过"施咒"手势("旋转")来实现开关功能。
四、关键代码
//手势读取代码 uint16_t DEV_I2C_ReadWord(uint8_t add_) { uint8_t 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)); }
可以对比过程帖,主要是对寄存器组的读取
if (Gesture_Data) { switch (Gesture_Data) { case PAJ_UP: HID_Mouse_Report=PapeToUp; break; case PAJ_DOWN: HID_Mouse_Report=PapeToUd; break; case PAJ_LEFT: HID_Mouse_Report=CursorToLeft; break; case PAJ_RIGHT: HID_Mouse_Report=CursorToRight; break; case PAJ_FORWARD: HID_Mouse_Report=CursorToOk; HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); break; case PAJ_BACKWARD: HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); break; case PAJ_CLOCKWISE: HAL_GPIO_TogglePin(RelayA_GPIO_Port, RelayA_Pin); break; case PAJ_COUNT_CLOCKWISE: HAL_GPIO_TogglePin(RelayB_GPIO_Port, RelayB_Pin); break; case PAJ_WAVE: break; default: break; } }
采用switch多选语法,当识别到对应的手势执行对应的指令。
/* USER CODE BEGIN 1 */ /** * @brief USBX_DEVICE_HID_MOUSE_Task * Run HID mouse task * @param none * @retval none */ VOID USBX_DEVICE_HID_MOUSE_Task(VOID) { ULONG tick; UX_SLAVE_DEVICE *device; UX_SLAVE_CLASS_HID_EVENT hid_event; device = &_ux_system_slave->ux_system_slave_device; ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT)); tick = HAL_GetTick(); /* Check if the device state already configured */ if ((device->ux_slave_device_state == UX_DEVICE_CONFIGURED) && (hid_mouse != UX_NULL)) { /* Sleep for 10ms */ if (ux_utility_time_elapsed(tick, HAL_GetTick()) > BUTTON_DETECT_WAIT) { return; } tick = HAL_GetTick(); /* Check if user button is pressed */ if (HID_Mouse_Report) { /* Get the new position */ GetPointerData(&hid_event); /* Send an event to the hid */ ux_device_class_hid_event_set(hid_mouse, &hid_event); /* Reset User Button state */ HID_Mouse_Report = 0U; } } } /** * @brief GetPointerData * Gets Pointer Data. * @param hid_event: Pointer to structure of the hid event. * @retval None */ static VOID GetPointerData(UX_SLAVE_CLASS_HID_EVENT *hid_event) { static int8_t x = 0, y = 0, Flip = 0; if(User_Button_State)/* Page flipping mode */ { switch(HID_Mouse_Report) { case PapeToUp:Flip = -1;break; case PapeToUd:Flip = 1;break; default:break; } }else/* Cursor mode */ { /* Update pointer position x and y */ switch(HID_Mouse_Report) { case PapeToUp:y = -CURSOR_STEP;break; case PapeToUd:y = CURSOR_STEP;break; case CursorToLeft:x = -CURSOR_STEP;break; case CursorToRight:x = CURSOR_STEP;break; case CursorToOk:break; default:break; } } /* Mouse event. Length is fixed to 3 */ hid_event->ux_device_class_hid_event_length = 3; /* Set X position. */ hid_event->ux_device_class_hid_event_buffer[0] = x; /* Set Y position. */ hid_event->ux_device_class_hid_event_buffer[1] = y; /* Set Roller position. */ hid_event->ux_device_class_hid_event_buffer[2] = Flip; /* Clear position. */ x = y = Flip = 0; }
USB代码框架,基于时序。
五、主要参数与成果演示
主要参数包括:
鼠标偏移步进量 CURSOR_STEP 10
按键识别延时 BUTTON_DETECT_WAIT 10
成果展示见:哔哩哔哩 爱者梦天下 手势翻页笔翻页笔结果展示与分析