2021年5月アーカイブ

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 を使う事例もあったりしている。この二冊を買ったのはベストチョイスだったと思う。

M5Paper と m5paper-dashboard

そもそも M5Paper で何がしたかったのかというと

* NTP で同期する時計を表示して
* 温度と湿度が表示したい

ということなのですね。

じゃあ張り切ってそれを作ろうか…と思って M5Paper での開発についていろいろ調べていたら、
これでいいじゃない、というのが見つかったのでした。

https://github.com/estshorter/m5paper-dashboard

温度・湿度の測定を外付けのセンサーでやっているのを M5Paper 付属のセンサーでやったり(付属センサーだと M5Paper 自体の熱などで精度が下がるから、ということが書いてあったのをどこかで見た気がする)、CO2 測定のセンサーはないのでその部分を外したり…とやって自分用のバージョンを作成しました。

m5paper-dashboard

その過程でいろいろ分かったこと。

  • M5Paper の SDK (API?) である M5EPD はライセンスの扱いに不備がある。
    • m5paper-dashboard を作った方が報告している: https://github.com/m5stack/M5EPD/issues/21 。今後の改善に期待。
    • m5paper-dashboard ではライセンスが怪しい部分を除去したと思われる独自バージョンの M5EPD を使っている(必要ない機能を削ったという側面もあると思うけれど)
  • m5paper-dashboard では表示周りには M5EPD の機能ではなく、 LovyanGFX というのを使っている。
    • https://github.com/lovyan03/LovyanGFX
    • 「℃」などの表示のために IPA フォントのサブセットを作って使用している。M5Paper_FactoryTest のカクカクの文字に比べてきれいな表示ができているのはこのフォントの作成をしているためのよう。
    • IFont をカスタマイズすることで文字の表示を制御できる。「:」が数字と並べるとズレて見える問題をこの方法で解決した。(: の位置がズレるのは一般的な問題で、特に今回の環境が問題というわけではないらしい)
  • バッテリーは 6 時間位しか持たない。(何をやるかにもよるんだろうけれど)
  • 電圧からバッテリー残量を表示するようにしたけれど、この表示がどこまで正しいのかは怪しい。ちゃんとバッテリー残量を表示するのであれば、バッテリー管理を行って情報を渡してくれる専用のチップが必要だが、M5Paper ではそういうチップは使っていない。

M5Paper と FactoryTest

ともあれ、何をするにせよ万が一ぶっ壊れたプログラムを書き込んだら元に戻せるようにしないとね、ということで

m5stack/M5Paper_FactoryTest

を書き込むところからはじめました。

いくつかのサイトを見て回った結果、 VSCode で PlatformIO というのを使うことにしました。
斜め読みした感じ、他の選択肢として ArduinoIDE というのも使えるのだと思います。

ちなみに Docker で開発できないかなあ、と思ったのですが(Windows で直接なにかするとだいたいトラブルため)、どうやら Windows で Docker コンテナから USB にアクセスする方法がないらしいので、断念しました。

PlatformIO のインストールは、「VSCode の Extension」としてのインストールが終わった後、PlatformIO 本体のインストールが行われるので、「VSCode の Extension」としてのインストールが終わって即何かをしようとするとうまく行かないようです。
なんかうまく動かないなあ、よし、VScode を再起動だ!ってやると、PlatformIO 本体がインストール処理中のままぶっ壊れるので何もかもが上手く行かなくなります。
よくよく見ると Output というウィンドウに


Installing PlatformIO IDE...
It may take a few minutes depending on your connection speed
Please do not close this window and do not open other folders until this process is completed.

Debugging information is available via VSCode > Help > Toggle Developer Tools > Console.

って書いてありますね。

とりま、VSCode のウィンドウ下部に
PlatformIO インストール中
という表示が出ている間は VScode はほったらかしにする、

VSCode でなにかしていいのは、Output ウィンドウで
{code}
PlatformIO IDE installed successfully.

Please restart VSCode.
{code}

というメッセージが出てきたり、ポップアップで
PlatformIO インストール完了の通知
という表示が出たりウィンドウ下部が
PlatformIO インストール完了
になってから、ということで、それまでパソコンを放っておくのがベストです。

ちなみに壊れちゃった場合は、 VSCode の Extension から PlatformIO IDE をアンインストールして、 %USERPROFILE%/.platformio を削除してから再び PlatformIO IDE をインストールすればなおりました。

そうしてめでたく PlatformIO のインストールが無事完了して M5Paper_FactoryTest を開いてさあビルドだ!とやると

{code}
command 'platform-ide.build` not found
{code}

と謎のエラーになります。どうやら VSCode 起動後、プロジェクトのフォルダに対して PlatformIO の初期化処理があるらしく、フォルダを開いた後に
PlatformIO のプロジェクト初期化処理
みたいな表示(細かいテキストは変わるけれども、要するに処理中のくるくるアイコンが出ている間)はまだビルド等が始められないようです。
この表示が終わった後はビルドが行なえます。
初回フォルダを開いた時は依存ライブラリのダウンロードが行われるらしく結構時間がかかります。二回目以降はもっと短く済むようになりますが、どちらにせよ、開いてすぐにはビルド等は行えないので、しばらく待つ必要はあります。

そうして初期化処理が終わってビルドすると、めでたくビルドに失敗します。なんでやねん。

In file included from src\epdgui\epdgui_switch.h:4:0,
from src\epdgui\epdgui_mutexswitch.h:4,
from src\epdgui\epdgui_mutexswitch.cpp:1:
src\epdgui\epdgui_base.h:4:19: fatal error: M5EPD.h: No such file or directory

***************************************************************
* Looking for M5EPD.h dependency? Check our library registry!
*
* CLI > platformio lib search "header:M5EPD.h"
* Web > https://platformio.org/lib/search?query=header:M5EPD.h
*
***************************************************************

どうやら依存に M5Paper の SDK が指定されていないということのよう。
platformio.ini というファイルがリポジトリにある以上、 PlatformIO でのビルドをサポートしていそうなものなのですが、なんで依存の設定がないんでしょうね。謎です。

ともあれ、VSCode のアクティビティバー(一番左の列)から PlatformIO(アリかハチの顔のアイコン)を開いて、QUICK ACCESS > PIO Home > Projects & Configuration から現在のフォルダをプロジェクトとして追加、その後 Libraries から、 M5EPD を検索、プロジェクトに追加します。
最終的には platformio.ini に

lib_deps = m5stack/M5EPD@^0.1.1

という記載が行われる結果になります。
その後ビルドすると、無事にビルドに成功します。

アップロードする際は USB ドライバを
https://docs.m5stack.com/en/quick_start/m5paper/quick_start_arduino
からダウンロードしてインストールしてから行います。
ちなみに USB ドライバは
https://shop.m5stack.com/pages/download
https://docs.m5stack.com/en/download
辺りからもダウンロードできるけれど、リンク先は一緒です。
製品情報から辿れる一番それっぽいルートが最初のもの、くらい。

長くなったので PlatformIO のインストールとビルドするまでの話で記事を分ければよかったと思うのであった。

M5Paperを購入

M5Paper
M5Paper を買いました。
最近、CASIOのデジタル時計の湿度計の挙動が怪しいのと、電波時計なのに電波がとれないのは問題なのではないかという議論の末。

何事もなく購入できたのだけれど、どうも本当は品薄だったりしているらしい。

実際には買ったのは3月末で、そういえば顛末を記録しておいたほうがいいな、と思ったので怒涛の更新を行います。

このアーカイブについて

このページには、2021年5月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2013年2月です。

次のアーカイブは2021年6月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 5.04