M5Paper と画像表示

ついに画像表示機能が出来上がりました。
https://github.com/ikedam/m5paper-ikedamclock/releases/tag/v0.3.0

出来上がったものの詳細はこちら: イケダム in イケダム時計
ミニダム1日1絵でアップした画像をサーバーに置いて、
それをランダムで返す CGI
をサーバーに置いて、定期的にアクセスして画像を表示しています。

M5Paper には SDK でオンラインの画像を表示する API があるのですが、「指定の URL の JPEG を表示する」「指定の URL の PNG を表示する」という形になっています。
イケダム時計では JPEG, PNG 混在でサイトで画像を出力するので、アクセスするまで画像が JPEG、PNG が分からず API が使用できません。
このため、これらの API が使用している TJpgDec, pngle を直接使うこととなりました。これらのライブラリはデータを読み込ませると、コールバックでピクセルの情報が返ってきます。それに対して API で提供される描画処理 (fillRect) を呼べば良いというわけです。
副産物として、SDK 標準の JPEG 画像表示の API は画像の表示サイズを任意サイズに伸縮させられなかったのですが、描画処理を自分でやるので、そこも自由にできるようになりました。

伸縮処理は単純に座標と幅を目的のサイズに単純変換して行っています。多分バイリニアと呼ばれる手法のはず。
基本的に表示する元画像は M5Paper の画面サイズよりもずっと大きいので、縮小して表示されます。
そうすると元画像の異なるピクセルが、M5Paper の画面上の同じピクセルに被ることになります。
単純に後勝ちで上書きしていっているので、縮小処理としてはかなり雑なことになります。
本当は重ね塗りされた色のマージなどが必要だと思います。
ただ見た限り、特に違和感なく表示できています。
きっと1日1絵の画像がそこまで精密でないということによる功績でしょう。

画像データはインターネットからダウンロードしつつ、適宜ライブラリに流し込んで描画処理を行うという形になっています。
つまり一度全部読み込んだ後、ライブラリにわたすという作りにはなっていません。
本当は一度全部読み込む方式にしたのですが、メモリが足りなくてクラッシュしました。
画像ファイルが 1MB あるのに対して、eps32 のメモリは 520 KB とのことです。
これはとても足りないですね。
TJpgDec, pngle は組み込み用に設計されているので、画像データがすべて同時にメモリに置かなくてもストリームで処理できるような設計になっているようです。

※最初は WiFi の接続の通知があったら、その通知のコールバック内で画像を読み込もうとしたのですが、さらにもっと手前の段階でクラッシュしました。
コールバック類は別スレッドで呼ばれて、スタック領域が小さいみたいです。
コールバックでは接続状態の更新のみ行い、メインループで接続状態の検知を持って画像の描画を行うようにしました。

その後調べたところ、 PSRAM という仕組みがあって、ビルドの設定を適切に行えば外付けのメモリを使えるみたいです。
M5Paper には 8MB くらい積まれているらしい。
platformio.ini の build_flags で -DBOARD_HAS_PSRAM と -mfix-esp32-psram-cache-issue を指定すればいいみたい。
試していなけれど。


なおダウンロードした画像の展開処理には 40 秒くらいかかっています。
「毎分表示する時間を更新する」という時計の役目から考えると結構ギリです。

M5Paper とフラッシュメモリ

「SPIFFS で平文ファイルを暗号化して保存し直してるけれど、コレ実はもとのファイルの内容がフラッシュメモリ上に残ってるんじゃね?」
疑惑について検証することにしました。

まずはフラッシュメモリの中身はパーティションに分割して使われているのですが、どういうパーティション構成になっているか確認しよう…とすると、どうもそういうツールが無いようです。
仕方ないので、M5Paper 自身にパーティション構成をシリアルから出力させるツールを作りました:
https://github.com/ikedam/m5paper-test/tree/list-partitions

こんな感じの出力が得られます:

APP partitions:
label type subtype encrypted address-start address-end size:
app0 00 10 0 0x010000 0x650000 6553600
app1 00 11 0 0x650000 0xc90000 6553600
DATA partitions:
label type subtype encrypted address-start address-end size:
nvs 01 02 0 0x009000 0x00e000 20480
otadata 01 00 0 0x00e000 0x010000 8192
spiffs 01 82 0 0xc90000 0x1000000 3604480

