Raspberry Pi Pico 2でLVGL v9をセットアップ
以前液晶付きRaspberry Pi Pico 2互換ボードを購入したので、今回は組み込みでも使用できる軽量なUIライブラリであるLVGLのセットアップと使用方法の学習を行います。
LVGLとは

LVGL(Light and Versatile Graphics Library)は、組み込みでも使用できる軽量さが特徴のオープンソースのUIライブラリです。公式HPによれば"Smartphone-like UIs in kilobytes"、つまりkBオーダーでスマホのようなリッチなUIを作成できるらしいです。
前回記事ではWaveshare社が出しているLVGLのデモを動かしていたのですが、このデモがLVGL v8向けに書かれていて、しかも最新のv9では一部関数が変わり互換性がなくなっているようです。
というわけで、今回はLVGLの最新バージョンをRaspberry Pi Picoで使用する方法を、簡単な温度センサーデモの作成を通して確認します。
なお、今回作成したコードはGitHubで公開しております。
開発環境のセットアップ
まずは、Raspberry Pi Picoプロジェクトを作成し、そこにLVGLのGitHubからライブラリをクローン…してもいいんですが、せっかくなのでCMakeのFetchContentでビルド時に自動でクローンするようにします。最上位のCMakeLists.txtに以下のように設定しました。
include(FetchContent)
FetchContent_Declare(
lvgl
GIT_REPOSITORY https://github.com/lvgl/lvgl.git
GIT_TAG v9.3.0
)
FetchContent_MakeAvailable(lvgl)
target_compile_options(lvgl PRIVATE -w)
LVGLライブラリに関するコンパイル警告が出ても「俺は関係ない」状態なので、全警告をオフにしておきます。また、FetchContentはCMake 3.11から追加されたのでcmake_minimum_required
がVersion 3.11以降になっていることを確認しておきます。
次に、lvglの設定を記載するヘッダーファイルである"lv_conf.h"を作成します。これは、クローンしたディレクトリ内に"lv_conf_template.h"があるので、これをlvglフォルダがあるディレクトリにコピーして、ファイル名を"lvconf.h"にリネームします。
ファイルの冒頭に以下のような記載があるので、#if 1
に変更するとファイルが有効化されます。
lv_conf.h 6-15
/*
* Copy this file as `lv_conf.h`
* 1. simply next to `lvgl` folder
* 2. or to any other place and
* - define `LV_CONF_INCLUDE_SIMPLE`;
* - add the path as an include path.
*/
/* clang-format off */
#if 1 /* Set this to "1" to enable content */
ひな形を埋めるだけ
次にやることはLVGL公式ドキュメントの実装例をコピペし、「自分で実装してね」と書かれている箇所を埋めることです。
作成する必要があるのは以下の3つ。
- ディスプレイ初期化関数
your_driver_init
- 起動時からの絶対時間をミリ秒で返す関数
my_get_millis
- ディスプレイに描画データを送る関数
my_flush_cb
ディスプレイの初期化関数はWaveshare社が提供しているデモファイルから単にコピーすれば完了。
次に、起動後の絶対時間を返す関数は、Pico SDKのhardware_timer内にあるget_absolute_time()
関数で時間を取得し、それをto_us_since_boot()
関数でマイクロ秒に変換したものを1000で割ることで取得しました。なんか遠回りなことをしている気もするのでよりよい案があればぜひContributionをお願いします。また、もともとのデモファイルではlv_tick_inc
関数を定期的に呼び出していましたが、このように実装することでLVGLライブラリ側が管理してくれるようになります。
最後に、ディスプレイに描画データを送る関数については、おおむねデモコードそのままではあるんですが、LVGL v8との違いとして
- 一部変数の型が違う(
lv_disp_draw_buf_t
型がlv_display_t
型に、lv_color_t
型がなくなっている) - SPIのエンディアン入れ替え方法が違う(
#define LV_COLOR_16_SWAP 1
の代わりにエンディアン入れ替え関数lv_draw_sw_rgb565_swap
になっている)
など、割といろいろ変わっていたのでやや面倒でした。というか、この変更点に関する公式からの説明資料は見つけられなかったですし、LV_COLOR_16_SWAP
フラグはv9で削除されたかと思いきや再度追加されたようなので、正直LVGLライブラリそのものの使い勝手は微妙な気がします。
そして、LVGLのページを見ていたら、このマイコンボードに載っているドライバICであるST7735向けドライバがLVGLライブラリに内蔵されているようなので、もっと簡単に実装できた気がします。気が向いたらこちらでの実装に切り替えたい…
デモンストレーション
以上の関数をライブラリとしてまとめ、mainから呼び出す形としました。
そして、LVGLのデモとしてRP2350内蔵の温度センサの値を読み取り、それを目盛付きバーとラベルで表示するプログラムを作成しました。

LVGLのドキュメントにあるデモをコピペしてちょっと変更するだけでサクッとそれっぽいのが作れたのですが、内蔵の温度センサの値は室温とはかけ離れているのでシステム監視以外には使えないですね…