このところILI9341タッチパネル付きTFT液晶をよく利用しているのですが、タッチパネル機能は使ったことがありません。タッチの有無や座標くらいならArduinoで取得できるようなのですが、画面にボタンなどを表示してタッチパネルで操作しようとすると作りこみが必要になり面倒だったからです。
でも、せっかくタッチ機能があるので何かに利用したいですよね。そのためにはGUIや入力デバイスを扱える汎用的なライブラリが必要です。こういった用途に使えてESP32などマイコンをサポートしているライブラリは、知っている限りLVGLだけでした。
LVGLはISP-IDFからは簡単に使えるので以前にも試したことはありましたが、タッチパネルを使わない画面表示だけならLovyanGFXの方が手軽なのでこれまで活用しませんでした。
このLVGLはメニューやボタンなどのウィジェットを画面上に配置して本格的なGUIアプリをつくれるライブラリです。数多くの便利なウィジェットと呼ばれるGUI部品があって、例えばキーボードウィジェットなどはタッチパネルから文字入力できる優れものです。ただし、入力デバイスがないと利用価値は半減してしまいます。
LVGLはArduinoで利用することはできるのですが、TFT_eSPIライブラリを介してLCDとタッチパネルをサポートしているようです。Arduinoのサンプルを見てみると、タッチパネル操作は単純に座標とタッチの有無を拾っているだけでした。LVGLのサンプルプログラムをコンパイルするときにはフォルダ構成を変える必要があったりと今一つな感じです。
ISP-IDFにもLVGLでILI9341とタッチパネルを使うためのサンプルがあります。こちらはタッチパネルドライバを組み込んで使うようでした。全体的にしっかり作りこんであるような感じです。
そこでISP-IDFで試すことにしたのですが、Windows環境のPlatformIOやVSCodeのISP-IDF拡張機能でサンプルプログラムをコンパイルしようとしたところエラーが続出してしまいました。地道に1つ1つエラーをつぶしていくのが面倒だったので、結局UbuntuのコマンドラインからISP-IDFを使ってコンパイルしました。この環境だとエラーが発生せず、コンパイルすることができます。
今回このサンプルプログラムの動作確認に用いたのはILI9341とESP32-WROOM-32Eです。
配線はサンプルプログラムの内容に従って以下のようにしました。(一部変更)
実際にサンプルプログラムをコンパイルしてESP32に書き込んでみたところ、画面は表示されたのですがタッチパネルは動作しませんでした。よくよく調べてみるとタッチパネルのドライバがSTMPE610となっていて使用しているタッチパネルと異なっていました。別途XPT2046のドライバが必要です。探してみるとここでXPT2046のドライバが見つかりました。早速サンプルプログラムにこのドライバを組み込んでみたところ、うまく動作しました。
ということで、ここまでの手順を説明します。まずは、ISP-IDFのコンパイル環境構築から。
・ESPRESSIFのサイトのStep.1に従ってUbuntuパッケージのインストールを行います。
・Step.2に従ってESP-IDFのリポジトリをクローンします。
・Step.3に従ってESP-IDFのセットアップを行います。手持ちのマイコンに合わせて ./install.sh esp32,esp32s2 と入力しました。
・Step.4にあるaliasの設定を.bashrcに記述します。Ubuntuでターミナルを開きget_idfと入力するとISP-IDFが利用できるようになります。
次はタッチパネルのサンプルプログラムです。
・ESP-IDFのリポジトリの esp-idf/examples/peripherals/lcd/spi_lcd_touch フォルダを任意の場所にコピーします。
・ターミナルを開いてコピーした spi_lcd_touch に移動します。
・コマンドラインで上記aliasで設定した get_idf を入力し、ESP32ターゲットの設定のため idf.py set-target esp32 と入力します。ESP32のCPUがS3なら idf.py set-target esp32s3 と入力します。
・次に idf.py create-manifest と入力します。mainフォルダーの中に idf_component.yml が作成されているので、テキストエディタで開いて以下のように変更して保存します。
- dependencies:
- idf: ">=4.4"
- lvgl/lvgl: "~8.3.0"
- esp_lcd_ili9341: "^1.0"
- atanisoft/esp_lcd_touch_xpt2046: "~1.0.0"
・idf.py reconfigureと入力します。
・idf.py menuconfigと入力して設定メニューを開きます。
カーソルの上下で項目を選び、右カーソル(→)でその項目の設定に移動し、設定ではスペースか右カーソルで設定内容の変更を行います。戻るときは左カーソル(←)です。
まず変更するのは Serial flash config です。
ESP32-WROOM-32Eを使ったので以下のように設定しました。
左カーソル(←)で上のメニューに戻ったら、次は Example Configuration です。
Enabloe LCD touch をオンにします。
最後にQキーを押してセーブメニューを表示させ、Yを押して設定を保存します。
・次にサンプルプログラムの修正を行います。タッチパネルドライバの入れ替えや一部のGPIOの変更と、バックライトがGPIOオンで点灯させるだけになっていて明るすぎたのでPWMで調整するようにしました。
修正箇所が多いので spi_lcd_touch_example_main.c をダウンロードできるようにしました。BOOTHをアップローダーとして使っていますが無料でダウンロードできます。
ダウンロードしたファイルを解凍したらmainプログラムと差し替えます。
・ESP32をPCにつなぎ(ESP32-WROOM-32Eならボタン操作でダウンロードモードにして)idf.py flash と入力します。
サンプルプログラムのコンパイルとFlash書き込みが終了したら(ESP32-WROOM-32Eならリセットボタンを押す)デモが始まります。
タッチパネルでボタンを押すと画面が90度ずつ回転します。
このサンプルプログラムだけでなく spi_lcd_touch/managed_components/lvgl__lvgl/examples のサンプルも実行することができます。spi_lcd_touch_example_main.c の下の方にある example_lvgl_demo_ui(disp); をexsamplesフォルダのそれぞれのサンプルプログラムのエントリに書き換えるだけで実行できます。ダウンロードしたファイルには、いくつか適当に記述しておきましたのでコメントをはずして実行してみてください。
サンプルプログラムのウィジェットはメモリが許す限りいくつでも同時に動かすことができます。(ウィジェットは組み合わせて使うものなので当たり前ですが)
また、spi_lcd_touch_test/managed_components/lvgl__lvgl/demos の下にあるデモプログラムも実行できます。まず spi_lcd_touch_example_main.c に #include "demos/lv_demos.h" を追加してください。(ダウンロードしたファィルには追加済みです)
次に idf.py menuconfig と入力して設定メニューを表示したら一番下の Component config を選択します。
さらに一番下にある LVGL configuration を選択します。
次に一番下の Demos を選んで次のように設定します。
このままではLVGLの作業メモリが足りないので、一度カーソルの左(←)を押して上のメニューに戻り Memory settongs を選んで Size of the memory … の値を32から48に変更します。
Qキーを押してセーブします。
spi_lcd_touch_example_main.c に lv_demo_widgets(); を記述します。ダウンロードしたファイルには記述してありますのでコメントを外してください。example_lvgl_demo_ui(disp); や他のexamples のエントリはコメントアウトした方がいいでしょう。
idf.py flash と入力してコンパイルと書き込みを行うとデモが開始されます。タッチパネルでスクロールさせて色々なウィジェットを操作できます。
idf.py menuconfig の設定で他のデモも動かせるので色々試してみてください。
自作のプログラムもデモプログラムと同様の方法で組み込むことができます。マイコンで作ったとは思えないような高度なGUIプログラムが作れますね。PSRAMのないESP32-WROOM-32Eでも上記のデモのようなものが動かせるくらいですから、かなり実用的なアプリケーションが作れそうです。
ちなみにWindowsのVisual studioでも上記のサンプルプログラムやデモを動かせます。
LVGL for Windows Visual Studio port
これを使えば自作のプログラムをPCで試作してマイコンに組み込むということもできます。
※コメント投稿者のブログIDはブログ作成者のみに通知されます