そして SPIFFS となっている領域をファイルにダンプします。
esptool というのがあるはずなのですが見当たらないので探し回った結果、
QUICK ACCESS > Miscellaneous > PlatformIO CoreCLI から CLI を起動して

cmd
python %USERPROFILE%\.platformio\packages\tool-esptoolpy\esptool.py --port COM3 read_flash 0xc90000 3604480 spiffs.dat

でダンプします。
ダンプしたファイルをテキストエディタで開くと、平文のパスワードが残っていることを発見。


ついでに、「WiFi を使うと NVS に ESSID とパスワードが保存されてしまう」という話もみたので、 NVS をダンプするツールも作りました。
nvs_entry_find() という API でできるのですが、なぜか Arduino 向けのライブラリには含まれていないので、 ESPIDF というのでやります。
platformio.ini 的には

-framework = arduino
+framework = espidf

と変更すれば良いようです。(実際にはこの他に CMakeFile.txt などもあるのでウィザートから新しくプロジェクトを作り直したほうがいい)

https://github.com/ikedam/m5paper-test-espidf/tree/dump-nvs

ダンプしてみると

(1394) app: nvs.net80211:sta.ssid (42)
(1404) app: 13 00 00 00 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 00 00 00 00 00 00 00 00 00 00 00 00 00
(1414) app:
(1414) app: nvs.net80211:sta.pswd (42)
(1424) app: xx xx xx xx xx xx xx xx xx xx xx xx xx 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(1444) app: XXXXXXXXXXXXX
...
(1544) app: Setting:ssid (21)
(1544) app: XXXXXXXXXXXXXXXXXXX
(1554) app: Setting:pswd (21)
(1554) app: XXXXXXXXXXXXX

とバッチリとパスワードが含まれています。 (xx や X としているのは伏せ字)

nvs.net80211 ネームスペースの sta.ssid と sta.pswd をキーにしているのが WiFi ライブラリのようで、
Setting ネームスペースの ssid と pswd は M5Paper_FactoryTest が保存するもののようです。なんてものを保存するんだ。


フラッシュメモリにパスワードがまんま入っているというのもアレなので、一度 Flash をリセットします。

python %USERPROFILE%\.platformio\packages\tool-esptoolpy\esptool.py erase_flash

また、ファイルの暗号化は、暗号化済みのファイルを登録すればいいので、先程ダンプした SPIFFS のイメージを
https://github.com/igrr/mkspiffs
を使って展開して、暗号化済みのファイルを直接登録します。

WiFi のパスワードについては
https://github.com/ikedam/m5paper-ikedamclock/blob/v0.2.0/src/ikedam_clock.cpp#L229
の通り

WiFi.persistent(false);

を設定すれば保存されないようです。

イケダム時計を動かした後、再度先程のツールで NVS をダンプすると

(400) app: nvs.net80211:sta.ssid (42)
(410) app: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
(420) app:
(430) app: nvs.net80211:sta.pswd (42)
(440) app: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
(460) app:

という具合に設定されていないことが確認できました。

M5Paper と NTP

ということで WiFi も接続できたので次は NTP へ。

この NTP 機能、 ntpdate みたいな実行するとその場で一回限りの時刻同期をするものなのかと思ったけれども、実際には一度動かすとバックグラウンドで動いて毎時同期するものらしい。
バッテリーのことを考慮して毎時都度 WiFi 接続して NTP で時刻同期することを考えていたのだけれど、それをやると逆に面倒くさそう。

あと、いろんな資料を見ると、
* WiFi の接続成功をポーリングで待つ
* NTP の処理を始めたらあとはほったらかし

という実装が主なのだけれど、M5Paper の時計への設定処理は自前でやらないといけないこともあって、いちいちポーリングをしないといけなくて面倒くさい。
ということで、最終的に以下の実装に:

