みかんのゆるふわ技術ブログ

Raspberry PiやIoT関係のことを書き残していきます

SensorTag (CC2650STK) とBLE通信 ~ Python + bluepyで簡単アクセス

前回の記事で、SensorTag (CC2650STK) にgatttoolを使ってアクセスしてみました。

www.mikan-tech.net

SensorTagの仕様書を見ながら、対応するセンサーのON/OFFをしたり、値を読み出したり…。 BLEやGATTの勉強には良いですが、手間がかかって不便ですよね。

そこで今回は、SensorTagにとても簡単にアクセスできるPythonライブラリのbluepyを使って簡単アクセスしてみたいと思います。

github.com

bluepy

bluepyとは

bluepyはLinuxのBluetoothプロトコルスタックであるbluezをPythonから扱えるようにするオープンソースのライブラリです。 bluepy-helperというC言語のネイティブコードのヘルパーコマンドを持っており、これを使ってbluezとやり取りします。 デバイスのスキャン、サービス、特性(Characteristic)へのアクセスなど、一通りの機能が揃っています。

APIリファレンスはこちらにあります。

ianharvey.github.io

インストール

試しに、手元のRaspberry Piにインストールしてみたいと思います。pipを使って簡単に導入できるので便利です。 sudo権限を使わずに、venv環境にインストールしてみます。 まずはPython3のpipとvenvパッケージをインストールします。

$ sudo apt install python3-pip python3-venv

続いて、好きな場所にvenv環境を作成します。

$ mkdir ~/sensortag
$ cd ~/sensortag
$ python3 -m venv venv

これで、~/sensortag/venvにvenv環境ができました。ここで、source ./venv/bin/activateとアクティベートすると、pythonpipコマンドがvenv環境のものに置き換わるので、以下のコマンドで./venv/bin/pythonなどとパスを指定せずpythonとしても大丈夫です。ここではアクティベートせずに進めた例を示しておきます。

いよいよbluepyをインストールしましょう。

$ ./venv/bin/pip install bluepy

これだけでbluepyがすんなりインストールできました。

SensorTagへのアクセス

sensortagコマンド

実はbluepyにはSensorTagへのアクセス用のライブラリとコマンドが付属しており、何もコードを書かなくてもアクセスができます。試してみましょう。

まずは、SensorTagのMACアドレスを調べます。SensorTagの電源を入れ、bluez付属のhcitoolでスキャンしてみます。

$ sudo hcitool lescan
LE Scan...
54:6C:0E:79:13:06 (unknown)
54:6C:0E:79:13:06 CC2650 SensorTag

大量のMACアドレスが出るかもしれませんが、CC2650 SensorTagというものを探します。私の場合、54:6C:0E:79:13:06でした。

続いて、bluepy付属のサンプルコマンドからセンサーの値を読んでみましょう。実はbluepyをインストールすると、sensortagコマンドも付属でインストールされています。これを使うと簡単にアクセスできます。

$ sudo ./venv/bin/sensortag --all -n 1 54:6C:0E:79:13:06
Connecting to 54:6C:0E:79:13:06
Temp:  (25.34375, 20.75)
Humidity:  (25.3997802734375, 55.877685546875)
Barometer:  (25.53, 1008.9)
Accelerometer:  (0.0576171875, 0.0498046875, 2.02734375)
Magnetometer:  (-96.86056166056166, -27.288888888888888, -57.57655677655677)
Gyroscope:  (-2.96783447265625, 1.2054443359375, 1.953125)
Light:  512.48
Battery:  86

Tempは赤外線放射温度センサーで、()の中身は前者が気温(雰囲気温度)[℃]、後者が対象物の温度[℃]です。Humidityは前者が気温[℃]、後者が湿度[%]です。Barometerは前者が気温[℃]、後者が気圧[hPa]です。Lightは明るさ[lx]を示します。気温が何種類も取得できていますが、3つのセンサーにそれぞれ温度センサーが内蔵されているので、このようになっています。まあ、どれも25.3~25.5℃を示しているので、どれを見ても良いでしょう。

sensortagコマンドのオプションですが、--allとすると全てのセンサー値を取得します。-n 1で1回だけ取得して接続を終了することを示します。回数を指定しないと、Ctrl-Cが押されるまでデフォルトで5秒インターバルで繰り返しセンサー値を取得します。取得間隔は-t 60などのように秒数で指定できます。

Pythonスクリプト

いよいよ自分のPythonスクリプトからアクセスしてみましょう。sensortag用のライブラリがあるので簡単です。 例えば、温度・湿度・気圧・照度・バッテリー残量を測定して、気象センサーみたいにしてみましょう。 最低限のスクリプトは、次のようになります。

from bluepy.sensortag import SensorTag
import time

SENSORTAG_MAC_ADDRESS = "54:6C:0E:79:13:06"

# Connect to SensorTag
print("Connecting to " + SENSORTAG_MAC_ADDRESS)
tag = SensorTag(SENSORTAG_MAC_ADDRESS)
print("Connected.")

# Turn on sensors
tag.humidity.enable()
tag.barometer.enable()
tag.lightmeter.enable()
tag.battery.enable()

# Waiting for sensor initialization
time.sleep(1.0)

# Read sensor value
humidity_value = tag.humidity.read()     # Returns tuple (temperature, humidity)
barometer_value = tag.barometer.read()   # Returns tuple (temperature, barometer)
lightmeter_value = tag.lightmeter.read()
battery_value = tag.battery.read()

# Print sensor value
print("Temperature: {:.1f}℃".format(humidity_value[0]))
print("Humidity: {:.1f}%".format(humidity_value[1]))
print("Barometer: {:.1f}hPa".format(barometer_value[1]))
print("Light: {:.0f}lx".format(lightmeter_value))
print("Battery: {:d}%".format(battery_value))

# Turn off sensors
tag.humidity.disable()
tag.barometer.disable()
tag.lightmeter.disable()
tag.battery.disable()

# Disconnect from SensorTag
tag.disconnect()

実行すると、このようになります。

$ ./venv/bin/python test.py
Connecting to 54:6C:0E:79:13:06
Connected.
Temperature: 25.3℃
Humidity: 63.9%
Barometer: 1008.4hPs
Light: 517lx
Battery: 86%

注意点としては、センサー値を読む前にセンサーをONにする必要があることと、センサーによってはONにしてから1秒ほど待たないと正しい値が読めないことです。このあたりの詳しい仕様はSensorTagのマニュアルを参照してください。

processors.wiki.ti.com

これでセンサー値が読めるようになったので、Pythonを使ってデーターベースに保存するなり、可視化アプリを作るなり、好きなようにできますね。 楽しいDIYにお使いください!