こんにちは、オークファンの @dz_ こと大平かづみです。
Prologue - はじめに
Raspberry Pi で Bluetooth を使ってセンサーデバイスのデータを取得できるように、Bluetooth の扱い方について調べました。
なお、この試みは当初 Raspberry Pi Zero でやりはじめたのですが、メモリ不足で必要なライブラリがインストールできなかったので、 Raspberry Pi 2 Model B にて進めることとなりました。
Raspberry Pi で Bluethooth を使う
Bluetooth アダプタの用意
今回使う Raspberry Pi には Bluetooth は搭載されていないので、USBアダプタを利用します。
Bluetooth のUSBアダプタあれこれ
よく利用されているのは、PLANEX の製品のようです。私は、某電気屋さんにいったら PLANEX はおいてなかったので、一番安かった PRINCETON のものを購入しました(笑)特に問題なく動作しています。
Bluetooth で接続するセンサーデバイス
10種のセンサーが搭載されている SensorTag CC2650 を利用します。これは Bluetooth で接続ができ、サンプルコードやユーザーによる情報もちらほらあるため扱いやすそうです。
Linux で Bluetooth を扱う場合の周辺事情
私もまだ勉強中なのですが、Linux で Bluetooth を扱うには以下の仕組みを使っていくことになるようです。
BlueZ
- Official Linux Bluetooth protocol stack
- 参考: Bluetoothのはなし(4)|Wireless・のおと|サイレックス・テクノロジー株式会社
GATT (Generic Attribute Profile)
- Attribute Protocol (ATT) を基にデータの転送や保存の仕組みを共通化、フレームワーク化したもの
- 参考: Bluetoothのはなし(2)|Wireless・のおと|サイレックス・テクノロジー株式会社
動作確認
難しいことはおいおい学んでいくとして、手はじめに、 RPi Bluetooth LE - eLinux.org を参考に、コマンドラインから動作確認をしてみました。
# 接続されているUSB機器を確認する
$ lsusb
...
Bus 001 Device 011: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
...
# Bluetoothアダプタの状態を確認する
$ hciconfig
hci0: Type: BR/EDR Bus: USB
BD Address: XX:XX:XX:XX:XX:XX ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING
RX bytes:610 acl:0 sco:0 events:36 errors:0
TX bytes:942 acl:0 sco:0 commands:36 errors:0
# もし上記で `DOWN` と表示されていたら、以下のコマンドで有効にする
$ sudo hciconfig hci0 up
# 周辺の Bluetooth 機器をスキャンする
$ sudo hcitool lescan
LE Scan ...
XX:XX:XX:XX:XX:XX (unknown)
XX:XX:XX:XX:XX:XX CC2650 SensorTag
...
スキャン結果に SensorTag の表示がありました。無事、認識することができそうですね。
Python から Bluetooth を使う
それでは早速、プログラムから Bluetooth を使ってみようと思います。
言語は Raspberry Pi 界隈ではメジャーな Python を、復習がてら使ってみます。Bluetooth を扱うためのライブラリは pybluez
を導入してみます。
pybluez
のインストール
インストール自体は以下をご参考ください。pybluez
で BLE 対応の機器を扱うには gattlib
も必要なので、それもインストールします。
# pyBluez の依存パッケージをインストール
$ sudo apt-get install python-dev libbluetooth3-dev
# pyBluez のインストール
$ sudo pip install pybluez
# gattlib の依存パッケージをインストール
$ sudo apt-get install libglib2.0 libboost-python-dev libboost-thread-dev
# BLEを使う場合に必要な gattlib をインストール
$ sudo pip install gattlib
サンプルコード
それでは、python から SensorTag を探してみましょう。
SensorTag は BLE対応なので、このサンプルコードでスキャンすることができます。
また、データを取得するには、こちらのサンプルコードが参考になります。
なお、もうお気づきかもしれませんが、実は pybluez は、BLE対応機器を扱う際は pybluez を介して gattlib を利用しているだけなので、 gattlib 自体のドキュメントも参考になります。
また、GATT では「ハンドル」と呼ばれる番地(?)を用いてデータを取得・設定します。SensorTag の GATTテーブルは、 分解 | Simplelink センサタグ - TI の「センサとサービス」に掲載されていますので、ご参照くださいませ。
これで、好みのセンサーデータが取得できるようになりましたね!?
(実際には、取得したデータは LSB, MSB の転換などが必要となります。)
Epilogue - おわりに
大好きな Raspberry Pi Zero で動かせなかったのは残念でしたが、これで Raspberry Pi 2 から Bluetooth を利用する準備ができました!
もりもり進んでいきますよー!
以降は、トラブルシューティングに関して記載しました。
pybluez
インストール時のトラブルシューティング
Python.h
が見つからない場合
以下のように、fatal error: Python.h: No such file or directory
というエラーが発生する場合は、python-dev
をインストールする必要があります。
エラー内容
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno
-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-se
curity -fPIC -I./port3 -I/usr/include/python2.7 -c bluez/btmodule.c -o build/temp.linux-arm
v6l-2.7/bluez/btmodule.o
In file included from bluez/btmodule.c:20:0:
bluez/btmodule.h:4:20: fatal error: Python.h: No such file or directory
#include "Python.h"
^
compilation terminated.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
----------------------------------------
Command "/usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-4nXTDu
/pybluez/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\
r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-fWWiRf-record/install-record.txt
--single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-
4nXTDu/pybluez/
対処
$ sudo apt-get install python-dev
bluetooth/Bluetooth.h
が見つからない場合
以下のように、fatal error: bluetooth/bluetooth.h: No such file or directory
というエラーが発生する場合は、libbluetooth3-dev
をインストールする必要があります。
エラー内容
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno
-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-se
curity -fPIC -I./port3 -I/usr/include/python2.7 -c bluez/btmodule.c -o build/temp.linux-arm
v6l-2.7/bluez/btmodule.o
In file included from bluez/btmodule.c:20:0:
bluez/btmodule.h:5:33: fatal error: bluetooth/bluetooth.h: No such file or directory
#include <bluetooth/bluetooth.h>
^
compilation terminated.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
----------------------------------------
Command "/usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-OWwZct
/pybluez/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\
r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-_zZYsg-record/install-record.txt
--single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-
OWwZct/pybluez/
対処
$ sudo apt-get install libbluetooth3-dev
gattlib
インストール時のトラブルシューティング
boost/python/list.php
が見つからない場合
以下のように、fatal error: boost/python/list.hpp: No such file or directory
というエラーが発生する場合は、libboost-python-dev
をインストールする必要があります。
エラー内容
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno
-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-se
curity -fPIC -DVERSION="5.25" -I/usr/include/glib-2.0 -I/usr/lib/arm-linux-gnueabihf/glib-2
.0/include -Isrc/bluez -I/usr/include/python2.7 -c src/gattservices.cpp -o build/temp.linux
-armv6l-2.7/src/gattservices.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not
for C++
In file included from src/gattservices.cpp:12:0:
src/gattlib.h:11:33: fatal error: boost/python/list.hpp: No such file or directory
#include <boost/python/list.hpp>
^
compilation terminated.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
----------------------------------------
Command "/usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-lIdNTN
/gattlib/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\
r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-h_pTpQ-record/install-record.txt
--single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-
lIdNTN/gattlib/
対処
$ sudo apt-get install libboost-python-dev
glib-2.0 がみつからない場合
以下のように、No package 'glib-2.0' found
というエラーが発生する場合は、libglib2.0
をインストールする必要があります。
エラー内容
$ sudo pip install gattlib
Collecting gattlib
Downloading gattlib-0.20150805.tar.gz (1.7MB)
100% |████████████████████████████████| 1.7MB 86kB/s
Complete output from command python setup.py egg_info:
Package glib-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `glib-2.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'glib-2.0' found
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-build-ix7ocM/gattlib/setup.py", line 12, in <module>
"pkg-config --cflags glib-2.0".split()).decode('utf-8')
File "/usr/lib/python2.7/subprocess.py", line 573, in check_output
raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['pkg-config', '--cflags', 'glib-2.0']' returne
d non-zero exit status 1
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-ix7ocM/gattli
b/
対処
$ sudo apt-get install libglib2.0
-lboost_thread
が見つからない場合
以下のように、cannot find -lboost_thread
というエラーが発生する場合は、libboost-thread-dev
をインストールする必要があります。
エラー内容
c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -
DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector-s
trong -Wformat -Werror=format-security -Wl,-z,relro -D_FORTIFY_SOURCE=2 -g -fstack-protecto
r-strong -Wformat -Werror=format-security build/temp.linux-armv7l-2.7/src/gattservices.o bu
ild/temp.linux-armv7l-2.7/src/beacon.o build/temp.linux-armv7l-2.7/src/bindings.o build/tem
p.linux-armv7l-2.7/src/gattlib.o build/temp.linux-armv7l-2.7/src/bluez/lib/uuid.o build/tem
p.linux-armv7l-2.7/src/bluez/attrib/gatt.o build/temp.linux-armv7l-2.7/src/bluez/attrib/gat
trib.o build/temp.linux-armv7l-2.7/src/bluez/attrib/utils.o build/temp.linux-armv7l-2.7/src
/bluez/attrib/att.o build/temp.linux-armv7l-2.7/src/bluez/src/shared/crypto.o build/temp.li
nux-armv7l-2.7/src/bluez/src/log.o build/temp.linux-armv7l-2.7/src/bluez/btio/btio.o -lglib
-2.0 -lboost_python -lboost_thread -lbluetooth -o build/lib.linux-armv7l-2.7/gattlib.so
/usr/bin/ld: cannot find -lboost_thread
collect2: error: ld returned 1 exit status
error: command 'c++' failed with exit status 1
対処
$ sudo apt-get install libboost-thread-dev
internal compiler error: Killed の場合
このエラーのときは、なかなかプロンプトが返ってこないで、返ってきたと思ったらこのエラーが表示されます。
エラー内容
arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-s
trict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-secu
rity -fPIC -DVERSION="5.25" -I/usr/include/glib-2.0 -I/usr/lib/arm-linux-gnueabihf/glib-2.0
/include -Isrc/bluez -I/usr/include/python2.7 -c src/bindings.cpp -o build/temp.linux-armv6
l-2.7/src/bindings.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not f
or C++
arm-linux-gnueabihf-gcc: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.9/README.Bugs> for instructions.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 4
原因
これは、どうやらメモリ不足のようです。
当初試していた Raspberry Pi Zero ではこれ以上 gattlib のインストールが進められませんでしたが、 Raspberry Pi 2 Model B であれば、このエラーは出ずに gattlib をインストールすることができました。