- Feature 1: Remote Battery Monitoring & Low-Battery LED Alert (Closes #5) * Parse BLE Battery Service (0x180F) & Characteristic (0x2A19) with notifications and polling * Double-pulse white LED blink on onboard NeoPixel when battery <= 15% * Display real-time battery percentage in Web UI status bar and BLE tab - Feature 2: Wake-on-LAN (WOL) & Advanced Actions Architecture (Closes #1) * Implement UDP broadcast WOL Magic Packet builder and sender (ACTION_WOL = 11) * Support MAC parsing in colon, dash, or 12-char hex formats, with port configuration * Add 'Advanced Extension' mode in Keymap UI with WOL tester and placeholders for Macro, Webhook, and MQTT * Persist wol_mac in NVS and handle immediate trigger on keypress - Docs: Update README.md and ROADMAP.md reflecting new features and future plans - Build: Update prebuilt firmware binaries in RemoteMapper-Flasher/bin
235 lines
13 KiB
Markdown
235 lines
13 KiB
Markdown
# 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) 协议开源。
|