簡體   English   中英

檢測藍牙遙控器上的按鈕(HID over GATT)

[英]Detecting the buttons on a Bluetooth Remote (HID over GATT)

我有一個藍牙 LE 遙控器,我想將它與我的 Raspberry Pi Zero 配對。

我的遙控器 ]

我能夠成功地將遙控器與 Android 手機配對,然后它像鍵盤一樣工作,我能夠在鍵盤上將數字輸入到空白音符中,甚至可以更改手機的音量。

似乎raspbian 不支持 HID over Gatt,這意味着我需要使用 python 實現/模仿最小的 HID over GATT 行為。 (如果有更直接的方法來做到這一點,請糾正我。)

樹莓派

我可以使用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 庫

我現在可以讀取特性,而且我過去也已經處理過 BLE 和讀/寫特性來控制燈泡。

目前尚不清楚如何以“GATT-ian”方式檢測遙控器的按鍵事件。 確實嘗試為我在遙控器中找到的所有特征啟用通知,但從未調用過回調。

我確實查看了 GATT 規范上的藍牙 HID,但沒有找到有關如何實現按鍵事件通知的線索。

總結。 我的問題如下:

  1. 如何在不丟失連接的情況下成功連接遙控器
  2. 如何使用 GATT 檢測遙控器上的按下按鈕

附錄:藍牙瀏覽器 GATT 屬性

使用iOS 應用程序,我能夠列出以下 GATT 服務和特征。

使用此應用程序,我還可以連接到遙控器,但也像使用 Raspberry Pi 一樣斷開了連接。

圖 1 圖 2

感謝@ukBaz指出如何通過 GATT(Linux 中的短HoG)訪問 HID,我現在可以在我的 Raspberry Pi Zero 上訪問藍牙 LE 遙控器:

使用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

現在重啟樹莓派

自動連接

bluetoothctl ,提示會顯示您是否已連接到設備。 60 秒后連接斷開。 我認為這是一個問題,遙控器現在不會向 PI 發送命令,但重要的是要注意,一旦配對建立,遙控器似乎會自動連接到我的 Raspberry Pi。

Linux 和/dev/input HoG

我首先想到我需要掛鈎 GATT 協議棧並檢測那些 GATT 消息和事件,以便檢測我的遙控器的按鈕事件。 這是可能的,但由於 Raspberry Pi 上的 BlueZ 支持 HID over GATT,即藍牙低功耗鼠標、操縱桿、鍵盤、游戲控制器或遙控器。 這意味着 Pi 上的內核會創建一個位於/dev/input/的輸入設備。 因此,一旦我配對並連接了我的 BLE Remote,兩個新條目確實出現在/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 ,它在我的遙控器上是更改程序鍵。

請注意靜音鍵有某種雙重分配,您可能需要以不同的方式處理。

陷阱 #1 - 更新 Bluez

bluez 包確實支持 HID over GATT,並且在此過程中進行了一些修復。 在某些時候,你就必須在添加--experimental標志結束ExecStart中的bluez服務/etc/systemd/system/dbus-org.bluez.service 但是,HID over GATT 在某個時候被添加到默認值中。

我確實將 bluez 更新到最新版本bluez-5.50 我從源代碼中做到了這一點,這不太難,並在此處進行了描述

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

陷阱 #2 - 運行rpi-update

為了確保我確實使用rpi-update將樹莓派更新到最新版本。 與所有這些問題一樣,我不知道它們是否是必需的,但如果有疑問,更新系統通常是一個好習慣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM