这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 作业:USBHIDKeyboard枚举和PAJ7620U2数据的实时读取,实现翻

共4条 1/1 1 跳转至

作业:USBHIDKeyboard枚举和PAJ7620U2数据的实时读取,实现翻页

菜鸟
2024-05-28 10:57:56     打赏

哭死!到底做错了哪一步,帖子为啥只剩一半!555

一、在开发板上实现USB HID模拟键盘的功能。

以前只玩过ESP模块的蓝牙模拟键盘鼠标的实验。第一次在STM32上实现通过USB HID模拟键盘功能。参考着论坛帖子一步一步地完成了复现(感谢anger老师)。

1 使用STM32CubeMX进行系统配置。这里需要留意软件的版本号,先前使用了旧版的STM32CubeMX,在配置USBX时,总是没有对应的选项。

image.png

需要配置USBX,将USB口添加为键盘。修改USB的缓存。

image.png

image.png

image.png

2 使用STM32CubeMX添加ThreadX添加实时操作系统threadx,这样就可以使用多任务的方式操作多个外设了。

image.png

3 编码实现USB键盘。

系统复位后,首先调用main函数,在main函数中初始化ThreadX,调用MX_ThreadX_Init()方法去启动内核。此时会调用UINT MX_USBX_Device_Init(VOID *memory_ptr) 对USB设备初始化,并且创建一个新任务

image.png

static VOID app_ux_device_thread_entry(ULONG thread_input)
{
  /* USER CODE BEGIN app_ux_device_thread_entry */

  /* Initialization of USB device */
  USBX_APP_Device_Init();

  /* USER CODE END app_ux_device_thread_entry */
}

/* USER CODE BEGIN 1 */
/**
 * @brief  Function implementing usbx_hidkeyboard_thread_entry.
 * @param  thread_input: User thread input parameter.
 * @retval none
 */
static VOID usbx_hidkeyboard_thread_entry(ULONG thread_input)
{
  /* USER CODE BEGIN app_ux_device_thread_entry */
  UX_SLAVE_DEVICE *device;
  UX_SLAVE_CLASS_HID_EVENT hid_event;
  TX_PARAMETER_NOT_USED(thread_input);
  device = &_ux_system_slave->ux_system_slave_device;
  ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
  while (1)
  {
    /* Check if the device state already configured */
    if ((device->ux_slave_device_state == UX_DEVICE_CONFIGURED) && (hid_keyboard != UX_NULL))
    {
      /* sleep for 10ms */
      tx_thread_sleep(MS_TO_TICK(100));
      if (gesture_key.valid != 0)
      {
        printf("gesture_key.valid=%d    %d\n", gesture_key.valid, gesture_key.type);
        gesture_key.valid = 0;
        Gesture_GetKeyData(&hid_event);
        //发�?�键盘码
        ux_device_class_hid_event_set(hid_keyboard, &hid_event);
      }
      else
      {
        ClearKeyData(&hid_event);
        ux_device_class_hid_event_set(hid_keyboard, &hid_event);
      }
    }
    else
    {
      /* sleep for 10ms */
      tx_thread_sleep(MS_TO_TICK(10));
    }
  }
  /* USER CODE END app_ux_device_thread_entry */
}

通过这个任务,调用手势传感器获取手势信息,将手势信息映射成键盘码(四个箭头对应的键盘码),并发送给上位机。


二、PAJ7620U2手势传感器的读取

1 PAJ720U2模块介绍:PAJ720U2手势识别传感器是一款强大的3D手势识别交互式传感器;在最远20cm范围内,最多可以识别13种手势。具备良好的手势识别稳定性和节能机制。就像是模块上有个摄像头,通过获得到的图像数据进行分析,得到手势的类型,并且将结果写入寄存器,通过IIC协议读取寄存器内容,即可获得手势信息。这里反复阅读了页面的介绍这里提供了Arduino下读取PAJ7620的代码,可以用来做参考。


 2、PAJ7620U2模块编码:在PAJ7620内部有两个BANK 寄存器区域,分别是BANK0,BANK1。控制着不同的功能。这里唤醒PAJ7620模块后,直接将功能码写入到对应的BANK中去。

