Slide 1

Slide 1 text

1 M5UnitUnifed M5UnitUnifed M5Stack に 色々なM5ユニットをつないで扱う為の 新たなアプローチ 2024/Sep. GOB (X: @GOB_52_GOB)

Slide 2

Slide 2 text

2 M5UnitUnifed 自己紹介 ● ハンドルネーム GOB (ごぶ)  X: @GOB_52_GOB ● ゲーム業界を中心に活動 ● 30 年以上、有名無名タイトル色々やってました フリーランスとなってからは 20年以上経ちました ● 2020年頃 M5Stack を知り、色々作って遊び始める ゲーム作ったり自作ライブラリ書いたりしているうちに沼へ ● 2024年春、M5Stack 様のお仕事として当ライブラリの作成を始める

Slide 3

Slide 3 text

3 M5UnitUnifed 従来のユニットの扱い方 ● 各ユニット毎に公式、M5製、個人のライブラリを使用して 計測データの取得や設定を行う

Slide 4

Slide 4 text

4 M5UnitUnifed 従来のユニットの扱い方 ● API や設計思想等がまちまちで、それぞれ独自のルールを知ら なければいけない ※特定のライブラリを揶揄するものではありません

Slide 5

Slide 5 text

5 M5UnitUnifed 従来のユニットの扱い方 ● API や設計思想等がまちまちで、それぞれ独自のルールを知ら なければいけない ※特定のライブラリを揶揄するものではありません 開始は begin 値取得は uint8_t GetHoge(); 設定は void SetHoge(const int a); 返り値が特定の値ならエラーとみなせるよ! Wire は begin の中で僕が開始!

Slide 6

Slide 6 text

6 M5UnitUnifed 従来のユニットの扱い方 ● API や設計思想等がまちまちで、それぞれ独自のルールを知ら なければいけない 開始は start 値取得は err_t readHoge(uint8_t& c); 設定は err_t writeHoge(const uint8_t c) 返り値には私独自のエラーコードが返ります Wire は begin 済みのものを頂きたい ※特定のライブラリを揶揄するものではありません 開始は begin 値取得は uint8_t GetHoge(); 設定は void SetHoge(const int a); 返り値が特定の値ならエラーとみなせるよ! Wire は begin の中で僕が開始!

Slide 7

Slide 7 text

7 M5UnitUnifed 従来のユニットの扱い方 ● API や設計思想等がまちまちで、それぞれ独自のルールを知ら なければいけない 開始は start 値取得は err_t readHoge(uint8_t& c); 設定は err_t writeHoge(const uint8_t c) 返り値には私独自のエラーコードが返ります Wire は begin 済みのものを頂きたい API 何か呼んだら開始するだぶー 値取得は void hoge_get(int* p); 設定は void hoge_set(int b); エラーなんか知らないぶー Wire0 を決め打ちで使うぶー ※特定のライブラリを揶揄するものではありませんよ? 開始は begin 値取得は uint8_t GetHoge(); 設定は void SetHoge(const int a); 返り値が特定の値ならエラーとみなせるよ! Wire は begin の中で僕が開始!

Slide 8

Slide 8 text

8 M5UnitUnifed 従来のユニットの扱い方 ● 各ライブラリが I2C 等との通信関数を独自に扱っていて、機能 も性能も異なる ※特定のライブラリを揶揄するものではありません

Slide 9

Slide 9 text

9 M5UnitUnifed 従来のユニットの扱い方 ● 各ライブラリが I2C 等との通信関数を独自に扱っていて、機能 も性能も異なる 外部から関数ポインタで渡してね! それにバグがあっても知らないよ! 仕様? コード見て推測してね! ※特定のライブラリを揶揄するものではありません

Slide 10

Slide 10 text

10 M5UnitUnifed 従来のユニットの扱い方 ● 各ライブラリが I2C 等との通信関数を独自に扱っていて、機能 も性能も異なる 細かい通信制御も可能です もっとも内部では そこまで細かく使っていませんがね 外部から関数ポインタで渡してね! それにバグがあっても知らないよ! 仕様? コード見て推測してね! ※特定のライブラリを揶揄するものではありません

