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

  • 34
    Like
  • 0
    Comment
More than 1 year has 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 をインストールすることができました。