Edited at

Check! Raspberry Pi で Bluetooth 経由のセンサーデータを取得する 〜 準備編

More than 3 years have passed since last update.

こんにちは、オークファンの @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


GATT (Generic Attribute Profile)


動作確認

難しいことはおいおい学んでいくとして、手はじめに、 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 をインストールすることができました。