LoginSignup
18
18

More than 5 years have passed since last update.

BLE温度計を作ってPythonista3で温度を取得する

Last updated at Posted at 2017-10-29

BLE温度計を作ってPythonista3で温度を取得する

はじめに

そういえば、Pythonista3ってBLE(Bluetooth Low Energy)が扱えるんだなぁ。
そういえば、ESP-WROOM-32のBluetooth機能を使ったことがないなぁ。
じゃあ、BLE温度計から温度を取得してみよう!

やりたいこと

BLE温度計(ESP-WROOM-32 + 温度センサ)からiPhoneで温度を取得する。

用意したもの

ESP-WROOM-32(ESP32-DevKitC)
温度センサ DS18B20
iPhone(Pythonista3インストール済み)

やり方

ESP-WROOM-32とDS18B20を接続し、温度を測定する。
ESP-WROOM-32のBLEで温度を送信する。
温度がどうしても気になるとき、iPhoneで温度を受信する。

完成イメージ

system_ds18b20.png

作る

ESP-WROOM-32とDS18B20を接続する

DS18B20は1-wireで接続する。データシートは次のようになっている。
ds18B20.png
そのためESP-WROOM-32とは以下のように接続する。
esp32_ds18B20.png
接続完了
esp32_temp.png

温度センサから温度を取得する

DS18B20と1-wire通信を行い、温度を取得する。
プログラムはfeelfreelinux/ds18b20を参考にした。

ESP-WROOM-32からBLEを使う

ソースコード

少し長いのでgithubにおいた。
esp/thermometer
ds18b20.c : 温度センサから値を取得する。
gatts_thermometer.c : ESP32をBLEのサーバーにする。クライアントからのREADイベントでセンサ値を送信する。
※ビルドにはESP-IDFが必要

プログラムはESP-IDFに付属しているGATT Serverサンプルを利用して作成した。
GATTについては【BLEを使う】GATT(Generic Attribute Profile)概要がとても参考になった。
製品化するわけではないので、UUIDは適当な値を使用している。

Pythonista3からBLEを使う

ソースコード

Pythonista3でcbを使用し、温度データを取得する。
UUIDは上記のプログラムに合わせている。

thermo_client.py
import ui
import cb
import sound
import struct

TM_SERVICE_UUID = '00FF'
TM_CHAR_UUID = 'FF01'

class MyCentralManagerDelegate (object):
    def __init__(self):
        self.peripheral = None
        self.temp = 0

    def did_discover_peripheral(self, p):
        global text_state
        print('+++ Discovered peripheral: %s (%s)' % (p.name, p.uuid))
        if p.name and 'ESP_THERMOMETER' in p.name and not self.peripheral:
            # Keep a reference to the peripheral, so it doesn't get garbage-collected:
            self.peripheral = p
            cb.connect_peripheral(self.peripheral)
            text_state.text = 'Detected'

    def did_connect_peripheral(self, p):
        print('*** Connected: %s' % p.name)
        print('Discovering services...')
        p.discover_services()

    def did_fail_to_connect_peripheral(self, p, error):
        print('Failed to connect')

    def did_disconnect_peripheral(self, p, error):
        print('Disconnected, error: %s' % (error,))
        self.peripheral = None

    def did_discover_services(self, p, error):
        for s in p.services:
            if TM_SERVICE_UUID in s.uuid:
                print('+++ Thermometer found')
                p.discover_characteristics(s)

    def did_discover_characteristics(self, s, error):
        if TM_SERVICE_UUID in s.uuid:
            for c in s.characteristics:
                if TM_CHAR_UUID in c.uuid:
                    print('read temperature sensor...')
                    self.peripheral.read_characteristic_value(c)

    def did_write_value(self, c, error):
        print('Did enable temperature sensor')

    def did_update_value(self, c, error):
        global text_temp
        if TM_CHAR_UUID == c.uuid:
            # 
            self.temp = (c.value[0] + (c.value[1]*256))/16
            print(self.temp)
            text_temp.text=(str(self.temp) + '℃')

view = ui.View()                                      
view.name = 'THERMOMETER'                                    
view.background_color = 'white'

text_state = ui.TextView()
text_state.frame = (view.width * 0.5, view.height * 0.2, view.width, view.height*0.3)
text_state.flex = 'LRTB'
text_state.font = ('<system>', 18)
text_state.text_color = 'grey'

text_temp = ui.TextView()
text_temp.frame = (view.width * 0.25, view.height * 0.4, view.width, view.height)
text_temp.flex = 'WHLRTB'
text_temp.font = ('<system-bold>', 50)                                                    

view.add_subview(text_state)
view.add_subview(text_temp)
view.present('sheet')

delegate = MyCentralManagerDelegate()
print('Scanning for peripherals...')
text_state.text = 'Scanning'
cb.set_central_delegate(delegate)
cb.scan_for_peripherals()

# Keep the connection alive until the 'Stop' button is pressed:
try:
    while True: pass
except KeyboardInterrupt:
    # Disconnect everything:
    cb.reset()

こちらもgithubにおいた。thermo_client.py

テスト

Pythonista3でtermo_client.pyを実行。
5C5AAD7B-08A1-43DC-93CC-39F265A8BEF1.jpeg
取得成功!!
少し肌寒い温度。

最後に

リモートにする意味あるのかというツッコミは受け付けません。
家の中ではあまり役に立たないが、農場とかでは役に立つかもしれない(省電力だし)。

参考サイト

ubuntuからESP32にbluetooth接続して信号を送受信する方法
cb — Connecting to Bluetooth LE Peripherals
feelfreelinux/ds18b20
【BLEを使う】GATT(Generic Attribute Profile)概要

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18