* WiFi.onEvent でコールバックを登録して、WiFi 接続完了を検知。
* WiFi 接続完了を検知したら、NTP を開始。
* sntp_set_time_sync_notification_cb で、 NTP の同期完了イベントを受け付けるコールバックを登録。
* 同期完了イベントを受け取ったら時刻を設定。
* イケダム時計は裏で行われているそういう処理のことは気にせず勝手に動く。

NTP の利用は多くの資料で configTime() を使うということになっているのだけれど、それとは別に低水準の API sntp_xxxx のシリーズがあるようで、どうもさらにその sntp_xxxx も二系統あるように見えて(ヘッダファイルが別)、どうにもよくわからない。
が、とりあえず上記でなんとなく動いた。

なお、当初 sntp_set_time_sync_notification_cb で登録して呼び出されたコールバックから直接 M5.RTC.setTime() 等を呼び出していたのだけれども、どうもちゃんと時刻が設定できない問題があった。
どうやら loop() 側でも M5.RTC.getTime() を呼んでいたので、それとかち合ったみたい。
loop 以外で時計にアクセスするとやばい、ということだと思うので、コールバック側では呼び出し時点の millis() を記録して、 loop() 側で millis() の差分を補正しつつ時刻を設定する、という対処とした。

ちなみに M5Paper には時計用の RTC チップというのが積んであってそれを使っているのだけれども、どうも ESP32 自体にも時計がついているみたいでそっちは NTP で自動設定されるみたいなので、M5Paper の RTC チップは実は使わなくてもよいのかもしれない。


ということで WiFi と NTP に対応したイケダム時計。
https://github.com/ikedam/m5paper-ikedamclock/tree/v0.2.0

M5Paper と WiFi

イケダム時計が一度バッテリーが切れて再起動すると、ひたすらおかしな時刻を指し示しているのが気の毒になってきたので、NTP に対応することにするのでした。
NTP を使うにはもちろんインターネット接続が必要で、 WiFi を使うことになります。

いまやぼくの中で聖典になっている m5paper-dashboard では WiFi へ接続するための ESSID とパスワードがソースコードに直書きになっているのだけれど、コード内にパスワードを書いてうっかり Github にアップロードすると大惨事なので、とここは変えたいなあと思って調べました。

SmartConfig という方法があって、設定待機モードに入って Android アプリの SmartConfig か iPhone アプリの Espressif Esptouch というアプリで無線設定ができるらしい。
のだけれど、これどういう仕組でスマホアプリからM5Paperに無線の情報を送るのかがイマイチ分からない。
M5Paper が一時的に AP になってそこにつなぎに行って、そこで無線の情報を送る…ということじゃないかなという気はするけれども、ちゃんとその辺の説明をしている資料が見つからない。
平文で送っていると書いてあるページもあったりして、うさんくさく感じたのでとりあえず今回は見送り。
(試してもいない)

M5Paper_FactoryTest では WiFi のアクセスポイントをリストアップして、選ぶとパスワード入力画面に行って…とできる画面があるので、それを流用できればいいのだけれど、なにぶん、再利用可能な形のコードになっていないのでした。
自前で UI を作ると大事業になるので、とりあえずは M5Paper の UI 上でアクセスポイントを選択できるようにするのは将来の目標にして、ソースコードには含めない形で設定をアップロードする、という方針としました。

M5Paper が使っているチップの esp32 のシリーズには SPIFFS という eps32 組み込みの Flash 領域をファイルシステムとして使えるようになっているので、以下の方針としました:

* PC から、ESSID とパスワードを書いたファイルを SPIFFS にアップロードする。
* イケダム時計は SPIFFS から WiFi への接続情報を読み込む


ただやっぱり WiFi のパスワードを平文で Flash に置くのは避けたいなあ…
と思って、なんとかならんかーというのも調べました。

少し調べると、パスワードを書かずに、ESSID とパスワードから計算される PSK (Pre shared key) を計算して書くという方法を案内している方もいるけれども、これってこの PSK を使ったら WiFi には接続できるわけで、意味ないんじゃないのかなあ。

最終的に、esp32 で暗号化を行う関数 esp_aes_crypt_cbc というのが提供されていることが分かったので、これで暗号化することとしました。

