ゴール、目的
我が家は断熱性能が結構高くて、油断して外に出るとめっちゃ寒かったなんてことがあり、家の中から外の気温を知る手段が欲しくなった。けど、それっぽい製品はそれなりのお値段なので、前に買って放置してた ESP32 で作ってみることにした。
wifi なら環境あるしすぐできそうだけど、せっかくなので BLE で遊んでみることにした。
ハードウェア
RaspberryPi 3 に Bluetooth USB アダプタを挿して使うことにした。
https://www.planex.co.jp/products/bt-micro4/
Model B+ なら Bluetooth 内蔵で物欲が一瞬湧き上がったけど、これだけのために買い換えるのも... と思いとどまり。
パッケージとかの準備
raspbian に apt-get で bluez をインストールするだけ。
バージョンはこんなかんじになってた。
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 = ペリフェラルになるらしい。
raspi から ESP32 の Bluetooth アドレスを調べる
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 で接続してみる
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]>
やったね!
次はデータを取得してみよう。まずサービス一覧を取得する。
[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 してみる。
[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 コードを変換してみると、
% 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 で表示できるようにして完成。今の所ノーガードだから、認証と暗号化も考えないと。