Slide 11

Slide 11 text

11 M5UnitUnifed 従来のユニットの扱い方 ● 各ライブラリが I2C 等との通信関数を独自に扱っていて、機能 も性能も異なる 細かい通信制御も可能です もっとも内部では そこまで細かく使っていませんがね 僕のチップとの間だけで動けばいいんだぶー 適当な実装だけど動いているからいいんだぶー 外部から関数ポインタで渡してね! それにバグがあっても知らないよ! 仕様? コード見て推測してね! ※特定のライブラリを揶揄するものではありませんってば

Slide 12

Slide 12 text

12 M5UnitUnifed 従来のユニットの扱い方 ● かつての M5Core のライブラリ群のようなカオスな状況!

Slide 13

Slide 13 text

13 M5UnitUnifed 統一化(Unifed)しようぜ! M5Core ライブラリ群が M5Unifed (作:らびやんさん)によって統一化され、 便利になったように統一化できないか? 既存プログラム資産には影響を与えてはいけない では新規で作りましょう!

Slide 14

Slide 14 text

14 M5UnitUnifed 統一化(Unifed)しようぜ! ● API を統一化 書式も含めて一貫性のあるものにする ● 通信を統一化 通信部分はユニットによらず共通な物を使う ● ライセンスを統一化 ライセンス感染をさける

Slide 15

Slide 15 text

15 M5UnitUnifed その1 API 統一化 ● ベースとなる親クラス(UnitComponent)を制定し、各ユニット のクラスはその派生として、各ユニットのインスタンスを同様に扱 えるようにします

Slide 16

Slide 16 text

16 M5UnitUnifed その1 API 統一化 ● 個々のセンサーに依存する部分については統一化できませんが、 API 名は系統毎に統一化します ● センサーの値の取得と設定 bool readHoge(uint8_t& val) (センサーの現在値の取得) bool writeHoge(const uint8_t val) (センサーの変化を伴う値の 設定) set()/get()/propertyname() 等はセンサーに影響を受けない/与 えない

Slide 17

Slide 17 text

17 M5UnitUnifed その1 API 統一化 ● 定期計測、データの保持、取得、破棄等を統一化します ● bool startPeriodicMeasurement(Args&&... args) 定期計測開始 (args はユニット毎に異なるパラメータ群) ● bool updated() 計測更新されたか? ● size_t available() 内部循環バッファに蓄積された計測データがいくつ存在する? ● T oldest() 最も古い蓄積データ取得(返却型はユニットによって異なる) ● void discard() 最も古い蓄積データの破棄 ● etc...

Slide 18

Slide 18 text

18 M5UnitUnifed その1 API 統一化 ● 個々のユニットの動作開始(Units.begin時)の初期パラメータ 設定(内容はユニット毎に相違) auto cfg = unit.confg(); cfg.start_periodic = false; cfg.sampling_rate = 100; unit.confg(cfg);

Slide 19

Slide 19 text

19 M5UnitUnifed その1 API 統一化 ● 全てのユニット共通の開始設定 auto ccfg = unitFoo.component_confg(); ccfg.stored_size = 8; // 循環バッファ最大要素数 ccfg.clock = 400 * 1000; // アクセスクロック unitFoo.component_confg(ccfg);

Slide 20

Slide 20 text

20 M5UnitUnifed その1 API 統一化 ● 各ユニットクラスのインスタンスは循環バッファ(初期蓄積可能要 素数は基本的に 1)を持っています ● FIFO を持っているチップ等、初期状態で複数データを蓄積でき る物も存在します

Slide 21

Slide 21 text