* PC から、ESSID とパスワードを書いたファイルを平文で SPIFFS にアップロードする。
* イケダム時計は SPIFFS から WiFi への接続情報を読み込む
* 設定情報が平文だったら、esp_aes_crypt_cbc() で暗号化して保存し直す。
* 設定情報が暗号文だったら、esp_aes_crypt_cbc() で複号して使う。


こんな感じの動作。

「保存し直す」とやったときに、前回の平文のデータがちゃんと上書きされているのか…は不明。

M5Paper と家庭内予算

なにげに

M5Paper 自体の購入費用よりも

M5Paper 関係で買った書籍

の合計費用のほうが高くついているのであった。

家庭内予算に暗雲が立ち込めるのであった。

M5Paper と ikedamclock v0.1.0

https://github.com/ikedam/m5paper-ikedamclock/tree/v0.1.0

TrueType フォントでの時計と固定画像を表示するようにしたもの。

ikedamclock ver0.1.0

いろいろ分かったこと。

* EInk の表示は結構遅い。しかも M5EPD では表示処理がブロックするため、全体の処理が目に見える動作になる。多分、EInk のデバイスのせいだと思うんだけれど、もしかすると TrueType の処理のせいかもしれない。
* ttf ファイルが使えるが、表示するフォントサイズを決めて Renderer を作成する必要がある。好きなときに好きなサイズで、というわけにはいかないようだ。
* 指定したフォントサイズに対して、描画領域がそれよりも大きい。特に文字の上部にスペースができる。余白のために思ったよりも小さく表示される、ならばともかく…。原因がよくわからない。とりあえず一定割合のマージン処理を入れて回避。
* M5EPD_Canvas というクラスがあって、フォントの読み込みはそのインスタンスメソッドとして提供される。EInk の特性に合わせてディスプレイの表示を複数のブロックに分けて管理できるように存在しているクラスなのに不便だなあ、と思ったら、どうやら実態としてフォントはグローバルで保持していて、キャンバスで共有らしい。API 設計にやや不便がある。
* ミニダム1日1絵 をランダムで表示する計画だったが、Twitter の画像はプログレッシブ JPEG で、 ESP32 のライブラリで提供している tjpgdec ではサポートしていない。ざっと見た限り、組み込み向けでプログレッシブ JPEG をサポートしているライブラリはなさそう。
* tjpgdec では画像サイズのスケーリングは 1/2, 1/4, 1/8 ... しかできないので、任意の領域にジャストフィットさせる、ということができない。LovyanGFXであれば読み込んだスプライトを任意の領域にスケールして貼り付けることができそうなので、いまから LovyanGFX に乗り換えるべきか。ただ LovyanGFX は直接 ttf ファイルを扱えないようなので、そのへんは作業が必要。

M5Paper と TrueType フォント

M5EPD 内に FreeType のライブラリが含まれていることが判明したので、
LovyanGFX の IFace のサブクラスを作って TrueType フォントが使えるんじゃない? と思い立ちました。

FreeType のチュートリアルを読んでフォントの読み込み処理を書き始めたら、
もそも M5EPD 自体におんなじコードがあることに気がついて、それどころかズバリ


Function: load TTF font file from file system, support SPIFFS and SD*.
esp_err_t loadFont(String path, fs::FS &ffs)

というメソッドがあることに気がついたのでした。
そういうわけでイケダム時計用の TrueType フォントを作ることに。
作ると言っても文字を起こすわけではなく、既存の TrueType フォントから時計で使う文字だけのサブセットを作るということです。

Google フォントの Noto Mono を使えば、もともと英数字記号だけでファイルサイズも小さくて良さそうだったのだけれど、気温用の「℃」が含まれていないので、Noto Sans CJK JP からサブセットを作ることとしました。
紆余曲折ありながらも、 fontforge を使ってスクリプトでサブセットを作成。

