RaspberryPi から ESP32 のデータを BLE で読み出す

## ゴール、目的

我が家は断熱性能が結構高くて、油断して外に出るとめっちゃ寒かったなんてことがあり、家の中から外の気温を知る手段が欲しくなった。けど、それっぽい製品はそれなりのお値段なので、前に買って放置してた ESP32 で作ってみることにした。
wifi なら環境あるしすぐできそうだけど、せっかくなので BLE で遊んでみることにした。

![network.png](https://qiita-image-store.s3.amazonaws.com/0/9549/fb57d498-e444-8e62-4bf7-f85e8b036a2e.png)

## ハードウェア


RaspberryPi 3　に Bluetooth USB アダプタを挿して使うことにした。
https://www.planex.co.jp/products/bt-micro4/
Model B+ なら Bluetooth 内蔵で物欲が一瞬湧き上がったけど、これだけのために買い換えるのも... と思いとどまり。

## パッケージとかの準備
raspbian に apt-get で bluez をインストールするだけ。
バージョンはこんなかんじになってた。

```shell-session
pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 9.4 (stretch)
Release:	9.4
Codename:	stretch
pi@raspberrypi:~ $ dpkg -l | grep bluez
ii  bluez                           5.43-2+rpt2+deb9u2           armhf        Bluetooth tools and daemons
ii  bluez-firmware                  1.2-3+rpt5                   all          Firmware for Bluetooth devices
ii  bluez-hcidump                   5.43-2+rpt2+deb9u2           armhf        Analyses Bluetooth HCI packets
pi@raspberrypi:~ $
```

## とりあえず何かデータを送ってみる
Arduino IDE で　ファイル > スケッチ例 > ESP32 BLE Arduino > BLE_server を選択し、そのまま書き込む。
server = セントラルのイメージだけど、ここでは server = ペリフェラルになるらしい。

![スクリーンショット 2018-05-30 5.10.35.png](https://qiita-image-store.s3.amazonaws.com/0/9549/51736a9e-a9dd-ccaa-dcbc-5846fb59a9a8.png)

raspi から　ESP32 の Bluetooth アドレスを調べる

```shell-session
pi@raspberrypi:~ $ sudo hcitool lescan
LE Scan ...
24:0A:C4:0C:9C:EA MyESP32
24:0A:C4:0C:9C:EA MyESP32
24:0A:C4:0C:9C:EA MyESP32
^Cpi@raspberrypi:~ $
```

MyESP32 がターゲット。gatttool で接続してみる

```shell-session
pi@raspberrypi:~ $ gatttool -b 24:0A:C4:0C:9C:EA -I
[24:0A:C4:0C:9C:EA][LE]> connect
Attempting to connect to 24:0A:C4:0C:9C:EA
Connection successful
[24:0A:C4:0C:9C:EA][LE]>
```

やったね! 
次はデータを取得してみよう。まずサービス一覧を取得する。

```shell-session
[24:0A:C4:0C:9C:EA][LE]> characteristics
handle: 0x0002, char properties: 0x20, char value handle: 0x0003, uuid: 00002a05-0000-1000-8000-00805f9b34fb
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: 0x0019, char properties: 0x02, char value handle: 0x001a, uuid: 00002aa6-0000-1000-8000-00805f9b34fb
handle: 0x0029, char properties: 0x0a, char value handle: 0x002a, uuid: beb5483e-36e1-4688-b7f5-ea07361b26a8
[24:0A:C4:0C:9C:EA][LE]>
```

コードで指定している UUID は　`beb5483e-36e1-4688-b7f5-ea07361b26a8`なので、char value handle である `0x002a` を read してみる。

```shell-session
[24:0A:C4:0C:9C:EA][LE]> char-read-hnd 0x002a
Characteristic value/descriptor: 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 73 61 79 73 20 4e 65 69 6c
[24:0A:C4:0C:9C:EA][LE]>
```

ascii コードを変換してみると、

```shell-session
% python3
Python 3.6.5 (default, May 24 2018, 07:40:25)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> a='48 65 6c 6c 6f 20 57 6f 72 6c 64 20 73 61 79 73 20 4e 65 69 6c'.split()
>>> [chr(i) for i in map(lambda x: int(x, 16), a)]
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', ' ', 's', 'a', 'y', 's', ' ', 'N', 'e', 'i', 'l']
```

ということで無事データを受信できた。

あとは温度センサーを　ESP32　につなげて、raspi で表示できるようにして完成。今の所ノーガードだから、認証と暗号化も考えないと。