結論
-
lv_conf.h
を設定する。 - arduino向けのサンプルは
LVGL/examples/arduino/LVGL_Ardino/LVGL_Arduino.ino
にある。 - ディスプレイとタッチパネルの実装を行う必要がある。
- ディスプレイの実装テンプレは
LVGL/examples/porting/lv_port_disp_template.{h,c}
にある。 - 入力デバイスの実装テンプレは
LVGL/examples/porting/lv_port_indev_template.{h,c}
にある。
- ディスプレイの実装テンプレは
前提条件
- 使用するデバイスはM5Stack Core2
- 開発環境はPlatformIO (Windows10)
- 使用するライブラリは以下のふたつ
- LovyanGFX
- LVGL
実装結果
githubに置きました。LVGLのサンプルコード由来の部分はもとのMITライセンスに準拠します。
追加実装部分はPDにしますのでご自由にお使いいただけます。
解説
M5Stack Core2のディスプレイを有効活用したい。
LVGLという組み込み向けのライブラリがあるため、これを試してみたが、
対応させるための手順がそこそこあり、またそのための情報が断片的であったため試した結果を記していく。
公式ドキュメントの読解
Arduino開発の際の手順は以下のページにある。
まずはlv_conf.h
の作成を行う。
Arduino向けのサンプルはexamolesの下にあり、
LVGL/examples/arduino/LVGL_Ardino/LVGL_Arduino.ino
となる。
が、そのままでは動かない。
ディスプレイの設定と入力デバイスの実装が必要になる。
そのための設定は以下のページにある。
実はテンプレートがある
よく読むと"Further Reading"にテンプレの場所が書いてある。
LVGL/examples/porting
の下にいくつかファイルがある。
lv_port_disp_template.{h,c}
がディスプレイ、
lv_port_indev_template.{h,c}
が入力デバイスとなる。
ディスプレイの実装
MY_DISP_{HOR,VER}_RES
という定数が求められる箇所があるため宣言する。
lv_port_disp_init()
の中で"Example for 1)"みたいな箇所があるが、
どれか一つだけにして残りはコメントアウトする。
disp_init()
とdisp_flush()
が自分で書く部分。
LovyanGFXを使うと以下のように書ける。
(lcdは事前に宣言しておくこと)
/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
/*You code here*/
lcd.init();
lcd.setBrightness(128);
lcd.setColorDepth(24);
}
/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
int32_t width = area->x2 - area->x1 + 1;
int32_t height = area->y2 - area->y1 + 1;
lcd.setAddrWindow(area->x1, area->y1,
width, height);
lcd.pushPixels((uint16_t*)color_p, width * height, true);
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
タッチパネルの実装
入力デバイスのうち、今回はタッチパネルだけ実装する。
ボタンもできると思うが一旦後回し。
テンプレートからタッチパネルに関連する以外のものを消しておく。
自分で書く部分はtouchpad_init()
とtouchpad_is_pressed()
とtouchpad_get_xy()
。
だが、M5Stackの場合M5.begin()
で初期化されるためinitは空にしておく。
残りの実装は以下のように書ける。
/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{
/*Your code comes here*/
return M5.Touch.ispressed();
}
/*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
{
/*Your code comes here*/
TouchPoint_t coordinate;
coordinate = M5.Touch.getPressPoint();
(*x) = coordinate.x;
(*y) = coordinate.y;
}
課題
汎用的に使えるライブラリ化を検討したが、主に理解不足により以下のような部分で躓いている。
lv_conf.h
をLVGLのライブラリの外におく方法が今のところわからない。
LV_CONF_INCLUDE_SIMPLE
をdefineせよ、と書いてあるが意図した挙動になっていない。
portingテンプレートも別ファイルにしたいが、
グローバル領域に置いてある変数があり、
ファイル分割できちんとスコープが通るかどうかがあやしく、現状できていない。
また、LVGLのデモコードを試していたが今の所動かせていない。
void*
を他の構造体にキャストするなど結構怖い部分があり、platformioでは弾かれている。
extern "c"
をつければいけるか?