* Noto Mono は ttf ファイルなのに、 NotoSans CJK JP は otf ファイルだった。なぜだ。
* otf ファイルを読み込むと fontforge が大量の警告を出す。なぜだ。
* fontforge が多バイト文字列をちゃんと扱ってくれない。「℃」をバイトごとに扱ってしまう。fontforge の独自スクリプト (pe) じゃなくて、 Python で書いたほうがマシだったかなあ…と思い始めたところで、Ucs4() 関数でちゃんと扱えると判明して解決。
* フォント名を変えようとするも、 SetTTFName() の引数に指定するべき値が分からない。リンク先がリンク切れ。とりあえず SetTTFName() でググって見様見真似で書いてみる。

出来上がったのがこちら:
https://github.com/ikedam/m5paper-ikedamclock/blob/main/font/makesubset.pe

M5Paper と EEPROM

無線 LAN への接続のユーザー名をパスワードをハードコードしているのですが、これがちょっとやだなあと思っています。
いつ、うっかりコミットしちゃうかわからないし…

M5Paper_FactoryTest で無線APのリストアップとパスワード入力できてるんだから、その設定を保存するようにすればいいじゃん!と思うのですが、M5Paper は USB を挿さずにバッテリーが無くなってしまうとすべての設定がパーになってしまうので、毎回無線設定をしないといけなくなります。

いろいろ調べていると、M5Paper には FM24C02 という EEPROM がついていて、 4096 バイトまで保存できるらしいです。
ただなぜか M5EPD 内に API がないらしいので、I2C でアクセスできるらしいので頑張ってライブラリを作ろうと思い立つのでした。

SHT3x は M5Paper の商品情報でデータシート(チップの使い方の説明書っぽい)があったのに、なぜか FM24C02 のデータシートはありません。
ググると出てくるのですが、なんかソフトウェアの再配布サイトみたいな感じでデータシートを再配布しているサイトで、これって安全なのか…と思いながらも、まあ、他にないので仕方ないかと参照することに。

I2C のライブラリレベルでのアクセス方法が知りたいのに、電気信号的な情報が載っていてつらいです。わからん。
何よりわからないのはアドレスが

1 0 1 0 A0 A1 A2 R/W

と 8bit なのですが、I2C でチップをスキャンしてアドレスを探しても 0x50, 0x51 とかしか出てこなくて、どう考えても 0xA? なんてアドレスは出てこないんだよな…

M5EPD の実装を見ていると 0x51 が BM8563 というチップのアドレスで、BM8563 のデータシートもやっぱり 1 0 1 0 0 0 1 RW という記載になっているので、なんか末尾のビットは無視して上位7ビットだけでいいらしい。
どうやら I2C のアドレスは(ライブラリとしては?)7ビットの指定で、末尾の R/W はライブラリ側で適宜つけてくれるものらしい。

あとデータシート読んでると、書き込み後は一定時間次の時間の書き込みできないよ、書き込みできるようになってから ACK を返すからね、って言っているけれど、多分ライブラリとしては ACK が返ってくるまでブロックするから、この辺の手当ては必要なさそうだなあと。


なんとなく仕様も分かったので作ってみようとしたところで
EEPROM.h
というファイルが既にライブラリ内にあることが判明。なんじゃこりゃ。


見ると「nvs を EEPROM っぽく使うためのライブラリ」みたいなことが書いてあるのだけれど、 nvs って何だろう。

調べて判明したこと:

* ESP32 にはチップ上に不揮発 Flash 領域がある。 (4MB くらいあるらしい)
* プログラムを書き込むのに使うところだけれども、一部領域をプログラムからアクセスする領域にできる。
* ひとつが nvs で、 Flash 領域に Key-Value を保存できる。
* 他に SPIFFS があって、階層構造のないファイルシステムとして使える。

SPIFFS は知ってたけれども、リードオンリーなものだと思ってた。読み書きできるんだ…
そうすると、FM24C02 ってなんのためにあるんだろう…


ググったところ、同じ疑問を持っている方がいたのだけれど、明確な結論は分からず。
(nvs は時々値がおかしくなることがある…という話もあったけれど、FM24C02 のほうがマシという話もあるわけでもなく)


ともあれ、何もしなくても欲しい物があることが判明した。
神がかってない?

M5Paper とライセンス