21 M5UnitUnifed その1 API 統一化 ● 蓄積データの取得例 while(unit.available()) { // データがある? auto data = unit.oldest(); // 最古のデータ M5_LOGI(“%f,%d”, data.foo(), data.bar()); unit.discard(); // 最古のデータ破棄 } ● この辺りはできるだけ馴染みのある書き方で、使用できるように していきたいと考えています

Slide 22

Slide 22 text

22 M5UnitUnifed その1 API 統一化 ● どのユニットでもこのように書ける(はず) m5::unit::UnitUnifed Units; m5::unit::UnitFoo unitFoo; void setup() { // 初期化済み Wire を使って接続 Units.add(unitFoo, Wire); Units.begin(); // add された unit の開始 } void loop() { Units.update(); // add された unit の更新 if(unitFoo.updated()) { // 計測更新された? M5_LOGI(“%d”, unitFoo.oldest().foo()); //計測された値 } }

Slide 23

Slide 23 text

23 M5UnitUnifed その2 接続統一化 ● 本体とユニットとの接続には多種の方式があります。事前設定 や、扱い方に違いがあり、これもまちまちです。 ● SPI / I2C / GPIO / UART 等、本体とユニット間の接続種別 を意識せず、透過的に使用できるようにするのが目標です 将来的には M5HAL との連携により実現される予定です ● 2024/Sep.現在 TwoWire ベースのみサポート中

Slide 24

Slide 24 text

24 M5UnitUnifed その2 接続統一化 ● 残念ながらPnP(自動検出と自動設定)ではありませんが、実際 の接続同様の構成をソースコード上で記述する事で使用すること ができます ● PaHub/PbHub等、別のユニットを複数接続することが前提と なるユニットとの接続を簡易化、統一化します

Slide 25

Slide 25 text

25 M5UnitUnifed その2 接続統一化 ● 実際の接続状況をそのままのイメージで記述 m5::unit::UnitUnifed Units; m5::unit::UnitPaHub2 unitPaHub; m5::unit::UnitVmeter unitVmeter; m5::unit::UnitTVOC unitTVOC; if (!unitPaHub.add(unitVmeter, 0) /* Vmeter を PaHub2 ch:0 へ接続 */ || !unitPaHub.add(unitTVOC, 1) /* TVOC を PaHub2 ch:1 へ接続 */ || !Units.add(unitPaHub,Wire) /* PaHub を本体へ接続 || !Units.begin() /* M5UnitUnifed 始動 */ ) { M5_LOGE("Failed to add or begin"); }

Slide 26

Slide 26 text

26 M5UnitUnifed その3 ライセンス統一化 ● M5 ではライブラリは MIT ライセンス下で提供されます ● 外部ライブラリは GPL や独自ライセンスのものがあり、商用利 用や、改変に対して不都合なものがあります ● M5UnitUnfed 並びに関連するライブラリは MIT ライセンス 下にて提供します ● チップ公式のクローズドなバイナリを併用する場合は、依存ライブ ラリのライセンスに留意が必要です(e.g. Bosch BME688 BSD-3-Clause)

Slide 27

Slide 27 text

27 M5UnitUnifed その4 その他 ● UnitTest (PlatformIO 上で googleTest による) を関連 ライブラリに搭載し、リグレッションを起こしづらくします ● コードスタイル(書式)を統一化し、読解しやすくします ● Doxygen による API ドキュメントを GitHub Pages にて公 開します

Slide 28

Slide 28 text

28 M5UnitUnifed 現在の M5UnitUnifed ● TwoWire を使用した I2C 接続のみサポート ● 対応ユニット UnitCO2 UnitENVIII UnitENVPro UnitV/Ameter UnitKmeterISO UnitHEART UnitTVOC UnitGESTURE UnitPaHub2

Slide 29

Slide 29 text

29 M5UnitUnifed 現在の M5UnitUnifed ● ライブラリ依存関係 UnitA UnitB Unit... M5UnitUnified M5Utility M5HAL 各ユニットの共通親クラスと ユニット管理クラス 各ユニットのクラス 共通ユーティリティ ハードウェア抽象化レイヤ (開発中)

Slide 30

Slide 30 text

30 M5UnitUnifed M5UnitUnifed を使うには? ● ArduinoIDE m5stack/M5UnitUnifed の GitHub リポジトリへ git pull するか、 zip ファイルをダウンロードして、自分の環境 のライブラリフォルダへ展開しましょう 依存ライブラリ、各ユニット用ライブラリも同様に当該リポジトリ から取得展開してください

Slide 31

Slide 31 text

31 M5UnitUnifed M5UnitUnifed を使うには? ● PlatformIO lib_deps= に、 M5UnitUnifed、 依存ライブラリ、各ユニット 用ライブラリを記述します(GitHub アドレス) 詳しくは各ユニットに付属の platformio.ini を参照

Slide 32

Slide 32 text

32 M5UnitUnifed M5UnitUnifed を使うには? ● ArduinoIDE/PlatformIO ライブラリ登録はβ以降を予定し ています

Slide 33

Slide 33 text

33 M5UnitUnifed M5UnitUnifed を使うには? #include //M5UnitUnifed 管理クラスと親クラス等 #include // 各ユニット毎のクラス m5::unit::UnitUnifed Units; m5::unit::UnitVmeter unit; void setup() { M5.begin(); auto pin_num_sda = M5.getPin(m5::pin_name_t::port_a_sda); auto pin_num_scl = M5.getPin(m5::pin_name_t::port_a_scl); Wire.begin(pin_num_sda, pin_num_scl, 400000U /* clock*/); Units.add(unit, Wire); // 本体に Wire を使って繋ぎますよ Units.begin(); // では開始しましょう } void loop() { Units.update(); // 計測更新 if(unit.updated()) { // 値更新? M5_LOGI(“%f mV”, unit.voltage()); // 値表示 } }

Slide 34

Slide 34 text

34 M5UnitUnifed M5UnitUnifed の将来 ● M5UnitUnifed 未対応ユニットのサポート ● GPIO 接続、 UART 接続のサポート ● M5HAL との連携 ● ESP-IDF での動作サポート ● 本体内臓センサー類の M5UnitUnifed 化 RTC / IMU etc... ● M5Unifed との統合

Slide 35

Slide 35 text

35 M5UnitUnifed M5UnitUnifed の将来 ● こんな感じになると素敵? (あくまでイメージですが) m5::unit::UnitHoge unitHoge{}; void setup() { M5.Units.add(unitHoge, M5.PortA); M5.begin(); // Units も begin } void loop() { M5.update(); // Units も update if(unitHoge.updated()) { M5_LOGI(“%f”, unitHoge.oldest().foo()); } }

Slide 36

Slide 36 text

36 M5UnitUnifed ロードマップ的な何か ● 2024/Sep. α版として公開 ● 2024/Sep. 以降 未対応ユニットの対応作業 これは随時公開していく予定です ● 2024/Sep. 以降 βに向けての作業 どの程度かかるか正直読めていませんが、季節単位で何らかの 大きな修正の反映を行えればと思っております ● フィードバックの反映により、API 名称の変更、構成の変更が今 後十分あり得ます

Slide 37

Slide 37 text

37 M5UnitUnifed リポジトリURL ● M5UnitUnfed https://github.com/m5stack/M5UnitUnifed ● M5HAL (M5UnitUnfed との最低限の連携テスト段階) https://github.com/m5stack/M5HAL ● M5Utility https://github.com/m5stack/M5Utility ● サポートされている各ユニットのリポジトリは M5UnitUnifed README よりたどってください ● 公開準備中、公開時は X などでアナウンスします

Slide 38

Slide 38 text

38 M5UnitUnifed ご清聴ありがとうございます ● 皆様からの忌憚のないご意見、ご要望、ご報告他頂けましたら幸 いです ● 自らの意思を正確に表明できる言語で構いません(日本人であれ ば日本語でおk ジュワ!) ● ユニットに特化した物は各ユニットのリポジトリへの Issue / PR にてお願いいたします ● ユニットによらない場合は、 M5UnitUnifed リポジトリで構い ません Have a happy coding!