IoTに関する研修を受けてきまして、raspberry piとクラウド(AWS IoT)の連携に関してはできるようになったのですが、BLEを使ったM2Mのような通信をさせたことがありませんでした。
そこで、raspberry pi(raspberry pi3 model B+) とwatchX(arduino leonarde)を使い、watchXの温度センサから値を取得し、BLEでwatchXからraspberry piへセンサ値を送ってみました。
簡単に行くかなと思ったのですが、割とはまりどころが多かったのでここにまとめます。
開発環境
watchX
以下のサイトをご参考ください。arduino leonardeが乗ったスマートウォッチと考えていただければいいかと思います。
https://www.watchx.io/
また、必要なarduinoのライブラリが以下で提供されているので、この中のBLEのペリフェラルとして、温度センサの値を送る「healththermometer」というサンプルプロジェクトを使用します
https://www.watchx.io/download.php
raspberry pi3 model B+
raspberry pi3 model B+に関しては、bluetoothモジュールがついているので、それを使って通信します。
また、今後、AWSとの連携も考えていきたいので、pythonを使ってBLEセントラルとしての機能を実装します。当初、pybluezを使用していたのですが、うまくモジュールが動かないとの情報も多々ある(自分の手持ちのraspberry piでも動きませんでした・・・)ので、bluepyを使用することにしました。
bluepy の導入は以下の記事を参考にさせていただきました。(とてもわかりやすくて助かりました)
https://qiita.com/FiveOne/items/ea04b74271da0f382ed6
ソースコード
watchX
開発環境の項目で紹介したライブラリですが、どうやらピン配置の設定が違うらしく、うまくBLEモジュールが動きませんでした。そのため、以下のように「BluefruitConfig.h」を改良しました。
https://github.com/tomsWalker/watchX/blob/master/healththermometerWatchX/BluefruitConfig.h
その他の場所はサンプルのままで問題ないようでした。(watchXのコードはファイルもいくつかに分かれていますのでgithubにあげさせてもらいました)
raspberry pi
開発環境作成もお世話になった以下の記事の「notify.py」を流用させていただきまして、温度センサの値を取得しました。
https://qiita.com/FiveOne/items/ea04b74271da0f382ed6
watchX側のプログラム上、使用するキャラクタリスティックのプロパティが「indicate」になるので、以下のように変更し、値を取得いたしました。
import bluepy
import binascii
HANDLE_INDICATE = XX # ここに使用するwatchXのキャラクタリスティックのハンドルを入れます
devadr = "XX:XX:XX:XX:XX:XX" # ここにwatchXのBLEのアドレスを入れます
class MyDelegate(bluepy.btle.DefaultDelegate):
def __init__(self, params):
bluepy.btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
c_data = binascii.b2a_hex(data)
print("data:")
print(c_data)
def main():
peri = bluepy.btle.Peripheral()
peri.connect(devadr, bluepy.btle.ADDR_TYPE_RANDOM)
peri.withDelegate(MyDelegate(bluepy.btle.DefaultDelegate))
# プロパティがindicateなので、「'\x01\x00'」ではなく「'\x02\x00'」を書き込む
peri.writeCharacteristic(HANDLE_INDICATE+1, b'\x02\x00')
while True:
if peri.waitForNotifications(1.0):
continue
print("wait...")
if __name__ == "__main__":
main()
最後に
なんとか、上記のソースコードでBLE通信ができるようになりました。
watchXも、温度センサだけでなく加速度センサなどもついているので、その辺りのセンサを使用したり、AWSとの連携も考えていこうかと思います