Raspberry Pi 4 にPyBluezをインストールしてBLEデバイスをスキャンする

投稿者: | 2022年10月8日

(2023/7/17 追記)ラズパイでBLEを扱うなら、こちらのサイトで紹介のある「bluepy」を使うほうが、定番かつ出来ることが多くておすすめだと思います。

PythonからBluetoothやBLE通信を扱えるライブラリ「PyBluez」を Raspberry Pi 4B (Buster) にインストールして、BLEデバイスをスキャンできるようになるまでの解説です。インストールに少々くせがあります。

※Python3環境を前提にしています。Python2の方、ごめんなさい。

Bluetoothの有効化

GUIが使える場合は、右上のBluetoothアイコンが青色になっていればOK。なっていない場合はアイコンをクリックして有効化する。

画面右上のBluetoothアイコンが青色になっていることを確認する

CUIから操作する場合、まずRF-KillでBluetoothを有効化。

sudo rfkill unblock bluetooth

次にhciconfigでも有効化する。hci0がBluetoothデバイスのことらしい。

sudo hciconfig hci0 up

hciconfigコマンドで、以下のようにRUNNINGになっていればOK。

$ hciconfig
hci0:   Type: Primary  Bus: UART
        BD Address: XX:XX:XX:XX:XX:XX  ACL MTU: 1021:8  SCO MTU: 64:1
        UP RUNNING
        RX bytes:3706 acl:0 sco:0 events:184 errors:0
        TX bytes:2149 acl:0 sco:0 commands:146 errors:0

ためしにBLEデバイスをhcitool lescanコマンドでスキャンしてみる。以下のように周囲のデバイスがぱらぱらと出てくれば成功。

$ sudo hcitool lescan
LE Scan ...
3D:D9:46:XX:XX:XX (unknown)
1A:7C:A9:XX:XX:XX (unknown)
6F:3A:70:XX:XX:XX (unknown)
C5:08:1E:XX:XX:XX (unknown)

PyBluezのインストール

分かるまでけっこう手間取ったので、備忘録として書き残す。手順として、必要な依存関係を apt install → gattlib のインストール → pybluez のインストール となる。

必要な依存関係をインストール

まず、sudo apt installで以下のパッケージをインストールする。

pkg-config
libboost-python-dev
libboost-thread-dev
libbluetooth-dev
libglib2.0-dev
python3-dev

gattlib をバージョンに注意しつつインストール

次に、Pythonライブラリのgattlibをインストールするのだが、これ以降のpip3コマンドはsudoをつける必要がある。そうしないと何が起きるかは最後のほうに書いてある。

以下のコマンドでgattlibをインストールする。注意点として、お使いのPythonバージョン(3.7 など)に合わせて、4行目のboost_python-py37を書き換えること

sudo pip3 download gattlib
tar xzf ./gattlib-0.20210616.tar.gz
cd gattlib-0.20210616/
sed -ie 's/boost_python-py34/boost_python-py37/' setup.py
sudo pip3 install .

pybluezをインストール

引き続きsudoが必要。注意点として、PyBluezの公式GitHubはじめインターネット上には、BLE通信を使うためには pybluez[ble] をインストールするという記述があるが、[ble]をつけるとpybluezとgattlibがまとめてインストールされてしまう。すると、前述したバージョンの不整合が生じてインストールに失敗するので注意。(ここで小一時間ハマった)

sudo pip3 install pybluez

いざBLEスキャン

公式READMEのExampleに載っているPythonコードを実行する。

from bluetooth.ble import DiscoveryService

service = DiscoveryService()
devices = service.discover(2)

for address, name in devices.items():
    print("name: {}, address: {}".format(name, address))

以下のように、周囲のBLEデバイスが表示されれば成功!

$ sudo python3 scan.py
name: , address: 6F:3A:70:XX:XX:XX
name: , address: 72:D7:60:XX:XX:XX

ちなみに

sudo権限でpython3を実行しないと怒られる。

$ python3 scan.py
Traceback (most recent call last):
  File "scan.py", line 4, in <module>
    devices = service.discover(2)
RuntimeError: Set scan parameters failed (are you root?)

たとえsudoを付けても、gattlibとpybluezをsudo権限でインストールしていない場合は怒られる

$ sudo python3 scan.py
Traceback (most recent call last):
  File "scan.py", line 1, in <module>
    from bluetooth.ble import DiscoveryService
ModuleNotFoundError: No module named 'bluetooth'

参考にしたサイト

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です