unsigned char PAJ7620u2_init(void)
{
	unsigned char status;
	HAL_Delay(10);
	status = paj7620u2_wakeup(); //唤醒PAJ7620U2
	if (!status)
		return 0;
	paj7620u2_selectBank(BANK0); // enter BANK0
	HAL_Delay(50);

	/* Load the registers data */
	for (uint8_t i = 0; i < INIT_REG_ARRAY_SIZE; i++)
		writeReg(initRegisterArray[i][0], initRegisterArray[i][1]); // init PAJ7620U2
	paj7620u2_selectBank(BANK0);									// enter BANK0
	return 1;
}

然后去读取寄存器,即可获得PAJ7620U2模块采集到的动作信息。

unsigned char getResult(void)
{
	char buf[16];
	char tpcVariable[16];
	Gesture_Init();
	gesture.detect = PAJ7620_Read_nByte(PAJ_GET_INT_FLAG1, 2, &gesture.data[0]); //	读取手势状态
	if (gesture.detect)
	{
		gesture.type = (unsigned short)gesture.data[1] << 8 | gesture.data[0];
		if (gesture.type)
		{
			gesture_key.type = gesture.type;
			switch (gesture.type)
			{
			case GES_UP:
				printf("Up\r\n");
				gesture.valid = 1;
				gesture_key.valid = 1;
				break; //
			case GES_DOWN:
				printf("Down\r\n");
				gesture.valid = 1;
				gesture_key.valid = 1;
				break; //
			case GES_LEFT:
				printf("Left\r\n");
				gesture.valid = 1;
				gesture_key.valid = 1;
				break; //
			case GES_RIGHT:
				printf("Right\r\n");
				gesture.valid = 1;
				gesture_key.valid = 1;
				break; //
			case GES_FORWARD:
				printf("Forward\r\n");
				gesture.valid = 1;
				break; //
			case GES_BACKWARD:
				printf("Backward\r\n");
				gesture.valid = 1;
				break; //
			case GES_CLOCKWISE:
				printf("Clockwise\r\n");
				gesture.valid = 1;
				break; //
			case GES_ANTI_CLOCKWISE:
				printf("Counterclockwise\r\n");
				gesture.valid = 1;
				break; //
			case GES_WAVE:
				printf("Wave\r\n");
				gesture.valid = 1;
				break; //
			default:
				gesture.valid = 0;
				break;
			}
		}
	}
	return 0;
}

image.png

三、实现翻页功能

将获得的手势信息映射为键盘码,这里只映射了4个键盘码:上、下、左、右。上传给电脑,就可以实现在PPT展示时前后的翻页功能了。

static void Gesture_GetKeyData(UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
  hid_event->ux_device_class_hid_event_length = 8;
  hid_event->ux_device_class_hid_event_buffer[0] = 0;
  hid_event->ux_device_class_hid_event_buffer[1] = 0;
  if (gesture_key.type)
  {
    switch (gesture_key.type)
    {
    case GES_UP:
      hid_event->ux_device_class_hid_event_buffer[2] = 0x52;
      break; //??
    case GES_DOWN:
      hid_event->ux_device_class_hid_event_buffer[2] = 0x51;
      break; //??
    case GES_LEFT:
      hid_event->ux_device_class_hid_event_buffer[2] = 0x50;
      break; //??
    case GES_RIGHT:
      hid_event->ux_device_class_hid_event_buffer[2] = 0x4F;
      break; //??
    case GES_FORWARD:
      break;
    case GES_BACKWARD:
      break;
    case GES_CLOCKWISE:
      hid_event->ux_device_class_hid_event_buffer[2] = 0x50;
      break; //F5
    case GES_ANTI_CLOCKWISE:
      hid_event->ux_device_class_hid_event_buffer[2] = 0x4F;
      break; //ESC
    case GES_WAVE:
      hid_event->ux_device_class_hid_event_buffer[2] = 0;
      break; //
    default:
      break;
    }
  }
}

视频地址:https://www.bilibili.com/video/BV1eZ421H7oM/

gesture_page.zip


高工
2024-05-28 11:08:53     打赏
2楼

学习了


工程师
2024-05-31 14:58:08     打赏
3楼

666


专家
2024-06-04 08:53:53     打赏
4楼

谢谢分享!学习!


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]