# RemoteMapper-ESP32 Windows下小米蓝牙遥控器最佳适配方案 基于 ESP32-S3 的小米蓝牙遥控器 2 Pro (RC003) 转 USB 复合设备硬件桥接方案。 将遥控器信号直接转换为标准免驱的 USB 输入设备(UAC 1.0 麦克风 + HID 键盘 + 媒体控制),解决 Windows 系统下特定按键被丢弃和音频输入依赖虚拟声卡的问题。 注:当前固件仅支持**小米蓝牙遥控器 2 Pro(型号:RC003)**,暂不支持其他型号。支持 ESP32-S3 N16R8、N8R2、N4R2 等主流硬件版本。 --- ## 背景与解决的问题 在 Windows 系统下直接使用小米蓝牙遥控器 2 Pro 时,存在两处系统级限制: 1. **部分物理按键被系统丢弃**: 遥控器的「音量+ (0x80)」、「音量- (0x81)」、「返回 (0xF1)」采用非标准 HID 键码。Windows 自带的蓝牙键盘驱动(`kbdhid.sys`)会在内核层将其直接过滤丢弃,应用层(包括全局 Hook、RawInput、AutoHotkey 等)无法截获这三个按键。若通过编写 Windows 内核过滤驱动来捕获,必须开启系统测试签名模式,存在系统崩溃风险且易被游戏反作弊程序拦截。 2. **语音功能依赖虚拟声卡**: 遥控器传输的是私有 ATVV 协议编码音频。在纯软件方案中,解码后的音频需要借助第三方虚拟声卡(如 VB-Cable)进行二次路由,输入法才能采集,配置繁琐且存在额外延迟。 本项目采用 ESP32-S3 作为硬件中间人: * 上游直连遥控器蓝牙,在空口完整接收所有 13 个按键的原始报文并解码音频; * 下游通过芯片原生 USB 向电脑模拟标准的免驱硬件(UAC 1.0 麦克风与标准 HID 键盘/多媒体设备); * 电脑端即插即用,无需安装任何驱动或后台软件,不修改系统内核,不影响游戏反作弊。 --- ## 系统拓扑 ```text ┌────────────────────────┐ BLE 5.0 (HOGP + ATVV) ┌────────────────────────┐ │ │ ──────────────────────────────► │ │ │ 小米蓝牙遥控器 2 Pro │ │ ESP32-S3 │ │ (RC003) │ ◄────────────────────────────── │ (Central 主机) │ └────────────────────────┘ └───────────┬────────────┘ │ │ USB 2.0 Full-Speed │ (原生 USB OTG 复合设备) ▼ ┌────────────────────────┐ │ PC 宿主机 │ │ │ │ • 标准 UAC 1.0 麦克风 │ │ • 标准 USB HID 键盘 │ │ • 标准 Consumer 媒体键 │ └────────────────────────┘ ``` --- ## 核心特性 1. **免驱 USB 物理麦克风(UAC 1.0)** * 基于 TinyUSB 协议栈,模拟 16kHz 16-Bit 单声道标准输入设备。 * 实时解码遥控器 IMA-ADPCM 音频流。 * 包含音频前处理:按下瞬间立即注入输入法快捷键,并在音频前段插入 150ms 静音区(抑制按键微动物理杂音并留出输入法唤起窗口),消隐期结束施加 10ms 微平滑淡入(消除电平跳变爆音),结合 AGC 软启动避免拾取环境底噪。 2. **5 层独立映射系统** * 提供 5 个独立按键配置层(默认层、层1 ~ 层4)。 * 每个按键均支持单击、长按(200~2000ms 可调)、双击(100~600ms 可调)。 * 支持三种层级生命周期: * 永久停留层:手动切入后持续生效,直至再次切换。 * 一次性层:触发任意按键后自动返回默认层。 * 超时返回层:闲置达到设定秒数(3~300 秒)后自动返回默认层。 * 穿透继承:非默认层未单独配置的按键自动沿用默认层的设置。 * 自动防呆反转:若当前已在目标层,再次触发切入该层的按键时,会自动返回默认层。 * 支持为不同层级指定不同的板载 RGB 指示灯颜色。 3. **标准媒体与系统按键支持** * 支持映射为音量调节、静音、播放/暂停、曲目切换、系统休眠等标准 USB Consumer 键码,系统级原生响应。 4. **内置 Web 管理后台** * 固件集成 Web 服务器,通过浏览器即可完成可视化按键映射配置、蓝牙配对、网络设置与日志查看。 * 支持 AP 热点配置(支持设置 WPA2 密码)与 STA 局域网接入。 * 配置数据持久化保存在 ESP32 的 NVS 分区中,掉电不丢失。 5. **局域网网络唤醒 (Wake-on-LAN / WOL)** * 支持将任意按键(单击、长按或双击)配置为向局域网广播 WOL 魔术包(Magic Packet)。 * 无论电脑处于关机(S5)还是睡眠(S3/S4)状态,只要网卡支持 WOL,按下按键即可远程无线开机。 * Web 控制台内置“发送测试唤醒包”调试按钮,支持标准 MAC 地址格式,配置直观。 6. **遥控器电量实时监控与低电量硬件提醒** * 自动发现并监听 BLE 标准电池服务(Battery Service `0x180F` / `0x2A19`)。 * WebUI 顶部状态栏与蓝牙详情面板实时显示电池电量百分比(`🔋 xx%`)。 * **硬件级防断电警示**:当遥控器电量低于等于 15% 时,ESP32 板载 RGB LED 会在就绪状态下以 2 秒为周期双闪白光,直观提醒更换 7 号电池。 7. **面向未来的高级扩展架构** * 按键动作模式新增【高级扩展】面板,除已上线的 WOL 唤醒外,界面已预留按键宏序列(Macro)、HTTP Webhook 网络请求以及 MQTT 物联网消息推送扩展占位,满足极客与智能家居联动需求。 --- ## 默认出厂按键映射 | 按键 | 物理键码 | 单击行为 | 长按行为 | 双击行为 | | :--- | :--- | :--- | :--- | :--- | | **电源键** | `0x66` | `Alt + F4` (关闭窗口) | 系统休眠 (`0x0032`) | — | | **语音键** | `0x04` | 麦克风音频推流 + `Alt + ,` | 按住持续录音 | — | | **方向上** | `0x52` | 方向键上 (`↑`) | — | — | | **方向下** | `0x51` | 方向键下 (`↓`) | — | — | | **方向左** | `0x50` | 方向键左 (`←`) | — | — | | **方向右** | `0x4F` | 方向键右 (`→`) | — | — | | **确定键** | `0x28` | 回车 (`Enter`) | — | — | | **返回键** | `0xF1` | 多媒体返回 (`0x0224`) | — | — | | **主页键** | `0x24` | 显示桌面 (`Win + D`) | — | — | | **菜单键** | `0x5D` | 空格 (`Space`) | — | — | | **音量+** | `0x80` | 音量增加 (`0x00E9`) | — | — | | **音量-** | `0x81` | 音量减少 (`0x00EA`) | — | — | | **电视键** | `0xC0` | `F8` | — | — | *注:以上按键均可在 Web 后台自由修改、重新分配或清除。* --- ## 硬件连接 1. **开发板要求**: 任意 ESP32-S3 开发板,推荐配置: * **N16R8**(16MB Flash, 8MB PSRAM):默认构建目标。 * **N8R2**(8MB Flash, 2MB PSRAM):主流常见规格。 * **N4R2**(4MB Flash, 2MB PSRAM):极简规格,编译产物约 1.2MB。 2. **遥控器**: 小米蓝牙语音遥控器 2 Pro(型号:RC003)。 3. **接口接线**: ESP32-S3 通常带有两个 Type-C 接口: * **`USB`(或 `OTG`)口**:必须连接到电脑。该接口直通 ESP32-S3 原生 USB 控制器,用于模拟 UAC 麦克风与 HID 设备。 * **`UART` 口**:仅用于烧录与查看串口日志,日常使用无需连接。 --- ## 固件刷写(新手推荐,免开发环境) 无需安装 Python、PlatformIO、Git 或任何开发编译环境,开箱即用: 1. **获取刷机包**: - **方式 A**:直接在 GitHub 点击 Code -> Download ZIP 下载本项目压缩包并解压,使用里面的 `RemoteMapper-Flasher` 文件夹; - **方式 B**:前往本仓库的 [Releases](https://github.com/cuicui-V5/RemoteMapper-ESP32/releases) 页面,直接下载已单独打包好的刷机包压缩包。 2. **连接硬件**: 使用具备数据传输功能的 Type-C 数据线,连接电脑与 ESP32-S3 开发板的 **USB / OTG** 接口(双口板请勿插在 UART 口)。 3. **进入刷机模式**: 按住开发板上的 **`BOOT`** 键不放,点按一下 **`RST`** 重启键,然后松开 **`BOOT`** 键。 4. **一键写入**: 进入 `RemoteMapper-Flasher` 目录,双击运行 **`一键烧录.bat`**(或 `flash.bat`),跟随全中文向导提示选择开发板型号(N16R8 / N8R2 / N4R2)与串口号,即可全自动完成烧录。 --- ## 固件编译与开发者烧写 若需要自行二次开发或修改源码,请确保本地已安装 Python 与 PlatformIO 环境: ### 1. 编译固件 (`build.bat`) 运行根目录下的 `build.bat` 脚本: ```cmd build.bat :: 一键编译全部 3 个版本(N16R8 / N8R2 / N4R2),并自动将生成镜像打包复制到 RemoteMapper-Flasher\bin 目录 build.bat n16r8 :: 仅编译 N16R8 版本 build.bat n8r2 :: 仅编译 N8R2 版本 build.bat n4r2 :: 仅编译 N4R2 版本 ``` ### 2. 正常烧录 (`flash.bat`) 编译完成后,通过根目录下的 `flash.bat` 脚本直接烧录至开发板: ```cmd flash.bat n16r8 :: 烧录至 N16R8 开发板(默认) flash.bat n8r2 :: 烧录至 N8R2 开发板 flash.bat n4r2 :: 烧录至 N4R2 开发板 ``` *(注:若本地未安装 PlatformIO 环境,运行根目录 `flash.bat` 会自动检测并引导启动 `RemoteMapper-Flasher` 免环境刷写工具)* 也可以直接使用 PlatformIO 原生命令: ```bash pio run -e esp32s3_n16r8 -t upload pio run -e esp32s3_n8r2 -t upload pio run -e esp32s3_n4r2 -t upload ``` --- ## 使用指南 ### 1. 配网 固件首次启动后会开启配置热点: * 热点名称:`RemoteMapper-AP`(无密码) * 浏览器访问:`http://192.168.4.1/` * 进入「Wi-Fi 与系统配置」页面,扫描并连接局域网 Wi-Fi。连接成功后,可在局域网内直接通过分配的 IP 地址访问后台。 ### 2. 配对遥控器 1. 打开 Web 后台的「蓝牙配对管理」标签页。 2. 拿起遥控器,**同时按住「主页键」与「菜单键」3 秒**,待指示灯快闪进入广播配对状态。 3. 在网页上点击「扫描蓝牙设备」,找到对应设备并点击连接。 4. 绑定成功后,设备信息会持久化保存,后续开机或遥控器休眠唤醒均会自动重连。 ### 3. 按键与层级设置 1. 进入「按键映射和层级设置」页面。 2. 点击上方层级选项卡切换配置层(默认层、层1 ~ 层4)。 3. 点击遥控器模型上的按键进入编辑弹窗,可独立设置单击、长按、双击触发的行为(键盘按键、多媒体控制、层级切换或高级扩展如 WOL 局域网唤醒)。 4. 保存配置后即刻生效并写入 Flash。 ### 4. 输入法语音配置 固件出厂默认在按住语音键时注入 `Alt + ,` 快捷键(微信输入法默认语音热键)。 1. 打开电脑输入法设置,将麦克风输入源选择为系统新增的硬件设备:`RemoteMapper Mic`。 2. 确认输入法的语音输入快捷键与遥控器语音键配置的快捷键一致。 3. 按住遥控器语音键说话,松开按键即完成输入。 --- ## 进阶:与 PC 伴侣程序联动 若需要让按键触发打开特定软件、运行脚本或系统命令,可以使用项目附带的 `pc_companion` 辅助程序: 1. 将遥控器指定手势映射为 `F13` ~ `F24` 等空闲功能键。 2. 在 `pc_companion/config.json` 中为对应键位定义执行命令: ```json { "F13": { "name": "打开浏览器", "command": "start https://www.google.com", "enabled": true } } ``` 3. 运行 `pc_companion/silent_start.vbs` 即可在后台静默监听触发。 --- ## 致谢 * [QL-4/RemoteMapper](https://github.com/QL-4/RemoteMapper):提供了 Windows C# 软件方案与 ATVV 协议参考。 * [godarrenw/mi_remote_control](https://github.com/godarrenw/mi_remote_control):提供了遥控器蓝牙协议分析与逆向参考。 --- ## 开源协议 本项目采用 [MIT License](./LICENSE) 协议开源。