M5Paper と m5paper-dashboard でも言及の通り、どうも M5Paper の SDK である M5EPD のライセンスの扱いが怪しい。
(詳細は https://github.com/m5stack/M5EPD/issues/21

一方でライセンスの扱いはよく分からなくて、

* M5EPD はリポジトリ全体のライセンス表記 (LICENSE ファイル)として MIT ライセンスにしていて、かつコピーライト表記を M5Stack としている。
* ただし、リポジトリ内のファイルには GPL 3.0 のファイル(GPL3.0 で公開されているリポジトリからの転載物)が含まれている。
* 他にも MITライセンスだけれど、コピーライト表記が別の人のライセンスが含まれている。
* M5EPD 自体はソースコードの形態で配布されている。
* なので、各ファイルのライセンスやコピーライト表記は確認できるわけで、これはライセンス違反か?

と聞かれるともうなんとも言えない。むずい。

さらに、ぼくが M5EPD を使ったソフトウェアを作ってそのソースコードを MIT ライセンスで公開した場合、そのソースコードには「M5EPD に依存しているからビルドするときには M5EPD をもってこい」と指示が書いてあるだけで、直接 M5EPD 自体が含まれるわけではなく、もちろん前記で問題になっていた GPL3.0 のファイルもそのソースコード一式には含まれない。これは実際問題になるの?という話になると、とんと検討もつかぬ。

確実にわかるのは、そのソフトウェアをビルドして、バイナリを配布して、そのときにライセンス&コピーライト表記として自分のライセンス&コピーライト、あと「M5EPD の LICENSE の中身」だけを表記したとすると、これは確実にアウトになる。それだけはわかる。
その点では、M5EPD には「このライブラリを使用する場合には最終的にこのコピーライトが必要だよ」という表記を行うのが親切であることは間違いない。そして親切と違反の間のギャップは判断がつかない。
そしてさらに根本的な問題を言うのであれば、「バイナリを配布する」って言うけれど、PlatformIO でビルドしたときにバイナリはどこにあるんだろう。そもそもあるのかないのか自分で分かっていないものを配布するという仮定自体がすでに異次元の話ではあるのであった。

ライセンス本文を読んでみたけれども、MIT ライセンスは短いからまだ読めるとして、GPL となると長くて読めなくはないけれども、途中を読んでいる間に先頭の方のことは忘れ始める体たらくでどうにも理解が及ばないのであった。
ググってみていろんな記事を見てみたけれど、ズバリなことは書いていないし、そもそも書いてあることをどの程度信用していいかも分からない。「MIT ライセンスの場合、ライセンス表記が必要なのはソースコード配布の場合のみ」というような記述まで見つかるのであった。MIT ライセンス記載を見る限りそんなことはなくて、バイナリであってもライセンス表記は必要なはず。

そういう経緯で信頼できそうなソースとして本を買うのでした。

単純に各ライセンスの扱い方だけではなく、ソフトウェア事業をする上での OSS に関する考え方の指針なども載っていてとても参考になる本です。
です、というのはまだ読み終わっていないからですね。

ライセンスの事例として TOPPERS → MIT → BSD → Apache と順に説明があるのだけれども、Apache の著作権の話で急激に難解になってきて、10日でわかる〇〇が4日めくらいから急激に難しくなるアレですね。

ざっくり読んだ結論としては

* 基本的に再配布時のライセンス表記の条件に「substantial portion」と記載があるので、多分、「各ソースコードでライセンス表記があるからオッケー」とはならないような気がする。
* この本では「ライセンスについて考える時は、開発者がそのライセンスによって期待していることを尊重することが大切」という趣旨のことを言っていて、その趣旨で考えると、ファイルだけ持ってきてリポジトリに突っ込んで、全体の LICENSE や README.md で言及しないのはナシな気がする。

と思うのでした。

そんなわけで自分用にライセンスが怪しいところを再実装することに。
なにぶん API のちゃんとしたドキュメントがないので、元のとおりに動いているのかはよくわからないのだけれど。
とりあえずなんとなく動いているからよしとしよう。

ちなみに元のチケットで指摘されていた部分以外にも、FreeType ライセンスのコードや、コピーライトが異なる MIT ライセンスのコード、あと「MIT ライセンス」って書いてあるけれど、コピーライト部分がなくなっているコードも見つかったりもするのでした。

M5Paper と勉強と書籍

m5paper-dashboard によって実はほぼ目的は達成されてしまったのだけれど、せっかく買ったので、

* スクラッチで自分で作ってみたいなあ。
* 自分で作るんだったら、イケダムの画像とかも表示したいなあ。そうすると今後、家庭内予算も下りやすくなる。

ということで、もうちょっとちゃんと PlatformIO での組み込み開発のことを勉強するか、と思ったのであった。

ざっくり調べた感じ(かなり適当)

* Adruino という学習用のボードがあって、M5Paper 向けのプログラムは ArduinoIDE で作るもので、派生として PlatformIO がある、ということらしい。
* もとの Arduino にはネットワーク機能がないのだけれど、IoT などの需要でネットワーク機能が要望されて、Arduino + ネットワーク機能な ESP32 というチップがあって人気らしい。
* M5Stack 社はその ESP32 + ディスプレイ + もろもろ をまとめて、基盤むき出しじゃない箱にはいったデバイスとして M5Stack シリーズを販売していて、M5Paper はそのシリーズのひとつらしい。

ということが分かったのであった。

ネットでいろいろ知るのも限界もあるので、本を買って勉強しようと調べた結果、以下を購入しました。
つまりアフィリエイト記事です。
ちなみに残念ながら M5Paper の本ズバリというのはありませんでした。そんな最近に発売されたものなのか。


みんなの M5Stack 入門

* 「M5」がエムファイブと読むと知って衝撃を受けました。ちなみに家庭内では「えむごぺーぱー」と呼ばれています。
* M5Stack のシリーズの説明があって良かった。なにぶん、そういうこと何も知らずに M5Paper を買ったので。
* I2C について詳しく知りたいというのがモチベーションだったのだけれど、あくまでライブラリの説明だけで、I2C に関する技術的な詳細の説明はなかった。
* M5Stack 全般について、API の説明があるのがとてもよい。なにぶん、M5Stack 社のドキュメントがなんというか雑なので。実際のところ、これみんなどうしてるの?
* 内容的にはどちらかというと初学者向けで、そこまで深くは踏み込んでいないっぽい。こんにちは、初学者です。
* Ambient、BLE などを使っている事例もあって、特にその辺は使うつもりはなかったが、温度や湿度を取得するのだし、使ってみてもいいかもと思った。
* いろいろ工作している点もおもしろい。ただぼくは工作するつもり無いので、ふーんって言いながら読むのであった。
* 「CEO の Jimmy さん(右)と筆者」は向かって右か、本人たちから見て右か悩む。向かって右の方がサムズ・アップしていて、CEO がサムズ・アップしているのか、筆者がサムズ・アップしているのか、どちらにせよ感慨深いものがある。

ESP32&Arduino 電子工作プログラミング入門

* みんなの M5Stack 入門よりも深く踏み込んでいる。中級者向き。
* 写真が時々上下逆な気がする。気になる。
* Arduino 言語は C++ とは別物(サブセット?)というのを知って衝撃を受ける。
* 言語の説明と、電子工作の説明が並行して行われている。C++ はだいたい知っているけれど、読み飛ばしができなくてちょっとつらい。
* ライブラリの作り方の説明があってよい。(Arduino での作法の説明という点で)
* 割り込み、DeepSleep に関する説明があってよかった。(というよりも、DeepSleep に関する説明目当てで目次からこの本を買ったのであった)
* SPIFFS、OTA に関する言及もあった(「みんなの M5Stack 入門」ではカバーされていない範囲)
* I2C に関しては記載が「みんなの M5Stack 入門」よりも少なく、というか、ほぼない。
* Ambient に関しても記述は 1 ページだけで、事例のカバー度合いの点では、「みんなの M5Stack 入門」の内容を含んでいるというわけではない。なので「みんなの M5Stack 入門」はこっちよりも初心者向けだったからいらなかった、ということは決してなかった。一方で、こっちでは Google Home を使う事例もあったりしている。この二冊を買ったのはベストチョイスだったと思う。