Zenn
🍫

【Wio Terminal】LvGLのまともなサンプルプログラム

2025/02/16に公開

WioWio TerminalTerminalLvGLLvGL

WioWio TerminalTerminalは、SeeedSeeed StudioStudio製のシングルボードコンピューターです。所謂ArduinoArduinoの類ですが、本記事で話題にする画面を始め、実に様々な周辺機器を搭載しています。

Realtek RTL8720DNによりBluetoothとWi-Fiが利用可能、IoTプロジェクトのバックボーンを提供します。
また、 2.4インチ LCD スクリーン、IMU(LIS3DHTR)、マイクロフォン、ブザー、microSDカードスロット、照度センサ、赤外線発光器(IR 940 nm)を搭載し、さらにGroveシステム用の多機能Groveポート2個と、Raspberry Pi 40ピン互換のGPIOを使ってモジュールを追加できます。

(スイッチサイエンス販売ページより)

一方でLvGLLvGLは、図形描画や画面構成の術を提供するもの(らしい)です。

https://lvgl.io/

個人的には、画面を作る手段といえばHTMLHTMLTkTkという先入観がありました。しかしWioWio TerminalTerminalでは、そうした(ある種)高級な財産が使えません。

本稿は、WioWio TerminalTerminalLvGLLvGLを扱う上での「出発点に至るまで」を述べるものです。本題は少し遠いのでご注意下さい。先に結論を述べると、「この記事と同じ轍を踏むな」という言に尽きます。

初等画面制御:TFTTFT_eSPIeSPI

https://wiki.seeedstudio.com/Wio-Terminal-LCD-Overview/

リンク先にも出てくる語、TFTTFT LCDLCDとは、ThinThin FilmFilm TransistorTransistor LiquidLiquid CrystalCrystal DisplayDisplay (薄膜トランジスター液晶画面)の略です。要するに画面のことです。

TFT_eSPIを基にしたSeeed_Arduino_LCDというライブラリーが提供されています。使い方を詳しく説明することはありませんが、これ自体の導入は必要です。

環境構築

開発環境はArduinoArduino IDEIDEです。有名なソフトウェアですから、本記事では説明を省きます。

  1. GitHubGitHubからSeeed_Arduino_LCDをダウンロードする

