MicroPythonの更新状況のウオッチを最近さぼっていたのですが、気がついたら汎用のBLEプロトコルスタックのモジュールが追加されていました。
ESP32でも使用できるようになっているので、試してみました。
このモジュールはソースツリーの中ではextmodの中に入っていて、ファイルシステムやlwIP等と同じく、プラットホーム非依存なモジュールの位置づけになっています。
もちろん、デバイス部分はプラットホームに依存しますのでプラットホーム側での対応は必要です。
ESP32用MicroPythonでは、ESP-IDFのv4.0系ビルドで対応しています。
というわけで、まずはビルドしてみました。
ESP-IDFのv4.0系はExperimentalであるため、これまではv3.0系でビルドしていたので、まずESP-IDFを更新します。
私は以前導入した開発環境を流用したため、ビルド手順の詳細は端折りますので、詳しくは公式のREADMEを参照してください。
ESP-IDFはバージョンアップが激しいため、MicroPythonでは特定のリビジョンを使用します。
リビジョンの情報はMakefileに書かれていますので、そのリビジョンをcheckoutします。
$ cd micropython $ grep IDF ports/esp32/Makefile | head -5 # the git hash of the currently supported ESP IDF version ESPIDF_SUPHASH_V3 := 6ccb4cf5b7d1fdddb8c2492f9cbc926abaf230df ESPIDF_SUPHASH_V4 := 310beae373446ceb9a4ad9b36b5428d7fdf2705f $(info Supported git hash (v3.3): $(ESPIDF_SUPHASH_V3)) $(info Supported git hash (v4.0-beta1) (experimental): $(ESPIDF_SUPHASH_V4))
ここで表示されたESPIDF_SUPHASH_V4
の値(上記では”310be…”)を以下のgit checkout
のパラメータで与えます。
$ git clone https://github.com/espressif/esp-idf.git $ git checkout ESPIDF_SUPHASH_V4 $ git submodule update --init --recursive
ESP-IDFの準備はこれで完了です。
MicroPythonをビルドします。
先にmpyクロスコンパイラをビルドしておきます。
$ make -C mpy-cross
次にESP32用MicroPythonをビルドします。ここではDevKit-C用なのでボードはデフォルトの”GENERIC”を使用しています。
$ cd ports/esp32 $ make clean $ make
ビルドが完了したら、DevKit-Cを接続してファームウェアを書き込みます。
$ make deploy
なお、ビルドにはPython3とpyparsingパッケージのバージョン2.4未満が必要です。
私の環境(Ubuntu 16.04)ではPython2系がデフォルトだったので、ビルドに先立ってvenvを設定しました。
$ python3 -m venv venv $ source venv/bin/activate $ pip install --upgrade pip $ pip install pyserial 'pyparsing<2.4'
では試用してみます。
>>> help('modules') __main__ flashbdev select upip_utarfile _boot framebuf socket urandom _onewire gc ssl ure _thread hashlib struct uselect _webrepl heapq sys usocket apa106 inisetup time ussl array io ubinascii ustruct binascii json ucollections utime bluetooth machine ucryptolib utimeq btree math uctypes uwebsocket builtins micropython uerrno uzlib cmath neopixel uhashlib webrepl collections network uhashlib webrepl_setup dht ntptime uheapq websocket_helper ds18x20 onewire uio zlib errno os ujson esp random uos esp32 re upip Plus any modules on the filesystem >>>
"bluetooth"モジュールがありますね。(無ければビルドがどこかで失敗しています。)
モジュールに関するドキュメントは以下にあります。
ubluetooth — low-level Bluetooth — MicroPython 1.11 documentation
私はBLEについては以前koshianを使ってみたことがあるくらいで、あまり詳しくないのですが、今回は、MicroPythonのmicropython/examples/bluetooth
ディレクトリにサンプルが2つ入っていますので、これを試してみました。
事前に、このディレクトリにある
・ble_advertising.py
・ble_uart_peripheral.py
・ble_temperature.py
・ble_uart_repl.py
の4つのファイルをESP32に転送しておきます。
◆サンプル1:温度センサ
ESP32がBLE接続のセンサになり、スマホなどから値を読み取ります。
ただし、サンプルなので温度の値は実際に測定しているわけではなく、ランダムに変動します。
読み取り側のアプリとしては、Android用の無料アプリ「nRF Connect」を使ってみました。
nRF Connect for Mobile - Google Play のアプリ
ESP32側で'ble_temperature.py'
を実行します。
>>> exec(open('ble_temperature.py').read()) [0;32mI (18740) BTDM_INIT: BT controller compile version [a482cda][0m [0;32mI (38101) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE[0m [0;32mI (38201) phy: phy_version: 4102, 2fa7a43, Jul 15 2019, 13:06:06, 0, 0[0m GAP procedure initiated: stop advertising. GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=800 adv_itvl_max=800
これでESP32側ではサーバが起動しています。
nRF Connectから、スキャンするとmpy-tempというBLEデバイスが見つかります。
CONNECTをタップして接続し、CLIENTタブを見ると「Environmental Sensing」というサービスが見つかるはずですので、さらにこれをタップします。
すると、「Temperature」という項目があり、タップすると温度の値が表示されます。
この値は1秒おきに更新されていきます。
◆サンプル2:UART
BLEで接続できるUARTポートを生成し、そのUARTポートにos.dupterm()
でREPLを接続します。
対向で通信するアプリとしては、Adafruit製の「Bluefruit」を使った、とソースコードに書かれているので、そちらを使用しました。
検証はAndroid版で行ったとありますが、このアプリはiPhone版もあります。
Adafruit Bluefruit LE Connect - Google Play のアプリ
Adafruit Bluefruit LE Connect on the App Store
以下のスクリーンショットはiPhone版です。
まず、ESP32側で'ble_uart_repl.py'
を実行します。
このモジュール内のstart()を実行すると、dupterm()を使ってBLE UARTにREPLが接続されます。
>>> import ble_uart_repl >>> ble_uart_repl.start() [0;32mI (36580) BTDM_INIT: BT controller compile version [a482cda][0m [0;32mI (46938) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE[0m [0;32mI (47048) phy: phy_version: 4102, 2fa7a43, Jul 15 2019, 13:06:06, 0, 0[0m GAP procedure initiated: stop advertising. GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=7 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=800 adv_itvl_max=800 >>>
Bluefruitを起動し、スキャンすると「mpy-repl」というデバイスが見つかるので、タップします。
CONNECTし、UARTをタップします。
するとターミナルエミュレータの画面に変わりますが、ここでまず改行コードの設定をします。
デフォルトは\n
ですが、\r\n
または\n\r
に設定する必要があります。
これでスマホからBluetooth経由でREPLにアクセスできます。
下の画面は"help()"と入力したところです。
参考リンク:
micropython/ports/esp32 at common-ble-api-esp32-nimble · jimmo/micropython
Common BLE API by jimmo · Pull Request #5051 · micropython/micropython
esp32: BLE support using Nimble by jimmo · Pull Request #5171 · micropython/micropython
コメント