ESP32のArduino IDEライブラリにはOTAというWi-Fi通信の機能があって、これを利用したスケッチ書き込みが出来るようになっています。これまでOTAは設定が面倒な気がして深くは調べていませんでしたが、M5Core2がUSBシリアルの書き込み時に頻繁にリブートするのが鬱陶しくなってきたのでOTAを試したくなり、設定方法について調べてみることにしました。
その結果、とても簡単に利用できることが分かりました。多くのサイトでOTAの設定について公開して下さっていますので、これらの情報から最低限必要な設定を書き込んだスケッチを作ってみました。
スケッチの6行目に接続Wi-FiのSSIDとパスワードを記述して、7行目にはArduino IDEから書き込み先のネットワークポートとして表示されるホスト名を記述します。ただし7行目はなくてもネットワークポートには接続先のIPアドレスは表示されます。
このスケッチでOTAの動作確認をします。
最初にESP32シリーズのマイコンにUSBシリアル経由でスケッチを書き込みます。このとき"ツール"メニューのボート設定の"Partition Scheme:"で"NO OTA"とあるものは選ばないようにしてください。
ESP32マイコンがリブートすると、Arduino IDE(2.2.1)の"ツール"→"ポート"メニューの中に"ネットワークポート"という項目が現れスケッチに記述したホスト名とアドレスが表示されます。
これを選択してスケッチの書き込みを開始すると、初回接続時のみパスワードを聞いてきます。
このスケッチではパスワード設定をしていないので、なにか適当に1文字入力して"マイコンボードに書き込む"ボタンを押します。するとWi-Fi経由でスケッチが書き込まれます。Arduino IDEを終了するなどでWi-Fiを切断した後、再接続するときまでこのダイアログは表示されません。
スケッチ内でOTAのハンドラを常に呼び出すようにしておかなければならないのは少し嫌ですが、ESP32マイコンを起動しておけばいつでも書き込みが出来るのは便利です。マイコン本体にUSBケーブル等をつなぐ必要がないのもいいですね。
スケッチのループ内でなくfreeRTOSからハンドラを呼び出す方法もありますが、スケッチに記述する方が簡素なのでこちらを使うことにしました。
以前ESP32-WROOM-32Eの書き込み手順を簡素化する記事をアップしましたが、これも必要なくなりました。ただし完全にいらなくなったわけではなく、プロクラムのパグによる無限ループや暴走などでOTAのハンドラが呼び出されなくなるとWi-Fi接続が出来なくなってしまいますので、このときはシリアル経由での書き込みを使うしかありません。
これでOTAの動作確認はとれたのですが、もっと本格的なスケッチで使用してパフォーマンスに影響がないか試してみたくなりました。そこでここのゲームを移植させてもらい、OTAを組み込んでみることにしました。
まずはESP32-WROOM-32Eに移植します。
元のゲームはWi-Fi経由でスマホをコントローラーにしていましたが、OTAに影響があるかもしれないのでI2C接続のWiiヌンチャクコントローラーに変更しました。ESP32の21ピンと22ピンがSDAとSCLになっているのでここにヌンチャクコントローラーをつなぎます。ディスプレイはビデオモニターを使います。したがってグラフィック周りはLovyanGFXに置き換えます。
ESP32-WROOM-32Eに接続するこれら周辺デバイスについて、事前に調べておかなければならないことがあります。
ビデオモニターは320×240の解像度で使用しますが、表示内容をモニター画面にきちんと収める為にLovyanGFXのコンポジット出力の設定値を決める必要があります。以下のスケッチをESP32-WROOM-32Eに書き込んでください。すでに上記のOTA_template.inoを書き込んであれば、Wi-Fiを使って書き込むことが出来ます。
画面に表示される四角形がモニター内に正しく表示されていなければ、LGFX_NTSC.hのcfg.memory_width,cfg.memory_heightの値を変更して再度書き込みます。手持ちのアスペクト値16:9と4:3のビデオモニターの値を入れておいたので、これを参考に自分のモニターに合う値を探してみてください。
NTSC_template.zip (クリックしてウィンドウが開いたら右上のダウンロードボタンを押してください)
この作業を何度か繰り返すことになると思いますが、OTAを使えば書き込み作業は苦にならないでしょう。
次にヌンチャクコントローラーのキャリブレーションを行います。下記のNunchuckCalibration.zip内のLGFX_NTSC.hを上記で値を修正したものに差し替えて、スケッチをESP32-WROOM-32Eに書き込んでください。このスケッチもOTA対応です。
初めにスティックの中心位置の値を調べますので、スティックから手を離してCかZのボタンを押します。次にスティックの可動範囲の値を取り込むので、スティックを目いっぱい倒してグルグル回します。十分回したらボタンを押して値を取り込みます。最後に画面に表示される内容をメモして終了です。もう一度ボタンを押すと最初からやり直せます。
NunchuckCalibration.zip (クリックしてウィンドウが開いたら右上のダウンロードボタンを押してください)
事前の準備は以上です。移植した倉庫番のスケッチをダウンロードしてください。
esp32_Sokoban.zip (クリックしてウィンドウが開いたら右上のダウンロードボタンを押してください)
ESP32Sokoban.inoの21行目からの定義に上記のヌンチャクコントローラーのキャリブレーションの値を書き込みます。THRESHOLDの値はスティックの感度ですが、2以上にしてください。大きい方が反応が鈍くなります。
このスケッチではArduinoOTA.handle()をloop()内に記述していますが、ゲーム実行中でも遅延を感じることなくOTA書き込みが行えます。ゲーム自体もOTAによる負荷は感じません。スケッチ書き込みの簡便性を考えるとOTAは利用価値がありますね。
ゲームの操作方法ですが、キャラクターの移動はヌンチャクコントローラーのスティックで行い、ギブアップするときはCかZボタンを押します。中断機能とかはありません。ひたすら10面までパズルを解いていくだけです。かなり難問ですよ。
つづいてM5Core2でもOTAを試してみたかったので、こちらにも移植してみました。操作はタッチパネルで行います。ライブラリばM5Stack社の全ボード共通に使えるM5Unifiedを使ってみました。グラフィックはLovyanGFXと同じM5GFXが使われていますので、クラスのオブジェクト名を置換するだけでLovyanGFXのスケッチがそのまま使えます。ボードの種類やメジャーな周辺デバイスは自動認識なので、タッチパネルを持っていて画面の解像度が同じならばM5Core2以外でもそのまま(もしくはわずかな変更だけで)動くかもしれません。
スケッチはこちらです。
Core2_Sokoban.zip (クリックしてウィンドウが開いたら右上のダウンロードボタンを押してください)
OTAの利用はとても快適です。邪魔なUSBケーブルがなくなり、書き込みスピードもシリアルの時より早くなりました。
ゲームの操作ですが、表示画面の上下左右をタッチするとキャラクターがその方向に動きます。画面下の三つの丸いタッチボタンのあたりをタッチするとギブアップします。
今回OTAがあまりにも快適だったので過去に作った色々なスケッチにも組み込んで使ってみたのですが、その過程で一つだけ問題点を見つけました。OTAを組み込んだスケッチでLovyanGFXのdrawPngメソッドを実行しても画面に何も表示されないのです。読み込むPNG画像のサイズを小さくしても表示されません。でも、OTAの記述を削除するとちゃんと表示されます。この現象はESP32-WROOM-32EだけのものでM5Core2では発生しませんでした。まあ、drawJpgやdrawBmpはちゃんと動作するので深刻な問題ではないんですけど。
もしかすると原因はRAMの容量が足りないせいかもしれません。というのもESP32-WROOM-32EでLovyanGFXとOTAとSPI接続のSDカードを同時に使おうとするとOTAやSDカードが機能しないという現象が発生したのですが、これら3つのライブラリのうち1つを外せば他のライブラリは正常に動作していたからです。もちろんM5Core2ではこんな問題は発生しません。そこでメインのRAMが足りないせいかもしれないと考えました。LovyanGFXのコンポジット出力ではSPI接続のモニターに比べてRAMを多めに使用するので、そのための弊害が出たのかもしれません。でも、OTAにこだわるのならESP32-WROOM-32Eには内部にFlashが16MBあるので、これをディスクとして使えばSDカードはいらないですけどね。
ところで話は変わりますが、ライブラリのM5UnifiedをESP32-WROOM-32Eで使ってみました。ボードの自動認識ではATOMと認識されました。グラフィック周りはLovyanGFXと同じですのでNTSC-J出力もできます。最終的にM5Stackシリーズで動かすアプリを作るときは、このライブラリをつかった方が変更箇所が少なくて済むので便利かもしれません。
以前作成した幾つかのスケッチをM5Unifiedで書き直してみましたが、ちゃんと動作しました。ただ、上記のdrawPng等の問題は発生します。
まだ深く使い込んではいないので開発のメインライブラリに出来るかどうかは不明です。周辺デバイスをつないだ時に初期設定がどうなるのかなど試してみないと分からないことがまだ色々あります。
※コメント投稿者のブログIDはブログ作成者のみに通知されます