Satoshi’s Blog

Tips for IoT development.

Using Bluetooth on Raspberry Pi

今回はRaspberry PiでBluetoothを使えるようにしたいと思います。

BluetoothのドングルはPLANEX の BT-Micro4を使いました。BLEタグと接続するので、Bluetooth 4.0対応のものが必要です。

Bluethoothを扱うためにBluezをインストールします。こちらによるとBluezはソースから最新版を入れたほうがよさそうです。

1
2
3
4
5
6
7
pi@raspberrypi ~ $ sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev
pi@raspberrypi ~ $ sudo wget https://www.kernel.org/pub/linux/bluetooth/bluez-5.27.tar.xz
pi@raspberrypi ~ $ sudo tar xvf bluez-5.27.tar.xz
pi@raspberrypi ~ $ cd bluez-5.27/
pi@raspberrypi ~/bluez-5.27 $ sudo LDFLAGS=-lrt./configure --disable-systemd
pi@raspberrypi ~/bluez-5.27 $ make
pi@raspberrypi ~/bluez-5.27 $ sudo make install

下記のようなエラーがLDFLAG-lrtを付けてみてください。

/usr/bin/ld: profiles/health/mcap.o: undefined reference to symbol 'clock_getres@@GLIBC_2.4'
//lib/arm-linux-gnueabihf/librt.so.1: error adding symbols: DSO missing from command line
collect2: ld returned 1 exit status
Makefile:4184: recipe for target 'tools/mcaptest' failed
make[1]: *** [tools/mcaptest] Error 1
Makefile:2648: recipe for target 'all' failed
make: *** [all] Error 2

参考: http://www.forum-raspberrypi.de/Thread-raspbian-bluez-5-x-kann-nicht-erstellt-werden

まず、ドングルがUSB機器として認識しているかを確認します。

1
2
3
4
5
6
pi@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 006: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 005: ID 0411:01a2 BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070]

ちゃんと認識されました。

hciconfigを用いて状態を確認します。

1
2
3
4
5
6
pi@raspberrypi ~ $ hciconfig
hci0:     Type: BR/EDR  Bus: USB
     BD Address: 00:1B:DC:06:0C:04  ACL MTU: 310:10  SCO MTU: 64:8
     DOWN
     RX bytes:547 acl:0 sco:0 events:27 errors:0
     TX bytes:384 acl:0 sco:0 commands:27 errors:0

上のようにDown状態だったら起動します。

1
2
3
4
5
6
7
pi@raspberrypi ~ $ sudo hciconfig hci0 up
pi@raspberrypi ~ $ hciconfig
hci0:     Type: BR/EDR  Bus: USB
     BD Address: 00:1B:DC:06:0C:04  ACL MTU: 310:10  SCO MTU: 64:8
     UP RUNNING
     RX bytes:1094 acl:0 sco:0 events:54 errors:0
     TX bytes:768 acl:0 sco:0 commands:54 errors:0

WICED Senseの電源を入れ、スキャンします。

1
2
3
4
5
6
7
pi@raspberrypi ~ $ sudo hcitool lescan
LE Scan ...
00:10:18:01:07:F1 WICED Sense Kit
00:10:18:01:07:F1 (unknown)
00:10:18:01:07:F1 WICED Sense Kit
00:10:18:01:07:F1 (unknown)
... (snip) ...

WICED Senseのアドレスが00:10:18:01:07:F1であることが分かりました。 ひたすらログが出続けるのでCTRL-Cで止めます。

実際に接続できるか確認してみましょう。

1
2
pi@raspberrypi ~ $ sudo hcitool lecc 00:10:18:01:07:F1
Connection handle 71

問題なさそうなのでgatttoolを使って、インタラクティブモードで接続してみます。

1
2
3
4
5
6
7
pi@raspberrypi ~ $ sudo gatttool -b 00:10:18:01:07:F1 -I
[00:10:18:01:07:F1][LE]> connect
Attempting to connect to 00:10:18:01:07:F1
Connection successful
[00:10:18:01:07:F1][LE]> primary
Command Failed: Disconnected
[00:10:18:01:07:F1][LE]>

最初は接続できるものの、すぐに切断されてしまい、primaryコマンドがエラーとなります。

ノンインタラクティブモードなら大丈夫のようです。

1
2
3
4
5
6
7
pi@raspberrypi ~ $ sudo gatttool -b 00:10:18:01:07:F1  --primary
attr handle = 0x0001, end grp handle = 0x0001 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle = 0x0014, end grp handle = 0x0018 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle = 0x0028, end grp handle = 0x002b uuid: 739298b6-87b6-4984-a5dc-bdc18b068985
attr handle = 0x004d, end grp handle = 0x0053 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle = 0x0061, end grp handle = 0x0063 uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle = 0xff00, end grp handle = 0xff07 uuid: a86abc2d-d44c-442e-99f7-80059a873e36
1
2
3
4
5
6
7
8
9
10
11
pi@raspberrypi ~ $ sudo gatttool -b 00:10:18:01:07:F1  --characteristics
handle = 0x0015, char properties = 0x02, char value handle = 0x0016, uuid = 00002a00-0000-1000-8000-00805f9b34fb
handle = 0x0017, char properties = 0x02, char value handle = 0x0018, uuid = 00002a01-0000-1000-8000-00805f9b34fb
handle = 0x0029, char properties = 0x12, char value handle = 0x002a, uuid = 33ef9113-3b55-413e-b553-fea1eaada459
handle = 0x004e, char properties = 0x02, char value handle = 0x004f, uuid = 00002a29-0000-1000-8000-00805f9b34fb
handle = 0x0050, char properties = 0x02, char value handle = 0x0051, uuid = 00002a24-0000-1000-8000-00805f9b34fb
handle = 0x0052, char properties = 0x02, char value handle = 0x0053, uuid = 00002a23-0000-1000-8000-00805f9b34fb
handle = 0x0062, char properties = 0x02, char value handle = 0x0063, uuid = 00002a19-0000-1000-8000-00805f9b34fb
handle = 0xff01, char properties = 0x18, char value handle = 0xff02, uuid = 1bd19c14-b78a-4e0f-aeb5-8e0352bac382
handle = 0xff04, char properties = 0x08, char value handle = 0xff05, uuid = 279f9dab-79be-4663-af1d-24407347af13
handle = 0xff06, char properties = 0x02, char value handle = 0xff07, uuid = 6aa5711b-0376-44f1-bca1-8647b48bdb55

