检测蓝牙遥控器上的按钮(GATT上的HID) [英] Detecting the buttons on a Bluetooth Remote (HID over GATT)

查看:49
本文介绍了检测蓝牙遥控器上的按钮(GATT上的HID)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个蓝牙LE遥控器,我想把它和我的覆盆子PI Zero配对。

]

我成功地将遥控器与Android手机配对,然后它就像键盘一样工作,我可以在键盘上将数字键入空白便签,甚至可以在手机上改变音量。

seemsRaspbian不支持GATT上的HID,这意味着我需要使用python实现/模拟GATT行为上的最小HID。(如果有更直接的方法,请纠正我。)

Raspbian

我可以使用lescan发现Linux终端中的遥控器:

sudo hcitool lescan
...
AA:BB:CC:DD:EE:FF FancyRemoteXY
现在,在GATTTool中,我可以与遥控器配对。然而,几秒钟后,当遥控器继续闪烁白色LED时,遥控器与我的PI断开连接。这种情况在Android手机上是不会发生的。因此,远程和主机之间必须进行某种握手,才能保持连接。

# Press 1 & 3 to unpair the remote from existing devices
gatttool -I -b AA:BB:CC:DD:EE:FF
connect
# Press the OK button on the remote

Python GATT Library

我现在可以读取特征,过去我还处理过BLE和读/写特征来控制灯泡。

目前还不清楚如何以"GATT-Ian"方式检测遥控器的按键事件。我did try to enable notifications for all the characteristics I found in the remote但从未调用回调。

我确实查看了Bluetooth HID over GATT Specification,但没有找到有关如何获得有关按键事件的通知的线索。

总而言之。我的问题如下:

  1. 如何才能在不丢失连接的情况下成功连接遥控器
  2. 如何使用GATT检测遥控器上按下的按钮

附录:蓝牙资源管理器GATT属性

使用iOS app我能够列出以下GATT服务和特征。

使用此应用程序,我还可以连接到遥控器,但也像Raspberry PI一样断开了连接。

LINUX

