SciTech-ICEE-Embeded-Automation-Simulation-HID-自动化交互: USB+OTG+HID模拟鼠标🖱️键盘⌨️指南→参考"Bot.js Pro 文档"
SciTech-ICEE-Embeded-Automation-Simulation-HID
市售完全硬件USB HID(鼠标/键盘/触摸板TouchPad) to TTL(UART)的解决方案:
CH9329
| CH9329 | |
|---|---|
![]() |
![]() |
![]() |
![]() |
参考教程:STM32 USB HID: Emulate a Mouse and Keyboard with STM32
https://controllerstech.com/stm32-usb-hid-mouse-keyboard/
https://controllerstech.com/about/
Home ▸ STM32 Tutorials ▸ USB Tutorials ▸ STM32 as USB Mouse and Keyboard
Updated On: August 5, 2026
STM32 USB HID: Emulate a Mouse and Keyboard with STM32
https://controllerstech.com/stm32-usb-hid-mouse-keyboard/
自动化交互: USB+OTG+HID模拟鼠标🖱️键盘⌨️指南
参考: HID 自动化控制指南
- hid.stm32otg - STM32 OTG
- hid.stm32ble - STM32 蓝牙
- hid - STM32 通用API
- hid.multi - 多模 HID 硬件
- hid.http - 通用服务端
HID 自动化控制指南
【BLE】HID设备的实现(蓝牙自拍杆、蓝牙键盘、蓝牙鼠标、HID复合设备)
基于物理级硬件的 零权限 / 强隔离 / 高一致性 自动化方案
HID(Human Interface Device)自动化是一种完全符合国际标准的完整硬件层IO模拟+软化可编程的方案。先通过 MCU/专用HID硬件在 USB/OTG/蓝牙 硬件协议层模拟标准交互设备(如键盘、鼠标、触控板等),对手机、电脑、平板、智能手表或其他智能终端进行自动化的操作控制。
👉 在硬件、操作系统和应用的视角看,这些行为与真实外设输入完全一致。
核心优势
- 零权限运行,完全符合国际标准。
- HID 模拟基于外置硬件IO实现,不要求任何系统级能力或高权限接口,包括但不限于:
- 无障碍 / 辅助功能
- ADB 调试通道 / 开发人员选项
- Root 或系统修改能力
- 无需授权、不占用系统权限,插入即生效。
- 强系统完整性
HID 方案的操作路径,完全位于系统输入链路最前端:- 输入事件来源为: 外部物理设备
- 行为由 OS操作系统 的 "Input SubSystem(输入子系统)" 统一接收
- 不通过应用层 API、不注入进程、不修改系统状态
- 不产生额外的调用痕迹或运行特征
- 在系统、应用和硬件的角度看👉 这些操作就是真实用户使用键盘、鼠标或触控设备完成的输入行为。
全功能覆盖,适配多种业务形态
支持完整的输入与控制能力,包括:
- 按键与组合键模拟
- 文本输入与粘贴
- 精准触控与多点手势
- 滑动、缩放、长按等交互
- 屏幕截图与视觉联动
- 同时兼容国际标准的 BLE 蓝牙 / OTG / USB 多种连接方式,满足不同部署环境。
高稳定性 & 低时延表现
| 指标 | HID 硬件方案 | 传统软件方案 |
|---|---|---|
| 输入延迟 | 5–50ms | 50–200ms |
| 连续运行稳定性 | ≈99.9% | 依赖系统状态 |
| 系统适配 | Android 7.0+ | 强依赖版本与厂商 |
| 长时间运行 | ✅ | ❌ 易受系统影响 |
HID 工作原理
HID 不是“模拟点击” 而是 作为国际标准的 硬件级IO(输入输出)设备接入系统工作
系统处理流程如下:
[程序化交互的源文件]
↓
[Programmable HMI(可编程人机交互) 自动化系统]
↓
[MCU/HID 硬件]
↓
[USB / OTG / BLE 协议]
↓
[系统输入子系统]
↓
[应用接收标准输入事件]
👉 对应用而言,输入来源不可区分,行为一致。
支持的连接方式
| 连接方式 | 特点 | 适用场景 |
|---|---|---|
| BLE 蓝牙 | 无线、部署灵活 | 移动设备、远程或分布式环境 |
| OTG / USB | 极低延迟、稳定 | 固定工位、高频交互场景 |
硬件支持列表
| 硬件类型 | 支持型号 | 说明 |
|---|---|---|
| MCU开发板 | STM32集成蓝牙+USB系列 | 成本低,支持单一连接模式 |
| 多模二合一 | 蓝牙 + OTG | 支持模式切换与供电控制 |
| 多模三合一 | 蓝牙 + OTG + USB | 全模式覆盖,即插即用 |
【BLE】HID设备的实现(蓝牙自拍杆、蓝牙键盘、蓝牙鼠标、HID复合设备)
https://blog.csdn.net/qq_34254642/article/details/126672201
The Human Interface Device (HID) ,即人机交互设备。
定义了蓝牙在人机接口设备方面的协议、特征和使用规程。
典型的应用包括蓝牙鼠标、蓝牙键盘、蓝牙游戏手柄等。
USB HID Protocol
HID协议改编自USB HID Protocol。
host和device是USB协议的角色概念:
- HOST类似于PC主机,
- device类似于鼠标、键盘这些USB外设ble hid,
蓝牙设备连接手机时,可视为蓝牙设备就是device,手机就是host。
Device通过结构化Report Descriptor(报告描述符)向Host主机声明数据格式与语义。
HID是USB/Bluetooth标准定义键盘、鼠标等输入设备的核心协议框架,
理解HID 协议,涉及 GATT服务组织、Input Report特征值及其通信机制,及修饰键/普通键的8字节报告构造原理。
HID协议有PnP(即插即用)、跨平台兼容、免Driver(驱动)识别(依赖Appearance值0x03c0)等技术优势,广泛应用于嵌入式交互终端、定制外设与IoT控制面板。
Bluetooth HID Protocol
HID Protocol是计算机与键盘、鼠标等外设通信的通用标准,其核心在于通过描述符定义设备功能。
Bluetooth HID Protocol协议则在此基础上实现了无线化,允许嵌入式设备通过蓝牙模拟标准输入设备。
其技术价值在于能以低成本、高灵活性的方式,将任意Physical Input(物理输入)映射为计算机可识别的指令,极大拓展了人机交互的边界。
在物联网和自动化领域,它常用于快速原型开发、创意交互及无障碍设备。
STM32是热门的物联网平台,有丰富的网络资源深入解析其蓝牙HID映射能力,及演示如何将其变为可编程的宏键盘与模拟鼠标。
- Bluetooth HID Protocol 是 Bluetooth Protocol 的一个Profile
- Bluetooth Protocol的每个版本都有HID Profile, 不管版本是2.0、2.1、3.0、4.0、5.0还是6.0。
- HID设备的协议广播包数据,要有HID设备的Service UUID(0x1812) 和 Device Appearance(0x03C1, 设备外观, 协议术语, 例如Keyboard)。
- Bluetooth Service(蓝牙服务)方面,要有Human Interface Device服务和Battery Service服务。
- Connection Management(连接的建立、绑定和管理):
Host连接上Device后,手机需要能够与蓝牙自拍杆进行连接和绑定,
并且在连接完成后,Device的 Bluetooth Broadcast(蓝牙广播)可能消失后,随时激活。
所以要能将绑定Connection及Device,以区分出Connection过的多个Devices的激活。 - Reporting 机制:
Device通过Bluetooth Protocol 的 Reporting,Notify有关的数据到Host, 同步数据。
- HOG(HID OVER GATT Profile)也就是低功耗HID
4.0以上的Bluetooth Protocol还多了一个BLE(Bluetooth Low Energy)的HOG(HID OVER GATT)。
HID规范规定基本的键盘和指示功能使用固定格式的数据包,
在HID Host端不要HID剖析器(约占70kB)。
允许用固定的PSM,和其它设备类,控制FHS数据包作为服务发现协议的定位,以及键盘与指示设备的连接。 - BLE(蓝牙低功耗)版本的HID协议
BLE(Bluetooth Low Energy)实现无线交互的核心协议之一就是HID(人机交互设备)。- BLE(蓝牙低功耗)版本的HID协议:
专为低功耗设备设计。适用于需要长时间待机设备(如无线键盘、遥控器)的场景。
从日常办公到游戏娱乐,其低功耗、高兼容性的特点使其成为智能设备生态不可少缺少的一环。
- BLE(蓝牙低功耗)版本的HID协议:
- HOG(HID OVER GATT)协议
HOG(HID over GATT)是最常用的BLE(蓝牙低功耗)版本的HID协议之一。
HOG定义标准化的数据格式和通信流程,确保Device(设备, 协议术语)与Host(主机, 协议术语, 如手机、电脑)之间的兼容性和低延迟交互。
例如有定义统一的数据格式(如按键码、坐标偏移量),确保不同厂商设备的兼容性。
HOG(HID OVER GATT)通过GATT服务, 将USB HID语义映射到BLE链路。
理解Report Descriptor(蓝牙报告描述符)的语法结构与Usage Table规范,是构建兼容Android/iOS的键盘、鼠标及多媒体控制器的前提;该描述符定义了输入数据的逻辑含义、位域布局与用途分类,直接影响主机解析正确性。
结合STM32-IDF的Bluedroid协议栈,需严格遵循HID Service(0x1812)、Report Map(0x2A4B) 和Protocol Mo
Bluetooth Protocol Debugging
从单一功能设备(如蓝牙自拍杆), 到复杂复合设备(如集成键盘鼠标的遥控器), 开发过程的核心就是要有调试经验。
涉及 Broadcast(广播)配置、hid report map(报告描述符编写与自动化生成)、Host(主机)缓存、复合设备特征值冲突 等关键问题的解决。利用nRF Connect等程序进行抓包和问题定位,可帮助开发者高效解决BLE HID开发。
BLE HID Protocol实例: 蓝牙自拍杆
-
蓝牙自拍杆实现拍照的原理
手机在拍照模式下按音量调节键就可以触发快门按下拍照,蓝牙自拍杆的原理也是通过模拟音量键触发,从而实现远程控制拍照。 -
蓝牙自拍杆的蓝牙服务
对于HID设备,广播包数据要有HID设备的服务UUID(0x1812) 和 设备外观(0x03C1, Keyboard)。
蓝牙服务过程要有Human Interface Device服务和Battery Service服务。
蓝牙自拍杆通过Report特性,Notify有关数据到手机。
同时还注意到,连接上蓝牙自拍杆后,手机需要能够与蓝牙自拍杆进行连接和绑定,
并且在连接后自拍杆的蓝牙广播消失,即功能上只能被一个设备连接。蓝牙协议的调试和验证: 首先用nrf connect看下手上的蓝牙自拍杆的蓝牙协议广播包和服务,如下:
- 广播:
![1000134147]()
- 服务:
![1000134148]()
- 广播:
-
代码
广播和服务这些是定好的蓝牙标准,请查阅。
hid report map部分:
HID设备被连接上后,HOST会通过获取hid report map,来确定这个设备具有哪些功能。
比如每次上报数据,有几个字节,有什么按键,每个按键对应上报数据的哪个字节和实现什么功能等。
重点就是hid report map,有Script/程序可以自动生成对应的"C语言头文件",并且网上肯定有人已经公开过生成好的标准键盘⌨️和鼠标🖱️的hid report map的C语言头文件(也可能是MCU厂商的官方SDK就有提供)。
// 蓝牙自拍杆
static const uint8_t hids_report_descriptor[] =
{
// Report ID 1: Advanced buttons
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report Id (1)
0x15, 0x00, // Logical minimum (0)
0x25, 0x01, // Logical maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x01, // Report Count (1)
0x09, 0x94, // (Quit)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0x95, // (Help)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xEA, // (Volume Down)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xE9, // (Volume Up)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xCB, // (Tracking Decrement)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xCA, // (tracking Increment)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xB6, // (Scan Previous Track)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xB5, // (Scan Next Track)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xB1, // (Pause)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x09, 0xB0, // (Play)
0x81, 0x06, // Input (Data,Value,Relative,Bit Field)
0x75, 0x01, // Report Size (1)
0x95, 0x06, // Report Count (6)
...
}
硬件方案之一是: "STM32H743IIT6+USB3300: USB_HS高速双向HID通讯开发"
另一款HID模拟设备的核心 API 模块说明
$hid—— STM32 通用控制模块
统一封装 STM32 OTG / 蓝牙 HID 能力,自动识别当前连接方式,提供一致的调用接口,适用于大多数场景。$hid.stm32ble—— 蓝牙专用模块
针对 STM32 BLE HID 优化,支持指定设备地址、蓝牙连接管理,适合无线部署环境。$hid.stm32otg—— OTG 专用模块
专注 MCU OTG 有线 HID 输入,具备更低时延与更高输入一致性,适合高频或精细操作。$hid.multi—— 多模硬件模块
适配二合一 / 三合一 HID 设备,支持在连接状态下切换工作模式,适合规模化或长期部署。$hid.http—— HTTP 控制模块
通过本地 HTTP 服务调用 HID 能力,便于跨进程、跨语言或远程系统集成。
HID 设备状态监听
用于监听 HID 设备的状态变化,包括设备插入、拔出、权限请求、权限结果、连接和断开等事件。
支持以下事件类型:
device_attached
OTG HID 设备插入时触发device_detached
OTG HID 设备拔出时触发permission_request
请求 USB 或 OTG 管理权限时触发permission_result
用户确认或拒绝权限请求后触发connected
HID 设备连接时触发disconnected
HID 设备断开连接时触发
基础监听示例
var receiverHID = new JavaAdapter(android.content.BroadcastReceiver, {
onReceive: function (context, intent) {
threads.start(function () {
try {
console.log("监听到消息");
// 单 ACTION 广播
if (intent.getAction() === "hid.action.EVENT") {
// 获取事件类型
var event = intent.getStringExtra("event");
// 获取设备(UsbDevice / UsbAccessory / BluetoothDevice)
var device = intent.getParcelableExtra("device");
console.log(device);
// 根据事件类型处理
switch (event) {
case "device_attached":
console.log("设备插入");
break;
case "device_detached":
console.log("设备拔出");
break;
case "permission_request":
console.log("请求OTG/USB管理权限");
break;
case "permission_result":
var granted = intent.getBooleanExtra("granted", false);
console.log("用户处理权限结果: " + granted);
break;
case "connected":
console.log("设备 HID 已连接");
break;
case "disconnected":
console.log("设备 HID 已断开");
break;
}
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
},
});
var filterHID = new android.content.IntentFilter("hid.action.EVENT");
if (android.os.Build.VERSION.SDK_INT >= 33) {
context.registerReceiver(receiverHID, filterHID, android.content.Context.RECEIVER_EXPORTED);
} else {
context.registerReceiver(receiverHID, filterHID);
}
// 脚本退出时注销广播接收器
events.on("exit", function () {
try {
if (receiverHID) {
context.unregisterReceiver(receiverHID);
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
$hid.stm32otg.init();
$hid.stm32otg.connect();
////////////////
// 在此处编写你的业务逻辑
// 用于测试 HID 广播监听,防止脚本执行完毕后退出,
// 保持脚本常驻运行,确保 HID 事件监听持续有效
setInterval(() => {}, 1000);
自动授权与界面辅助处理
在 HID 设备连接或权限请求过程,系统可能会显示权限确认界面。
通过临时启用无障碍服务,可以自动完成权限确认或其他界面操作,实现 HID 设备的自动授权与异常恢复。
无障碍服务仅在需要时启用,完成操作后可自动关闭,不影响系统正常使用。
适用场景:
- USB / OTG HID 自动授权
- HID 重连恢复
- 系统权限确认自动处理
无障碍服务的启用与关闭方法请参考:
自启动无障碍服务
关闭无障碍服务
/** 启用无障碍服务 **/
function enableAccessibilityService() {
const SERVICE_PATH = ":" + context.getPackageName() + "/com.google.android.accessibility.selecttospeak.SelectToSpeakService";
var Settings = android.provider.Settings;
let enabledServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
// 移除重复服务,防止写入冲突
enabledServices = enabledServices ? enabledServices.replace(new RegExp(SERVICE_PATH, "gi"), "") : "";
// 清空并写入服务,确保生效
Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
Settings.Secure.putString(
context.getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
enabledServices + SERVICE_PATH
);
}
/**
* 检查应用是否拥有指定权限
* @param {string} permission 权限名称
* @returns {boolean} 是否已授权
*/
function checkPermission(permission) {
var pm = context.getPackageManager();
return android.content.pm.PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, context.getPackageName());
}
/**
* HID 设备连接后的自动处理逻辑
*
* 功能说明:
* 1. 检查并启用无障碍服务(支持 WRITE_SECURE_SETTINGS 自动开启)
* 2. 自动处理 USB/HID 权限授权弹窗(点击“确定”)
* 3. 授权完成后自动关闭无障碍服务,避免长期占用
*
* 使用场景:
* - ESP32 HID
* - OTG HID 键鼠
* - USB HID 自动授权
*
*/
function handleHidConnected() {
console.log("HID 设备已连接,开始执行自动授权流程: ");
// =========================
// 第一步:检查无障碍自动开启权限
// =========================
if (checkPermission("android.permission.WRITE_SECURE_SETTINGS")) {
console.log("已获得 WRITE_SECURE_SETTINGS 权限,正在自动启用无障碍服务");
enableAccessibilityService();
} else {
console.warn(
"\n⚠️ 未授予 WRITE_SECURE_SETTINGS 权限,无法自动开启无障碍服务" +
"\n请使用 ADB 授权或手动开启无障碍服务" +
"\n授权命令已复制到剪贴板"
);
// 复制授权命令
var cmd = "adb shell pm grant " + context.getPackageName() + " android.permission.WRITE_SECURE_SETTINGS";
setClip(cmd);
console.info("已复制 ADB 授权命令");
// 打开无障碍设置页面
app.startActivity({
action: "android.settings.ACCESSIBILITY_SETTINGS",
});
console.info("等待用户手动开启无障碍服务...");
// 阻塞等待无障碍开启
auto.waitFor();
}
// =========================
// 第二步:检测无障碍状态
// =========================
if (auto.service == null) {
toastLog("❌ 无障碍服务启动失败,无法执行自动授权");
return;
}
console.log("无障碍服务已启用");
// =========================
// 第三步:等待 USB 权限弹窗出现
// =========================
sleep(2000);
console.log("正在查找 USB 授权确认按钮...");
// =========================
// 第四步:点击“确定”
// =========================
var confirmBtn = selector().text("确定").className("android.widget.Button").visibleToUser(true).clickable(true).findOne(2000);
if (confirmBtn) {
var result = confirmBtn.click();
console.log("USB 授权确认点击结果: " + result);
} else {
toastLog("⚠️ 未找到 USB 授权确认按钮");
return;
}
// =========================
// 第五步:自动关闭无障碍服务
// =========================
sleep(2000);
if (auto.service != null) {
auto.service.disableSelf();
console.log("无障碍服务已关闭(自动授权流程完成)");
}
}
// 监听 HID 广播
var receiverHID = new JavaAdapter(android.content.BroadcastReceiver, {
onReceive: function (context, intent) {
threads.start(function () {
try {
console.log("监听到消息");
// 单 ACTION 广播
if (intent.getAction() === "hid.action.EVENT") {
// 获取事件类型
var event = intent.getStringExtra("event");
// 获取设备(UsbDevice / UsbAccessory / BluetoothDevice)
var device = intent.getParcelableExtra("device");
console.log(device);
// 根据事件类型处理
switch (event) {
case "device_attached":
console.log("设备插入");
break;
case "device_detached":
console.log("设备拔出");
break;
case "permission_request":
console.log("请求OTG/USB管理权限");
break;
case "permission_result":
var granted = intent.getBooleanExtra("granted", false);
console.log("用户处理权限结果: " + granted);
break;
case "connected":
console.log("设备 HID 已连接");
// 对于 OTG 类型的 HID 设备:
// 1. 系统会弹出“是否允许应用访问 USB 设备”提示
// 2. 可通过无障碍服务查找控件并点击“确定”,或点击指定坐标,实现自动授权
// 3. 等待 "permission_result" 广播后,可延迟 2000ms 再关闭无障碍服务
// 4. 也可以在点击“确定”后直接关闭无障碍服务
handleHidConnected(device);
break;
case "disconnected":
console.log("设备 HID 已断开");
break;
}
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
},
});
var filterHID = new android.content.IntentFilter("hid.action.EVENT");
if (android.os.Build.VERSION.SDK_INT >= 33) {
context.registerReceiver(receiverHID, filterHID, android.content.Context.RECEIVER_EXPORTED);
} else {
context.registerReceiver(receiverHID, filterHID);
}
// 脚本退出时注销广播接收器
events.on("exit", function () {
try {
if (receiverHID) {
context.unregisterReceiver(receiverHID);
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
$hid.stm32otg.init();
$hid.stm32otg.connect();
// 在此处编写你的业务逻辑
// 用于测试 HID 广播监听,防止脚本执行完毕后退出,保持脚本常驻运行,确保 HID 事件监听持续有效
setInterval(() => {}, 1000);
总结
核心价值
- 输入层一致性:所有操作等价于真实外设输入
- 系统完整性强:不依赖系统权限或应用接口
- 稳定可控:不受系统更新、权限策略变化影响
- 组合能力强:可与 YOLO / OCR / 找图找色等视觉方案协同工作
选择建议
- 快速上应用 / 通用需求 → $hid
- 无线部署 → $hid.stm32ble
- 低延迟有线 → $hid.stn32otg
- 复杂环境 → $hid.multi
- 跨语言控制 → $hid.http
如需进一步扩展协议或进行深度定制,请参考开发文档。







浙公网安备 33010602011771号