##M5Stackの設定ファイルの運用例のコード内容について
先日書いた記事の続きになります。
今回はコードを読み解く際の詳細になるので、コードと見比べながら読む想定です。
普通に読むとわけがわからないのでお勧めできませんw
##main.cpp概要
main.cppの中身についてまとめます
####namespace Config
設定関係の処理を含みます。内部については後述
####namespace SubScreen
設定が取得できない場合の処理です。ここに入ると再起動以外では抜け出せません。
####void dispMenu()
ボタン別の機能名をメニュー的に表示
####void setup()
SDカードをチェックして、設定情報を読み込みます。
auto loadOK = Config::loadConfig();
が読込処理です。
M5GFXで処理状況をLCDに表示します。
ロード中はテキストがスクロールして上に流れていくように設定しています。
ロード完了後は、成功メッセージを表示し、シリアル出力に設定情報を書き出しています。
(実際のアプリケーションではここでアプリケーション本体を起動します)
補足:SDカードへアクセスするときは、endWrite()でバスを解放する必要があります。
####void showProgress(const char *message)
ボタンを押したときにメッセージをLCDに表示します。
ボタンを押したときに反応がないと不安になるので表示する方が安心です。
####void loop()
テスト用の機能として「再起動」「設定リセット」を用意しています。
Cボタンは特に機能がないのでDummyと表示するだけです。
「設定リセット」でnvsの情報も削除できますが、サンプルでは無効化しています。
nuke(true)で削除します。
https://gist.github.com/panda728/4a55c50a8c82ee70223ec8b545fb6643#file-main-cpp-L515
Wifi接続したときにnvsに設定情報が記録されます。
次回以降はSSIDやパスワードなしで接続できて便利なのですが、M5Stackを人に渡すときなどを考えるとリセットする機能が必要ですので、こういった機能が必要となります。
##namespace Config詳細
下の方から読むことを推奨(説明もそのようになってます)
####共通処理
処理状況を出力する処理が各所に入っています。
読み解く際はスルーした方が見やすいです。
log_iなどのログコマンドで開発時、デバック時にシリアル情報が取得出来て便利です。
LCDにも要所要所で情報を出力するようにします。
事前にテキストがスクロールするように設定しているので、状況を大量に出力しても自動でスクロールして表示されます。
ユーザー側としては処理が止まっているのか、少しでも進んでいるのかがわかるので安心して待てます。
(余談ですが、Wifi接続などもこの方式で表示すると安心感がでます)
####基本フロー
SDカードからMACアドレス名のついた.iniファイルを探します。
次にSDカードからconfig.iniを探します。
見つかれば、そのファイルをSPIFFS上にconfig.iniとしてコピーします。
SPIFFS上のconfig.iniがあれば、設定クラスに値を展開します。
見つからなければ、読込失敗を返します。
####補足
MACアドレス名.iniファイルを探すのは、複数の機器情報を1つのSDカードに保管する運用を想定したものです。
SPIFFSにコピーしておくことで、SDカードを抜いても設定が読み込めるようにしています。
SPIFFS上のconfig.iniファイルはnuke処理で削除します。
#### bool loadConfigSPIFFS()
https://gist.github.com/panda728/4a55c50a8c82ee70223ec8b545fb6643#file-main-cpp-L166
設定ファイルを全行読み込んでいます。
メモリ不足対策として、heap_caps_get_free_size(MALLOC_CAP_DMA)でメモリの空きと相談しながら処理ります。(クラッシュ防止)
https://gist.github.com/panda728/4a55c50a8c82ee70223ec8b545fb6643#file-main-cpp-L196
filterでコメント行や空白行をカットします。
今日の末尾に「;」でコメントが設定できる想定です。「#」にも対応したい場合は、以下のあたりの処理を変更する必要があります。
https://gist.github.com/panda728/4a55c50a8c82ee70223ec8b545fb6643#file-main-cpp-L210
####void ParseConfig
https://gist.github.com/panda728/4a55c50a8c82ee70223ec8b545fb6643#file-main-cpp-L96
グループ名とキー項目名、値を引数で受け取って、対応する設定ファイルの値を更新します。
型の変換のエラー処理が甘いところがあればエラー対策した方が安全です。
####設定情報クラス
https://gist.github.com/panda728/4a55c50a8c82ee70223ec8b545fb6643#file-main-cpp-L22
別に1つのstructでもよかったのですが、サンプルなので細かく分けています。
設定項目は宣言時に初期化推奨です。
行を丸ごとコメントアウトして、設定が流れてこないことがあります。
未設定のままだとアクセスしたときにクラッシュします。
void writeLine
設定情報をLCDに出力します。
事前にテキストがいっぱいになると上にスクロールするように設定しているので、大量にログを出力しても大丈夫です。
大量にログが流れたほうがユーザー側には頑張ってる感がでますw
##以上
処理内容の補足説明を羅列しました。
コード読み解くときの参考になれば幸いです。(半分は半年ごとの自分に向けてのメッセージw)