拓冰建站拓冰建站
首页 / 资讯中心 / 正文

用 ESP32 做蓝牙 HID 设备:从烧录到配对成功的完整流程

用 ESP32 做蓝牙 HID 设备从烧录到配对成功的完整流程【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf给桌面加一组自定义物理按键——切歌、调音量、开电源——市售的蓝牙小键盘功能要么固定、要么一百多块钱起步。用 ESP32 加上 ESP-IDF 的蓝牙 HID 能力这些按键完全可以自己定义ESP-IDF 的 esp_hid 组件把设备端做成标准 HID 外设主机手机、电脑把它识别成普通键盘或鼠标无需安装任何驱动。这套技术栈能做出什么蓝牙键盘串口里敲字符电脑键盘光标处打出对应字母支持大小写和符号组合蓝牙鼠标通过按键输入模拟左键、右键和 X/Y 方向移动带滚轮消费控制遥控器音量加减、静音、播放/暂停、快进快退对应系统媒体键经典蓝牙与 BLE 双模同一套 HID 示例在 Bluedroid经典蓝牙和 NimBLEBLE下都能跑HID_DEV_MODE配置项决定走哪条路。对创客和小批量产品来说这套组合的价值在于代码在仓库里就能直接编译硬件只需要一块开发板和一根 USB 线。核心概念速览先懂两个名词做 HID 设备只需要先理解两件事GATT和报告描述符。GATTGeneric Attribute Profile通用属性配置文件是 BLE 上数据往来的通道。主机不直接听设备说话而是读写 GATT 服务里的特征值Characteristic。HID 协议在 GATT 之上定义了一组固定服务主机从其中的 Report Map 特征读到报告描述符再通过 Input Report 特征拿到你发来的按键数据。报告描述符Report Descriptor可以理解为设备的说明书一串二进制字节声明了这个设备有哪些输入项、每项占几个 bit、取值范围是多少。主机不读说明书就不干活——描述符写错主机要么拒绝连接 HID 服务要么按键行为错乱。上图是蓝牙 Host协议栈与 Controller射频控制器的分工。你写的应用代码只和 Host 侧 API 打交道HID 服务注册、配对加密这些都由协议栈处理。仓库里同时有 Bluedroid 和 NimBLE 两套 Host 实现选 NimBLE 更省 RAM大约省 30KB 量级但经典蓝牙 HID 只能走 Bluedroid。跑通最小路径从 clone 到主机认出你的鼠标第一步环境。拿到工具链只需三条命令git clone https://gitcode.com/GitHub_Trending/es/esp-idf cd esp-idf ./install.sh . ./export.shinstall.sh 会把 Xtensa/RISC-V 交叉编译器下载到本地首次运行较慢属正常现象。第二步选示例并定目标芯片。BLE 的 HID 全功能示例键盘/鼠标/媒体三合一通过 menuconfig 切换角色在examples/bluetooth/esp_hid_device/经典蓝牙鼠标在examples/bluetooth/bluedroid/classic_bt/下。进入示例目录后先定芯片idf.py set-target esp32s3芯片按手头的板子选C3/C6/S3/H2 系列都在支持列表里。第三步menuconfig。这是最容易卡住的环节三个选项必须对齐Component config → Bluetooth启用NimBLEBLE 路线或Bluedroid经典蓝牙路线二选一别两个都开若走 NimBLE确认HID Service选项打开对应配置项CONFIG_BT_NIMBLE_HID_SERVICEExample Configuration → HID Device Role在 Media Device / Keyboard / Mouse 里选一个这就是你设备的身份决定了用哪份报告描述符。第四步编译烧录。idf.py -p /dev/ttyUSB0 flash monitor串口里看到HID_DEV_DEMO: START说明广播已启动。到这一步先做一件事调广播参数省电。设备没被连接前的全部时间都花在广播上广播间隔直接决定待机功耗。示例默认间隔偏短把esp_hid_ble_gap_adv_start()里的 min/max 间隔拉长到 12 秒单位 6.25ms即 0x00A00x0100电池设备的待机电流能明显下降。广播帧长这样主机扫描到它才发起连接第五步连接验证。在电脑或手机上扫描蓝牙找到 ESP MouseNimBLE 鼠标模式下的默认名配对时按提示输入示例里的固定 passkey123456。串口出现CONNECT日志即成功媒体模式下设备每 2 秒自动发一次音量加减macOS/iOS 会弹出音量条——这是最快确认通路的方式鼠标模式下串口输入q/w/e/a/s/d分别对应左键、上移、右键、左移、下移、右移键盘模式下串口输入字符电脑光标处打出相同字符。如果设备长期不工作别只在广播阶段省电要整体进睡眠空闲时调用esp_pm_configure()开启自动 light sleep彻底闲置时esp_deep_sleep_start()进深睡唤醒源用 RTC GPIO按键引脚接到支持 RTC 唤醒的 GPIO。深睡电流曲线大致如下从活动态到深睡能压到个位数微安级发数据只有一行核心代码。无论哪种角色把字节按描述符排好交给输入报告接口即可esp_hidd_dev_input_set(hid_dev, 0, report_id, buffer, len);report_id对应描述符里0x85声明的编号比如示例中消费控制用的是 ID 3、键盘用 ID 1。关键机制与调参报告描述符和两种协议模式报告描述符决定主机如何解析你的字节流。示例里的mouseReportMap开头几字节就能读懂结构0x05, 0x01, // Usage Page: 通用桌面 0x09, 0x02, // Usage: 鼠标 0xa1, 0x01, // Collection: 应用后面依次定义 3 个按键1 bit/个和 X/Y/滚轮各 8 bit范围 -127~127。如果你发现发出去的按键在主机上变成了别的键通常是 Usage 编码抄错了或者 Logical Minimum/Maximum 和实际数值范围对不上——用 4 字节{btn, dx, dy, wheel}发数据时四个字段必须恰好铺满描述符声明的 bit 数多一个 bit 主机就会错位解析。HID 还有两种工作模式要分清报告模式Report按你的描述符解析自定义设备只走这条路启动模式Boot协议固化格式永远是标准键盘/鼠标兼容性最好主机在驱动加载前先用它。如果你发现自定义报告主机不理、换成标准键盘布局却能用了说明主机把设备切到了 BOOT 模式串口能看到PROTOCOL_MODE[...]: BOOT日志此时别在描述符里做文章直接按启动模式的固定格式发数据即可。另一个影响体验的参数是发送节奏键盘示例里按下后延时 50ms 再发一次全 0 的抬起报告太短主机可能合并成一次长按太长则手感迟钝。常见坑与快速修复现象iOS 上不弹音量条其他功能正常 →原因iOS 要求经过认证的加密配对才响应媒体键 →处理把CONFIG_BT_NIMBLE_SM_LVL设为 2启用认证配对。现象主机完全搜不到设备 →原因广播未真正启动常见于蓝牙 Host 未初始化完就发广播 →处理等ESP_HIDD_START_EVENT回调后再调广播 API检查BTM_BleWriteAdvData相关告警。现象按键卡住不松、字符重复 →原因只发了按下没发抬起 →处理每次按键后延时 30~50ms 再发一次清零报告示例send_keyboard()已是这个写法照抄即可。下一步打开esp_hid_device_main.c里的mediaReportMap把Usage Page从 0x0C消费控制改成 0x07 并加入 X/Y 轴和扳机键位你就有了一个能接收陀螺仪数据的游戏手柄描述符——把esp_hidd_dev_input_set()的数据源从定时任务换成 I2C 传感器读取整个流程就通了。【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门