Kick Out the World

技術的なメモとかポエムを書きます。

【Moddable】manifest.jsonで定義した値が適用されているか確認する

manifest.jsonconfigdefine といった設定値が定義されていますが、Exampleのアプリケーションを動かしてたり、新しいボード対応とかをしていると、ここで定義した値通りに動いてないのでは、みたいな場面に遭遇することが稀によくあります。

ということで、いくつか確認できたものを例に紹介する

確認する場所

mcconfig コマンドでビルドされた生成物は以下フォルダに格納されている。 ${MODDABLE}/build/tmp/$(platform)/$(subplatform)/debug/$(Application)

esp32/m5stackhelloworldアプリを動かしたなら moddable/build/tmp/esp32/m5stack/debug/helloworld

結論としてはここにあるヘッダファイルが自動生成され、ビルド時に参照される。

define

例えば以下のようにI2Cのデフォルトsda,sclピンとかが定義されていると、

"defines": {
    "i2c": {
        "sda_pin": 21,
        "scl_pin": 22
    }

mc.defines.hのヘッダファイル内で以下のような定義に自動生成される。

#define MODDEF_I2C_SDA_PIN (21)
#define MODDEF_I2C_SCL_PIN (22)

この定義はmodules/pins/i2c/esp/modI2C.cで参照されており、I2Cコンストラクタでsda,sclが指定されていない場合のデフォルト値として利用されていることがわかる。

#if defined(MODDEF_I2C_SDA_PIN) && defined(MODDEF_I2C_SCL_PIN)
    conf.sda_io_num = (-1 == config->sda) ? MODDEF_I2C_SDA_PIN : config->sda;
    conf.scl_io_num = (-1 == config->scl) ? MODDEF_I2C_SCL_PIN : config->scl;
#else

config

アプリケーションで利用する際にはimport config from "mc/config";でインポートして参照する設定値。

"config": {
    "screen": "m5stack/screen",
    "rotation": 90,
    "touch": "",
}

mc.config.jsを見たらだいだい見たまんま

mc.rotation.h

画面出力する場合は本ファイルで定義されるkPocoRotationが画面の向きを決定する。実際この値が変わると参照しているcommodettoやpiuは再ビルドが走る。

ここに適用される値は、config.rotaionが適用されるが、mcconfig-rオプションを指定していた場合はその値が優先される。

複数のmanifest.jsonで同じ定義が衝突したとき

ApplicationやPlatformやModuleごとに定義されるmanifest.jsonファイルで同じ定義がされていた場合は、(恐らく)定義が読み込まれてた順で後勝ちになっていそう。

例えばM5stackのアプリケーションでexamples/manifest_base.jsonを読み込んだ場合は、 includeで以下のように辿って読み込まれていく。

(アプリケーションのmanifest.json)
┗ $(MODDABLE)/examples/manifest_base.json
  ┗$(BUILD)/devices/esp32/manifest.json
  ┗$(BUILD)/devices/esp32/targets/m5stack/manifest.json
   ┗(以下略)

ただし、includeで先読みしてくため、下から上に向かってdeinfeやconfigは読み込まれていく(アプリケーションのmanifest.jsonでで定義したものが最終的に後勝ちになる)ので、意図しない定義値が適用されているときは、manifestの読み込み順にも注意したほうがよい。

まとめ

Platformで定義した値をSubPlatformで上書きできない点がモヤモヤする(嵌った)ところですが、意図する値となってないと思ったら値を確認してみましょう。

M5Stack×Moddable入門その3~人感センサーユニットを動かす

今回はPIRセンサーユニットで人感を試してみました。 買ったのは以下のM5stack用のやつ。

www.switch-science.com

ユニットを接続する

当然Modabbleにドライバがなかったので、製品ページを見ているとI2Cインターフェースではなく、GroveをポートBに刺してGPIOから値が取得できる、と書いてあるが、手元のM5stackGrayにはGroveポートがI2C用の1つしかない。

どうもFIREやGOには3つのGroveポート(Aポート:I2C、Bポート:I/O、Cポート:UART)がついているようだ。こういう配線したくなくてM5stackを選んだにミスったなと感じつつ、自分でジャンパワイヤーを刺して接続します。

Modabbleで実装

GPIOから人感のオン・オフのデジタル入力を読み取るだけなので、確かにドライバはいらなさそう。

デジタル入出力に関してはbuiltin/digitalがあるので、使えそーじゃんと思って使ったら、まだ標準仕様を策定中でESPでしか使えないExperimentalの状態でした。

今回はデジタル入力なので、これってボタン入力と同じじゃね?ってことに気づきM5stackのsetupスクリプトにあるButtonクラスと同じ感じつくればよさそう。

moddable/setup-target.js at public · Moddable-OpenSource/moddable · GitHub

ってことで動きました。

あと、人感を試すためにM5stackを設置する上でスマホ用の撮影スタンドが便利でした。

ソフトウェア見積り 人月の暗黙知を解き明かす を読んだ

ちょうどこの前のkindleセールだったので買って読んだ。

  • 見積もり、ターゲット、コミットメントの違いを理解すること
  • シングルポイントの見積もりではなく、幅のある数値の見積もりを。ビジネスにとっては予測可能性が重要
  • できの悪い見積もりは将来の見積もりを縛る傾向がある
  • 最良と最悪の両ケースの見積もりをすることで起こりえるすべての範囲の結果を考えるきっかけとなる
  • 過少見積りの不利益は限界がないので、意図的な過少見積もりをすべきではない
  • スケジュールが切迫して開発者にストレスが及ぶと品質は落ちる
  • 不確実性のコーン(ソフトウェア定義が詳細化するにつれて見積もりのばらつきは小さくなる)
  • 見積もりも重要だけどプロジェクトコントロールも重要
  • 開発者は楽観的な見積もりをしてしまう
  • 規模の不経済(ソフトウェアは規模が大きくなるほどコストが大きくなる)
  • 開発対象の特性によって生産性は変わるし、規模によっても変わる
  • 大きなプロジェクトでは個人の力量よりもプロジェクトマネジメント(特にリスクマネジメント)が重要
  • 政治的圧力のかかった見積もりをさけるために過去データを利用する
  • 分解して見積もりした際の「大数の法則(1つ1つの見積もり誤差が打ち消しあって結果全体誤差が小さくなる)」
  • 複数の見積もり技法や指標を使い結果を比較する

単に定量的指標を使ってPDCAしろみたいな一辺倒なアプローチではなく、見積もりとは何なのか、数値をどう見るのか、みたいな視点が広がるかと思います。

M5Stack×Moddable入門その2.5~ディスプレイが色反転していた件について [20200901追記]解決した

そろそろPiuでUIで書くかー、とdocumentを見ながら動かしていたら、指定した色通りに表示されていないことがわかった。

今までLabelに1行の文字列だけ表示させていたので、白黒が判定したことさえ気づいていなかった。 意味分かんないな、とググっていたところ、M5StackのディスプレイはILI9341 から ILI9342Cに変わっていた。

www.mgo-tec.com

と ILI9342C のデータシートを見てみると、色反転に関するレジスタコマンドは、 Display Inversion OFF ( 0x20 ) Display Inversion ON ( 0x21 ) です。

とあり、どうも0x21に対してコマンドを送ってやる必要がありそう。 また、新旧のディスプレイに対してうまくやっているというコードもM5stack本家のドライバに見つかり、初期化処理でコマンドを叩くという解決策で合っていそう。

https://github.com/m5stack/M5Stack/blob/master/src/utility/In_eSPI.cpp

#ifdef M5STACK
  if (lcd_version) writecommand(TFT_INVON); // TFT_INVONが0x21
#endif

肝心のModdable対応については、$(MODULES)/drivers/ili9341/modIli9341.c のドライバにて初期化処理っぽいところに色反転のコマンドを追加した。

void ili9341Init(spiDisplay sd)
{
        // (省略...)

        ili9341Command(sd, 0x21, NULL, 0); // この行を追加
        sd->firstFrame = true;
}

解決策合ってるか分からんが解決はした。

manifest.jsonに書くii9341のdefines当たりで切り替えるか、本家みたいに動的に切り替えれるとよさそうが、現状の力では及ばずhot-fixです。

Moddalbe始めてからC言語ばっかり読んでるな。。。

(2020/07/09 追記) PiuでUIを書き始めて気づいたのだが、どうもシミュレータで表示される色と実機ディスプレイで見える色がだいぶ違う。 下記はorange(#ffa500)で塗りつぶした結果。

全般的に明るく表示されている気がする。

Mobbableのディスプレイドライバの問題が切り分けるためにArudionoIDEでM5stack公式のライブラリを使ってみたが結果は同じだった。

[20200901追記] ModdableのGithubでissuesを挙げたところ、m5stack用のディスプレイクラスのラッパーとディスプレイクラスにコマンドを送れるように拡張してもらったので、修正なしにうまく表示されるようになりました。

github.com

M5Stack×Moddable入門その2~I2Cでバッテリー情報を読み取る

センサー情報とかを取得する練習としてバッテリー残量をとってみることにした。起動していてイマイチ残量がわからないというのもあったので。

IP5306

M5stackにはIP5306という電源制御モジュールが搭載されており、schematicを読んでいるとI2C通信ができるようにカスタマイズされたものが搭載されているようだ。

Power Management IC (IP5306) is customized I2C edition,its I2C address is 0x75. Clickhere to check IP5306 datasheet

ということで、この0x75アドレスに対してIC2通信をしてみる。 レジスタの情報とかはリンクされているデータシートを読んでみることにしたが中国語だった。

どうもバッテリー残量を取得できるレジスタ情報の記載がなく困っていたが、色々と紆余曲折もありつつ最終的にはM5stack公式のリポジトリにIP5306にアクセスするコードがあったので、これを参考にすることにした。

M5Stack/Power.cpp at master · m5stack/M5Stack · GitHub

結局は自分でデータシートと格闘するよりも既存のCやC++のデバドラ探してきて移植したほうが楽そうである印象。

Moddableとしての実装

I2C通信するドライバを作成するにあたっては、他のModdableのリポジトリにあるドライバのコードを見てながら真似てみた結果、I2Cクラスを拡張して、IP5306と通信して情報取得するドライバを作ることができた。

I2C通信先のアドレスとレジスタのアドレスおよび読み取った値のビットマスク方法が分かっていれば、特に難しいことはなさそう。

ということで3つのボタンにそれぞれ、充電中か否か / フル充電か否か / バッテリー残量 を取得する処理を割り当てて表示するものができあがった。

フル充電状態はなぜか取れないけど、残量が分かればまぁいいでしょう。

おまけ:起動音を消す

起動時の音が結構うるさい。

%MODDABLE%/build/devices/esp32/targets/m5stack/setup-target.jsに機器固有の初期処理が書いてあるので、鳴動処理をコメントアウトすることで解消された また、このファイル中で、ディスプレイ下に配置された3つのボタンをピン番号を指定してglobal.buttonとして登録されている

M5Stack×Moddable入門その1~M5stackにサンプルを焼いてみる

M5stack到着

今回買ったのは

www.switch-science.com

M5StackGray。Amazonでスイッチサイエンスから購入。

環境構築

焼きこむための環境構築を進めていく。

github.com

やったことはざっくり以下通り

  1. ドライバをインストール
  2. ツールチェイン類をインストール
  3. ESP-IDFをリポジトリからクローン
  4. M5stackをホストPCに接続
  5. Pathを通す
  6. 環境変数UPLOAD_PORTESP32_CMAKEを設定
  7. サンプルを起動
cd %MODDABLE%\examples\piu\balls
mcconfig -d -m -p esp32/m5stack

pythonのパッケージが古いとか言われて失敗したので、エラーメッセージに従い以下を実行してパッケージインストール よくよく見るとTroubleshootingにも書いてた。

python -m pip install --user -r %IDF_PATH%\requirements.txt

おまけ:manifest を追っかける

書き方自体はここ参照

github.com

Eamplesとかを見る限りは、$(MODDABLE)/examples/manifest_base.jsonとかを使いまわすのがよさそう。

M5Stack向けにビルド(-p esp32/m5stack)する構成を諸々端折って追っかけると、

$(MODDABLE)/examples/manifest_base.json
 ┗$(BUILD)/devices/esp32/manifest.json
 ┗$(BUILD)/devices/esp32/targets/m5stack/manifest.json // M5stack自体の設定
  ┗$(MODDABLE)/modules/drivers/ili9341/manifest.json // ILI9341液晶の設定

となっているので、わざわざピン番号とか機器固有の設定を調べて書く必要はなさそう。

M5Stack×Moddable入門その0~環境構築・シミュレータ起動

マイコンでの電子工作には興味があったものの、C/C++を書くことに苦手意識がありなかなか手が出せていなかったのですが、JavaScriptでも書けることが分かってきたため、この度M5Stack×ModdableでJavasSriptを使った電子工作に挑戦してみたい。

Moddable 選定について

まず今回使用するModdable以外にもobnizやJohnny-Fiveといったプラットフォームを使うことでJavaScriptによるマイコン制御ができるのですが、

obniz

obniz.io

一意のobnizライセンスが付与されたマイコンをインターネット接続することにより、クラウド上よりプログラムの実行が可能。 クラウド経由の実行となるため、環境構築の手間は最も手軽に思われる一方、実行に当たってはマイコンがインターネット接続されていることが前提となってしまうため、マイコン単体で動いてくれないことに微妙さを感じる

Johnny-Five

johnny-five.io

npmインストールするだけのため、これも環境構築の手間は手軽そうであるが、プログラム実行に当たってはホストマシンと接続しないといけないため、これもまたマイコン単体で動いてくれないことに微妙さを感じる

Modabble

www.moddable.com

これまでの2つと違ってマイコン単体でも動きそうだし、シミュレータやデバッガもありそうなので、なんとかなりそう。 日本語の情報は少なさそうだが、前述2つも少ないので、頑張って公式のドキュメントやサンプル見るか、という機運

環境構築

公式のGetting Startedを見て進める。

moddable/Moddable SDK - Getting Started.md at public · Moddable-OpenSource/moddable · GitHub

今回はWinows10 HomeをホストPCとして進めました。 やったことは大まかに以下通り。特に嵌りどころも無かった。

  1. Visual Studio 2019 (Community Editionでよし)をインストール。その時C++のよるデスクトップ開発もインストール。
  2. Moddableのリポジトリをクローン
  3. 上記クローン先にパスを通す
  4. VSのコマンドラインツールでビルドする
  5. シミュレータが動くようになるので、サンプルのhelloworldを動かす(立ち上がるがコンソールのほうにheloworldと出るだけ。。あまりに面白みがないので"examples\piu\balls"を動かした

次回はM5Stack到着後に。

(2020/06/28 23:00追記)

mcconfig

ビルドやプログラム実行時に打つmcconfigコマンドについては以下に詳細が記載されているので、軽く読んでおくと何をしようとしてるか分かるので安心。

github.com

上記にも記載されているが、$MODDABLE/buildに生成物が格納される。 XSリンカー?がmakeファイルやCファイルを吐いて、コンパイルされていそう

$ ls makefile mc.exp mc.resources.c mc.xs.c modInstrumentation.c.o modTime.c.o modTimer.c.xsi Resource.c.o screen.c.o timer.c.o mc.config.js mc.format.h mc.resources.o mc.xs.h modInstrumentation.c.xsi modTime.c.xsi modTimer.h.xsi Resource.c.xsi screen.c.xsi timer.c.xsi mc.defines.h mc.lib mc.rotation.h mc.xs.o modInstrumentation.h.xsi modTimer.c.o modules/ resources/ screen.h.xsi