zipダウンロード
<> CodeからDownload ZIPZIPZIPファイルをダウンロードできる
(https://github.com/Seeed-Studio/Seeed_Arduino_LCD)

  1. ArduinoArduino IDEIDEに追加する

zip追加

  1. Adafruit Zero DMAを追加する

こちらはGitHubGitHub関係なく、ArduinoArduino IDEIDEでの操作です。

Adafruit Zero DMA追加
下のAdafruit Zero DMA library by Adafruitを追加する

実用例

https://wiki.seeedstudio.com/Wio-Terminal-LCD-Graphics/

基礎となる画面制御の例が示されています。

DrawingDrawing PixelsPixels」は点を描くもの、「DrawingDrawing LinesLines」は線を描くものといったように、座標を指定することで自由自在に図形や文字を描画することができます。

しかし、突然自由を与えられても何を作ればよいのか困る、というのが忌憚ない素直な所感でした。搗てゝ加えて、自由すぎて定型がなく、高級なそれしか知らない身としては頗る不便とも感じました。これをどうにか工夫された先人は数多あるようですが、公式であるSeeedSeeed StudioStudioもまた、利便性を上げるものとして紹介するものがあります。

高級画面制御:LvGLLvGL

https://wiki.seeedstudio.com/Wio-Terminal-LVGL/

Seeed_Arduino_LvGLというライブラリーが提供されています。第三者の作ったものよりも、公式が提供するものを使う方が安心するのは、素人ゆえでしょうか。

LvGLLvGLとは何者か

先にも触れた通り、LvGLLvGLは画面に関するライブラリーですが、今は令和の御代、JavaJavaSwingSwingPythonPythonTkinterTkinter(やTkEasyGUITkEasyGUI)、果てはあらゆる言語に波及しつつあるWebViewWebView(HTMLHTML等々)など、既に便利なものは溢れています。

世に高級なそれらが溢れて猶も淘汰されないのは、LightLight(軽量)と謳うように、OSOSの無い「組込みシステム」の需要に応えているためでしょう。WioWio TerminalTerminal始めArduinoArduinoの類は、(基本的には)OSOSの存在しない、所謂「barebare metalmetal」です。処理能力も低く、記憶容量も寡少と、悉く恵まれないのが「組込みシステム」です。

貧弱な環境では、絢爛豪華なものは「狭すぎて入らない」、「重すぎて動かない」という結末になりがちです。従って、性能は慎ましいながらも「軽量で動かしやすい」、「容量が嵩張らない」といったものが台頭するのです。

描画例

組込みシステム向けではありますが、WebWeb上でもその様子を体験することができます。一つ一つの読み込みには時間が掛かるようですから、気長に構えてご覧ください。

https://docs.lvgl.io/latest/en/html/examples.html

WioWio TerminalTerminalにおけるLvGLLvGLの問題点

例をご覧になればお分かりでしょう、ボタンを押したり、スライダーを滑らせたり、人間の手で操作できる機能が揃っています。これを使えば、実に様々なアプリケーションを作れるでしょう。

而して残念ながら、WioWio TerminalTerminalの搭載する画面はタッチスクリーンではありません。ボタンを映しても、私たちの手がそこに触れることは叶いません。これに端を発し、幾つか問題が見つかりました。

そもそもタッチスクリーンではない

上述の通り、WioWio TerminalTerminalの画面は描画(出力)のみであり、操作(入力)はできません。しかしながら、筐体にボタンが三つ、画面下にスイッチ、更に内部には幾つものセンサーを有し、無線通信もできることを踏まえると、入力の手段は多種多様に用意されています。これだけあれば、画面はその情報を映す出力のみでも充分かもしれません。

Wio Terminal外観

Wio Terminal内容
引用:https://www.switch-science.com/products/6360

バージョン互換

先に紹介した描画例にはご親切にプログラムコードも付記されていますが、これらはSeeed_Arduino_LvGLを使う場合、コンパイルエラーとなります。この嘆かわしい実情は、Seeed_Arduino_LvGLに内包されているLvGLLvGLと、最新のLvGLLvGLとのバージョンが乖離していることが原因です。

こちらはSeeed_Arduino_LvGLのものです。"version": "v7.0.2"とあります。

https://github.com/Seeed-Studio/Seeed_Arduino_LvGL/blob/master/src/library.json

一方こちらは最新のものです。"version": "9.3.0-dev"とあり、メジャーアップデートを既に8899と経ていることが分かります。

https://github.com/lvgl/lvgl/blob/master/library.json

使い方が分かりにくい

どこぞのYewYewもそうでしたが、バージョン互換が無いだけではなく、当初は「そもそもどうやって実行するのか」が分かりませんでした。

単純な話から始めましょう。ArduinoArduinoのプログラム(スケッチ)は次の定型を持ちます。

void setup() {
    /* code */
}

void loop() {
    /* code */
}

しかし例のコードはその構造を持ちません。

https://github.com/lvgl/lvgl/blob/master/examples/get_started/lv_example_get_started_2.c

つまり、これを上手くスケッチと組み合わせる手間があります。しかしその方法がまだわかりません。そこで探してみると、ArduinoArduinoスケッチと思われるサンプルプログラムが見つかります。

https://github.com/lvgl/lvgl/blob/master/examples/arduino/LVGL_Arduino/LVGL_Arduino.ino

これで一応実行方法が判明しました。しかし、これらの苦節を経て得られる成果とは即ち、「バージョン互換が無さすぎてコンパイルできない」という失望です。

LvGLLvGLが齎すエラーの例

今参看していたLvGLLvGLv9.3.0ですが、先述の通りSeeed_Arduino_LvGLの内包するLvGLLvGLv7.0.2です。メジャーアップデートを経ているだけのことはあり、「複数色を用いたグラデーション」を始め、v7.0.2には未実装だった新機能が幾つか在ります。例えばlv_grad_dsc_tという構造体(型)は、v7.0.2には在りません。当然、そうした機能は「無い」ので使えません。

https://github.com/lvgl/lvgl/blob/9760d5754066616a64549b739a2e6934ff46590f/src/misc/lv_grad.h#L58-L91

また、バージョンアップによって簡略化された、純粋な改善の跡も見られます。

new
lv_obj_center(obj);

objectを中央に配置する関数ですが、v7.0.2では下のように記述が煩雑でした。

old
lv_obj_align(obj, NULL, LV_ALIGN_CENTER, 0, 0);

ここまでは理解の範疇です。

ここからは怨嗟で詭激を禁じ得ませんが、改名された者共のなんと夥多たるや。のべつ幕なしといったように未定義エラーが湧いて出てきます。

その代表格は此奴です。

https://github.com/lvgl/lvgl/blob/master/examples/arduino/LVGL_Arduino/LVGL_Arduino.ino#L132

画面には基礎として大元となる要素が一つあり、この上にボタンやテキストを追加します。何も、無に対してボタンを配置するのではありません。HTMLHTMLではbodyTkinterTkinterではrootの名で見ることができます。
このプログラムは、大元の要素lv_screen_active()で参照しています。こうして、大元の要素の上にlabel(テキストエリアのようなもの)を作っているのです。

このようにlv_screen_active()は重要な関数ですが、こちらv7.0.2には存在しませんので、未定義の関数であるとしてエラーになります。根幹に関わる関数であるだけに、無視することはできません。

このように改名されたのであれば、改名以前は何であったのかを調べる外有りません。しかし、等を躐えるようなことばかり強いられるわりには、吾々は未だ一度たりともLvGLLvGLが動いた姿を見ていません。

物知りなサンプルプログラム

敢えて最後まで隠しておいたものですが、Seeed_Arduino_LvGLにもサンプルプログラムがあります。こちらはしっかり動きます。

  1. benchmark

https://github.com/Seeed-Studio/Seeed_Arduino_LvGL/tree/master/examples/benchmark

Bench Mark
引用:https://files.seeedstudio.com/wiki/Wio-Terminal-LVGL/benchmark.gif

  1. lv_test_stress

https://github.com/Seeed-Studio/Seeed_Arduino_LvGL/tree/master/examples/lv_tests/lv_test_stress

stress test
引用:https://files.seeedstudio.com/wiki/Wio-Terminal-LVGL/stress.gif

動くのですが、動けばよいという話ではなく、動かし方を知りたいのです。比較的ファイル数が少ないのは後者ですので、こちらを取り挙げます。が、何故かタッチスクリーンに関わっていそうな記述があります。未だにこの意図が分かりません。教えてください。

https://github.com/Seeed-Studio/Seeed_Arduino_LvGL/blob/master/examples/lv_tests/lv_test_stress/lv_test_stress.ino#L85-L90

さて、このプログラムの中でタッチスクリーンの箇所は不要として、他の箇所は一体必要なのか、それとも不要なのか、当初は判別できませんでした。今でこそ、この辺りが必要そうだという見当が付きますが、これは後述の答えを知ってからの事です。

https://github.com/Seeed-Studio/Seeed_Arduino_LvGL/blob/master/examples/lv_tests/lv_test_stress/lv_test_stress.ino#L61-L83

また、このプログラムにおいて、描画の仕組みはlv_demo_stress()によって呼び出されています。

https://github.com/Seeed-Studio/Seeed_Arduino_LvGL/blob/master/examples/lv_tests/lv_test_stress/lv_test_stress.ino#L91-L92

lv_demo_stress()は、obj_test_task_cb()をタスクとして作成しています。

https://github.com/Seeed-Studio/Seeed_Arduino_LvGL/blob/master/examples/lv_tests/lv_test_stress/lv_demo_stress.c#L42-L44

つまりobj_test_task_cb()を見ればよいわけですが、400400行もあるので見る気が失せます。長すぎてZennZennのプレビューにも収まらないようです。

これら二つのサンプルプログラムは大層なもので結構ですが、単純明快な話から始めて貰わなければ、一体何を言っているのか分かりません。そして、何故か斯様に複雑なものばかりあって、単純なものはないのです。

本題:チュートリアル

実はSeeed_Arduino_LvGLを紹介するページには、lv_arduinoと記されたリンクがあります。

lv_arduinoのリンク

このリンクが示す先は、lv_arduinoというライブラリーです。

https://github.com/lvgl/lv_arduino

これを見てみると、LvGLLvGLのバージョンがSeeed_Arduino_LvGLと一致しています。

https://github.com/lvgl/lv_arduino/blob/master/src/library.json

つまり、これに付属したサンプルプログラムならば、動く見込みがあるのです。

サンプルプログラム

https://github.com/lvgl/lv_arduino/blob/master/examples/ESP32_TFT_eSPI/ESP32_TFT_eSPI.ino

こちらは確かに動きます。

https://github.com/lvgl/lv_arduino/blob/master/examples/ESP32_TFT_eSPI/ESP32_TFT_eSPI.ino#L81

こうあるように、画面にHello Arduino! (V7.0.X)と表示されるだけの、単純明快なプログラムです。同梱されている画像にその様子がありますが、古いのかV6.0とあります。

実行例
引用:https://github.com/lvgl/lv_arduino/blob/master/extras/img/lvglarduino.jpg

これで、ようやく定型が分かりました。

チュートリアルを終えて

チュートリアルを終え、LvGLLvGLの使い方が分かってきましたが、これから待っているのは敢えて古いバージョンの情報を探す作業です。しかし折角最新の例が充実しているのですから、最新のものを使いたいと考えるのが自然ではないでしょうか。

なんと、実践せられている先達の記事がございました。WioWio TerminalTerminalの記事でこそありませんが、最新バージョンへの乗り換えが現実味を帯びて参りました。

https://zenn.dev/akihiro_ya/articles/25f37c3075f4bc

今回の成果は納得できるものではありませんでした。茲に筆を置いたら早速、不倶戴天のSeeed_Arduino_LvGLを除去し、最新のLvGLLvGLが使えないか試すこととします。

Discussion

ログインするとコメントできます