[ESP8266/ESP32]DFRobot ESP32C3 USB HID Shield 精华

1900浏览
查看: 1900|回复: 3

[ESP8266/ESP32] DFRobot ESP32C3 USB HID Shield

[复制链接]
这次带来的作品是 DFRobot Beetle ESP32-C3的扩展版,通过这个扩展版能够让 Beetle ESP32-C3 取得 USB 键盘鼠标这种 HID 设备的输入数据。
这个扩展版的核心是 WCH 出品的CH9350芯片,CH9350USB键盘鼠标转串口通讯控制芯片。就是说USB键盘鼠标连接到这个芯片之后,数据会转化为串口输出。关于这个芯片的功能介绍如下:

  • 支持12Mbps全速USB传输和1.5Mbps低速USB传输,兼容USB     V2.0
  • 上位机端USB端口符合标准HID类协议,不需要额外安装驱动程序,支持内置HID类设备驱动的WindowsLinuxmacOS等操作系统。
  • 同一芯片可配置为上位机模式和下位机模式,分别连接USB-Host主机和USB键盘、鼠标。
  • 支持USB键盘鼠标在BIOS界面使用,支持多媒体功能键,支持不同分辨率USB鼠标。
  • 支持各种品牌的USB键盘鼠标、USB无线键盘鼠标、USBPS2线等。
  • 上位机端和下位机端支持热插拔。
  • 提供发送状态引脚,支持485通讯。
  • 串口支持115200/57600/38400串口通信波特率。
  • 内置晶振和上电复位电路,外围电路简单。
  • 支持5V3.3V电源电压。
  • 提供LQFP-48无铅封装,兼容RoHS
电路图设计如下:

DFRobot ESP32C3 USB HID Shield图1

DataSheet可以知道,芯片支持 3.3V h5V供电,为了方便电路设计这里我们直接使用5V供电。PCB 设计如下:

DFRobot ESP32C3 USB HID Shield图2

3D渲染结果如下:
DFRobot ESP32C3 USB HID Shield图3

为了Beetle配合板子只使用了一个 USB 母头,实际芯片同时支持2USB接口,让客户可以同时使用键盘和鼠标。
下面带来一个USB键盘转蓝牙例子,展示这个板子的能力。
从原理上来说,首先使用 CH9350取得鼠标数据,之后通过 Beetle ESP32-C3 的蓝牙功能将这个数据发送出去。

  1. #include <Arduino.h>
  2. #include <BleKeyboard.h>
  3. BleKeyboard bleKeyboard;
  4. #define DEBUGMODE 1
  5. void setup() {
  6.   Serial.begin(115200);
  7.   Serial1.begin(115200, SERIAL_8N1, RX, TX);
  8.   bleKeyboard.begin();
  9. }
  10. void loop() {
  11.   while (Serial.available()) {
  12.     char c = Serial.read();
  13.     if (c == '1') {
  14.       Serial.println("get1");
  15.     }
  16.     if (c == '3') {
  17.       ESP.restart();
  18.     }
  19.   }
  20.   //根据 CH9350 Spec 每次最多输出 72Bytes
  21.   byte Data[72];
  22.   unsigned int CounterLast = Serial1.available();
  23.   unsigned int CounterCurrent = 0;
  24.   // 如果当前串口有数据
  25.   if (CounterLast != 0) {
  26.     // 进行简单测试,如果当前还在传输数据那么持续接收
  27.     while (CounterCurrent != CounterLast) {
  28.       CounterLast = Serial1.available();
  29.       delayMicroseconds(500);
  30.       CounterCurrent = Serial1.available();
  31.     }
  32.   }
  33.   if (CounterCurrent > 0) {
  34.     // 一次性将数据收取下来
  35.     Serial1.readBytes(Data, CounterCurrent);
  36.     unsigned int i = 0;
  37.     unsigned int Length;
  38.     while (i < CounterCurrent) {
  39.       // 识别帧头
  40.       if ((Data[i] == 0x57) && (Data[i + 1] == 0xAB)) {
  41.         // 有效键值帧
  42.         if (Data[i + 2] == 0x88) {
  43.           // 获得数据长度
  44.           Length = Data[i + 3];
  45.           if (DEBUGMODE) {
  46.             //Serial.print("Ln:");Serial.print(Length);
  47.             for (int j = 1; j < Length + 1; j++) {
  48.               if (Data[i + 3  + j] < 16) {
  49.                 Serial.print("0");
  50.               }
  51.               Serial.print(Data[i + 3  + j], HEX);
  52.               Serial.print(" ");
  53.             }
  54.             Serial.println(" ");
  55.           }
  56.           //如果是键盘
  57.           if (Data[i + 4] == 0x10) {
  58.             if (DEBUGMODE) {
  59.               Serial.print("Key");
  60.               for (int j = 1; j < Length + 1; j++) {
  61.                 Serial.print(Data[i + 3  + j], HEX);
  62.                 Serial.print(" ");
  63.               }
  64.               Serial.println(" ");
  65.             }
  66.             
  67.             //判断为Dostyle键盘
  68.             if (Data[i + 3  + 1] == 0x10) {
  69.               if (bleKeyboard.isConnected() == true) {
  70.                 bleKeyboard.sendReport((KeyReport*)(&Data[i + 3  + 2]));
  71.               }
  72.             }
  73.           }
  74.           i = i + 3 + Length;
  75.         } else if (Data[i + 2] == 0x82) {
  76.           i = i + 3; // 跳过
  77.         }
  78.       }
  79.       i++;
  80.     } // while (i < Counter)
  81.   }
  82. }
复制代码

首先,调用了 ESP32 BLE 键盘库(第三方),创建一个蓝牙键盘;之后就是分析串口数据。CH9350能够获得USB 键盘鼠标数据,但是获得这个数据每家会有差别。正确的做法是使用工具(USBlyzer)读取键盘鼠标数据,然后编写分析代码。或者是使用工具读取这个设备的 HID Report Descriptor。再进一步解释就是,例如:市面上有2中鼠标,他们发送出来的数据格式可能是:
A鼠标:
Byte0:  Button
Byte1: X
Byte2: Y
Byte3: Wheel
B鼠标:
Byte0:  Button
Byte1: X 8
Byte2: X 8
Byte3: X 8
Byte4: X 8
Byte5: Wheel
具体的格式数据是设备通过HIDReport Descriptor报告给系统的,而对于我们来说只能通过人工识别然后在代码中分析的方式来实现解析。相比USB鼠标,键盘的情况要好得多,通常都是使用8Bytes 来报告按键信息。我这次测试使用的是一款机械键盘,使用的同样是 8 Bytes的格式,因此代码中直接将对应的数据以KeyReport结构体直接发送出去。
  1. if (bleKeyboard.isConnected() == true) {
  2.                 bleKeyboard.sendReport((KeyReport*)(&Data[i + 3  + 2]));
  3. }
复制代码

工作的视频:

[media=x,500,375]【DFRobot Beetle ESP32-C3 USB键盘转蓝牙】 https://www.bilibili.com/video/B ... 819bfc37d4672cb6d54[/media]


















zoologist  高级技匠
 楼主|

发表于 2023-8-14 09:04:31

回复

使用道具 举报

花生编程  中级技匠

发表于 2023-8-22 14:06:04

不错不错
回复

使用道具 举报

花生编程  中级技匠

发表于 2023-8-22 14:08:57

赞赞赞赞赞
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail