一、系统设计
项目是基于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
成果展示见:哔哩哔哩 爱者梦天下 手势翻页笔翻页笔结果展示与分析
我要赚赏金
