如何用Arduino Nano 33读取BLE遥控器按键?求示例代码
解决Arduino Nano 33读取BLE遥控器按键的问题
BLE遥控器大多遵循HID over GATT规范,按键事件不会通过广播数据传输,而是通过HID服务的输入报告特征以**通知(Notification)**的形式主动推送。你之前扫描广播数据看不到变化是正常的,核心是要连接设备并订阅对应特征的通知。
核心步骤
- 识别遥控器的HID服务与输入报告特征:
- HID服务UUID:
00001812-0000-1000-8000-00805f9b34fb - 输入报告特征UUID:
00002a4d-0000-1000-8000-00805f9b34fb
- HID服务UUID:
- 连接遥控器设备后,发现服务与特征
- 订阅输入报告特征的通知,接收按键推送数据
- 解析HID报告数据,匹配按键动作
示例代码
#include <ArduinoBLE.h> // HID服务和输入报告特征的UUID const BLEUUID hidServiceUUID("1812"); const BLEUUID inputReportUUID("2a4d"); BLEDevice remoteDevice; BLECharacteristic inputReportCharacteristic; // 通知回调函数,处理收到的按键数据 void inputReportCallback(BLEDevice central, BLECharacteristic characteristic) { // 获取报告数据 byte reportData[characteristic.valueLength()]; characteristic.readValue(reportData, characteristic.valueLength()); // 打印原始数据,方便调试对比按键状态 Serial.print("收到HID报告:"); for (int i = 0; i < characteristic.valueLength(); i++) { Serial.print(reportData[i], HEX); Serial.print(" "); } Serial.println(); // 这里需要根据你的遥控器报告格式修改,比如判断音量+对应的位变化 // 示例:假设第1字节的第0位对应音量+ if (reportData[0] & 0x01) { Serial.println("音量+键被按下"); } } void setup() { Serial.begin(9600); while (!Serial); // 初始化BLE Central模式 if (!BLE.begin()) { Serial.println("BLE初始化失败"); while (1); } Serial.println("开始扫描BLE设备..."); BLE.scan(); } void loop() { // 扫描到设备 BLEDevice peripheral = BLE.available(); if (peripheral) { Serial.print("发现设备:"); Serial.print(peripheral.name()); Serial.print(" "); Serial.println(peripheral.address()); // 匹配遥控器设备(可以根据名称过滤,替换成你的遥控器名称) if (peripheral.name() == "你的遥控器名称") { BLE.stopScan(); Serial.println("连接遥控器..."); // 连接设备 if (peripheral.connect()) { Serial.println("连接成功"); } else { Serial.println("连接失败"); BLE.scan(); return; } // 发现HID服务 if (peripheral.discoverService(hidServiceUUID)) { Serial.println("找到HID服务"); // 获取输入报告特征 inputReportCharacteristic = peripheral.characteristic(inputReportUUID); if (inputReportCharacteristic) { Serial.println("找到输入报告特征"); // 检查是否支持通知 if (inputReportCharacteristic.canNotify()) { // 设置通知回调并启用通知 inputReportCharacteristic.setNotifyCallback(inputReportCallback); inputReportCharacteristic.enableNotify(true); Serial.println("已订阅输入报告通知,等待按键事件..."); } else { Serial.println("该特征不支持通知"); peripheral.disconnect(); BLE.scan(); return; } } else { Serial.println("未找到输入报告特征"); peripheral.disconnect(); BLE.scan(); return; } } else { Serial.println("未找到HID服务"); peripheral.disconnect(); BLE.scan(); return; } // 保持连接,处理事件 while (peripheral.connected()) { BLE.poll(); delay(10); } Serial.println("设备断开连接,重新扫描"); BLE.scan(); } } }
调试与注意事项
- 替换设备名称:将代码中
"你的遥控器名称"替换为实际遥控器的BLE名称(可以从扫描结果中获取)。 - 解析HID报告:不同遥控器的HID报告格式不同,运行代码后,按下不同按键,观察串口打印的十六进制数据,对比按键按下/松开时的差异,找到对应按键的特征位,修改
inputReportCallback中的判断逻辑。 - 工具辅助:可以用手机端的BLE调试工具扫描遥控器,查看其服务和特征,确认输入报告特征的UUID和属性(是否支持通知)。
内容的提问来源于stack exchange,提问作者dirk8b
相关产品推荐
相关产品推荐