切断されてしまう原因が分からないのですが、ノンインタラクティブモードで進めてみましょう。

Manufacturer Name Stringを取得してみます。

1
2
3
4
pi@raspberrypi ~ $ sudo gatttool -b 00:10:18:01:07:F1  --char-read --handle=0x004f
Characteristic value/descriptor: 42 72 6f 61 64 63 6f 6d
pi@raspberrypi ~ $ echo "42 72 6f 61 64 63 6f 6d" | tr -d \ | xxd -r -p; echo ""
Broadcom

期待通りBroadcomという文字列が取得できました。

では、本来の目的であるセンサー情報を取得してみます。ここを参考に、notificationを受け取るために0x0100を書き込みます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sudo gatttool -b 00:10:18:01:07:F1 --char-write-req --handle=0x002b --value=0100 --listen
Characteristic value was written successfully
Notification handle = 0x002a value: 0b 00 00 01 00 53 00 11 06 3d e9 d5 03 d6 03 a8 ff 56 fb
Notification handle = 0x002a value: 0b 00 00 01 00 52 00 11 06 3d e9 d5 03 d9 03 9f ff 5b fb
Notification handle = 0x002a value: 0b 00 00 02 00 53 00 11 06 3d e9 d5 03 ed 03 a1 ff 61 fb
Notification handle = 0x002a value: 0b 00 00 01 00 52 00 11 06 3d e9 d5 03 d9 03 a1 ff 5d fb
Notification handle = 0x002a value: 0b 00 00 01 00 53 00 11 06 3d e9 d5 03 df 03 a1 ff 59 fb
Notification handle = 0x002a value: 0b 00 00 01 00 53 00 11 06 3d e9 d5 03 db 03 a0 ff 5d fb
Notification handle = 0x002a value: 0b 00 00 01 00 53 00 11 06 3d e9 d5 03 e0 03 9e ff 51 fb
Notification handle = 0x002a value: 0b 00 00 01 00 53 00 11 06 3d e9 d5 03 d6 03 a3 ff 52 fb
Notification handle = 0x002a value: 0b 00 00 01 00 53 00 11 06 3d e9 d5 03 de 03 9a ff 61 fb
Notification handle = 0x002a value: 34 09 02 79 27 a8 00
Notification handle = 0x002a value: 0b 00 00 02 00 52 00 11 06 3d e9 d5 03 e9 03 93 ff 54 fb
Notification handle = 0x002a value: 0b 00 00 02 00 52 00 11 06 3d e9 d5 03 e0 03 a7 ff 5d fb
Notification handle = 0x002a value: 0b 00 00 02 00 53 00 11 06 3d e9 d5 03 e0 03 9f ff 65 fb
Notification handle = 0x002a value: 0b 00 00 02 00 53 00 11 06 3d e9 d5 03 e5 03 9a ff 5d fb
Notification handle = 0x002a value: 0b 00 00 02 00 52 00 11 06 3d e9 d5 03 d3 03 9c ff 55 fb
Notification handle = 0x002a value: 0b 00 00 02 00 53 00 11 06 3d e9 d5 03 dc 03 9f ff 54 fb
Notification handle = 0x002a value: 0b ff ff 02 00 53 00 11 06 3d e9 d5 03 da 03 93 ff 5f fb

無事、センサーデータを取得できたのですが、やはい、1秒くらいで接続が切れてしまいます。

hcidumpでパケットをキャプチャしてみたところ、WICED Senseから接続を切っているようですが。。。今日のところはここで手詰まりです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> ACL data: handle 71 flags 0x02 dlen 26
    ATT: Handle notify (0x1b)
      handle 0x002a
      value 0x0b 0x00 0x00 0x01 0x00 0x53 0x00 0x11 0x06 0x3d 0xe9 0xd5 0x03 0xff 0x03 0x06 0x00 0x86 0xfb
> ACL data: handle 71 flags 0x02 dlen 26
    ATT: Handle notify (0x1b)
      handle 0x002a
      value 0x0b 0x00 0x00 0x02 0x00 0x52 0x00 0x11 0x06 0x3d 0xe9 0xd5 0x03 0x13 0x04 0x05 0x00 0x95 0xfb
< HCI Command: Disconnect (0x01|0x0006) plen 3
    handle 71 reason 0x13
    Reason: Remote User Terminated Connection
> HCI Event: Command Status (0x0f) plen 4
    Disconnect (0x01|0x0006) status 0x00 ncmd 1
> ACL data: handle 71 flags 0x02 dlen 26
    ATT: Handle notify (0x1b)
      handle 0x002a
      value 0x0b 0x00 0x00 0x02 0x00 0x53 0x00 0x11 0x06 0x3d 0xe9 0xd5 0x03 0x07 0x04 0x02 0x00 0x90 0xfb
> HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 71 reason 0x16
    Reason: Connection Terminated by Local Host

References