我现在可以在我的Raspberry Pi Zero上访问蓝牙LE遥控器了,这要归功于@ukBaz推荐答案pointed out如何通过关贸总协定访问HID(在LINUX中简称HOG

使用bluetoothctl

配对遥控器

此操作只能发生一次。

首先,我同时按住1和3以清除遥控器上的所有当前配对。这特定于我的远程型号,但最好知道在连接设备之前重置设备可能是必要的。

sudo bluetoothctl
power on
agent on
# you might need to do `scan on` / `scan off` until you see the remote
pair AA:BB:CC:DD:EE:FF
# click ok on the remote or otherwise confirm the pairing
trust AA:BB:CC:DD:EE:FF
connect AA:BB:CC:DD:EE:FF # Pairing might perform a connect, but it does not hurt
info # info shows you if you're connected and or paired with the remote

现在重新启动RaspberryPI

自动连接

bluetoothctl中的提示符显示您是否已连接到该设备。60秒后,连接断开。我认为这是一个问题,遥控器现在不会向PI发送命令,但重要的是要注意,一旦建立配对,遥控器似乎会自动连接到我的Raspberry PI。

Linux中的HOG和/dev/input

我首先想到的是,为了检测遥控器的按钮事件,我需要挂钩到GATT协议栈并检测那些GATT消息和事件。 这是可能的,但因为树莓Pi上的BlueZ支持通过GATT的HID,即蓝牙低能量鼠标、操纵杆、键盘、游戏控制器或遥控器。这意味着PI上的内核创建了一个驻留在/dev/input/中的输入设备。因此,一旦我配对并连接了我的BLE遥控器,/dev/input中确实显示了两个新条目:/dev/input/event1/dev/input/event0

我做了一个cat /dev/input/event1,一旦我按下遥控器上的一个键,我就看到一些字节垃圾在终端中飞来飞去。这样我就可以验证遥控器是否正在向PI发送事件。

使用evdev

读取事件

更新:evdev有一个模块,可让您快速输出所选设备的事件:

python3 -m evdev.evtest

@ukBaz指出我可以使用PIP3包evdev访问我的设备。通过运行以下Python代码,我能够检测远程🎉上的按钮

安装evdev并运行python3控制台:

pip3 install evdev
python3

运行python脚本

import evdev
device = evdev.InputDevice('/dev/input/event1')
print(device)
# device /dev/input/event1, name "Swisscom RC", phys "AA:BB:CC:DD:EE:FF"
for event in device.read_loop():
  if event.type == evdev.ecodes.EV_KEY:
    print(evdev.categorize(event))

这将输出以下内容:

key event at 1550575506.080840, 2 (KEY_1), down
key event at 1550575506.230643, 2 (KEY_1), up
key event at 1550575506.410622, 3 (KEY_2), down
key event at 1550575506.560618, 3 (KEY_2), up
key event at 1550575506.730621, 4 (KEY_3), down
key event at 1550575506.880608, 4 (KEY_3), up
key event at 1550575507.080630, 5 (KEY_4), down
key event at 1550575507.230630, 5 (KEY_4), up
key event at 1550575507.430884, 6 (KEY_5), down
key event at 1550575507.580611, 6 (KEY_5), up
key event at 1550575507.770633, 7 (KEY_6), down
key event at 1550575507.930623, 7 (KEY_6), up
key event at 1550575514.040805, 104 (KEY_PAGEUP), down
key event at 1550575514.295156, 104 (KEY_PAGEUP), hold
key event at 1550575514.345174, 104 (KEY_PAGEUP), hold
key event at 1550575514.395158, 104 (KEY_PAGEUP), hold
key event at 1550575514.445154, 104 (KEY_PAGEUP), hold
key event at 1550575514.495155, 104 (KEY_PAGEUP), hold
key event at 1550575514.545187, 104 (KEY_PAGEUP), hold
key event at 1550575514.595153, 104 (KEY_PAGEUP), hold
key event at 1550575514.645155, 104 (KEY_PAGEUP), hold
key event at 1550575514.695154, 104 (KEY_PAGEUP), hold
key event at 1550575514.745153, 104 (KEY_PAGEUP), hold
key event at 1550575514.795154, 104 (KEY_PAGEUP), hold
key event at 1550575514.840643, 104 (KEY_PAGEUP), up
key event at 1550575517.290737, 116 (KEY_POWER), down
key event at 1550575517.440740, 116 (KEY_POWER), up
key event at 1550575520.110901, 158 (KEY_BACK), down
key event at 1550575520.230905, 158 (KEY_BACK), up
key event at 1550575658.372344, 113 (['KEY_MIN_INTERESTING', 'KEY_MUTE']), down
key event at 1550575658.375718, 113 (['KEY_MIN_INTERESTING', 'KEY_MUTE']), up
key event at 1550575520.530643, 164 (KEY_PLAYPAUSE), down
key event at 1550575520.680666, 164 (KEY_PLAYPAUSE), up
key event at 1550575520.880818, 167 (KEY_RECORD), down
key event at 1550575521.020807, 167 (KEY_RECORD), up

事件对象有一个值0,1,2,它是按下并保持的,还有一个类似104的代码,它可以解析为相应的代码KEY_PAGEUP,在我的遥控器上是更改程序键。

请注意,静音键具有某种双重赋值,您可能需要以不同的方式进行处理。

Gotcha#1-更新Bluez

Bluez包确实支持GATT上的HID,并在此过程中进行了一些修复。在某些情况下,您必须将--experimental标志添加到Bluez服务/etc/systemd/system/dbus-org.bluez.serviceExecStart的末尾。但是,GATT上的HID在某个时候被添加到默认值。

我确实将Bluez更新到了bluez-5.50的最新版本。我是从源头做的,这不太难,described here

bluetoothctl -v
5.43

sudo apt-get install libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev -y

wget www.kernel.org/pub/linux/bluetooth/bluez-5.50.tar.xz
tar xvf bluez-5.50.tar.xz 
cd cd bluez-5.50/

./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --enable-experimental 
make -j4
sudo make install
sudo reboot
bluetoothctl -v
# bluetoothctl: 5.50

Gotcha#2-运行rpi-update

只是为了确保我确实使用rpi-update将raspberry pi更新到了最新版本。与所有这些问题一样,我不知道是否需要它们,但如果有疑问,通常更新您的系统是一个很好的做法。

这篇关于检测蓝牙遥控器上的按钮(GATT上的HID)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