M5StackでLVGLを使っているサンプルってあまりない。
モニタ搭載のマイコンキットで構成ので入手性が良いのに日本語のドキュメントがあまりないからだろう。
LVGLのマニュアル分かり難いんだよ
Add LVGL to Your ProjectってLVGLの公式のドキュメントを読めばそれなりに書いてあるんだけど分かり難い。
必要な作業
- lv_conf.h の作成
- ディスプレイの登録
とりあえずこの2工程でLVGLが動作します。
・lv_conf.h の作成
platformioで開発している場合はLibraresから登録するとlv_conf_template.hが登録されているのでlv_conf.h にリネームして中を編集する。
(M5 CARDPUTER(Stamp S3)だとデフォルトで動いた。)
・ディスプレイの登録
M5stackというかArduino用のサンプルが
\lvgl\examples\arduino\LVGL_Arduino
に置いてある。LVGL_Arduino.inoを参考にmian.cppを編集するといい。
Connecting LVGL to Your Hardwareに編集方法が書いてあるがやはり分かり難い。
具体的にはDisplay Interfaceの登録とTick Interfaceの登録。
LVGLの最終出力先はLCDなので、最初にディスプレイを使えるようにする必要がある。
M5 CARDPUTERはM5GFXが標準で使われているので
M5GFX display;
M5Canvas canvas(&display);
display.begin();
のようにして有効化。(意外とこれを忘れがちみたいで公式のドキュメントにも書いてある。)
続いてLVGLの設定をする。
LVGLに設定するdefineを追加
#define TFT_HOR_RES 240
#define TFT_VER_RES 135
#define TFT_ROTATION LV_DISPLAY_ROTATION_90
#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
こんな感じでデイスプレイを登録
lv_display_t * disp;
disp = lv_display_create(TFT_HOR_RES, TFT_VER_RES);
lv_display_set_flush_cb(disp, my_disp_flush);
lv_display_set_buffers(disp, draw_buf, NULL, sizeof(draw_buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
LVGLと実際のディスプレイを次の関数で接続する
void my_disp_flush( lv_display_t *disp, const lv_area_t *area, uint8_t * px_map)
{
uint32_t width = (area->x2 - area->x1 + 1);
uint32_t height = (area->y2 - area->y1 + 1);
lv_draw_sw_rgb565_swap(px_map, width*height);
display.startWrite();
display.pushImageDMA<uint16_t>(area->x1, area->y1, width, height, (uint16_t *)px_map);
canvas.pushSprite(0, 0);
display.endWrite();
lv_display_flush_ready(disp);
}
最後に定期的にLVGLを更新するためにTickを登録する。
static uint32_t my_tick(void)
{
return millis();
}
で lv_tick_set_cb(my_tick); としてLVGLに登録する。
lv_timer_handler();をloop()で定期的に呼び出すとLVGLは動作する。
全然最適化していないけど、最低限これだけで動作するので試してみて欲しい。