LvGL 9.3.0 on Wio Terminal
Wio Terminal でLvGL v9.3.0
これまで9.3.0-dev
だった9.3.0
となり、
本記事では、
前提要件
-
Wio があることTerminal -
Arduino があることIDE -
Arduino からIDE Wio にスケッチを書き込めることTerminal
この要件には、 の設定にてIDE https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
を指定する必要があります。これにより、次の要件が自動的に満足されるはずです。-
Seeed_Arduino_LCD
がインストールされていること
-
-
Arduino の「ライブラリマネージャー」でIDE (LvGL )をインストールしていることv9.3.0
(上の画像を参照) -
TFT_eSPI
をインストールしていないこと
なお、
LvGL の設定
lv_conf_template.h
というファイルをコピーし、libralies
フォルダー(lv_conf.h
に変更します。
以降、このlv_conf.h
の内容を編集します。
1. 設定ファイルを有効にする
始めはこの箇所が0
になっており、ファイルの内容が全て無効になっています。コメントにある通り、1
に変更します。
#if 1 /* Set this to "1" to enable content */
2. TFT_eSPI
を有効にする
本記事では、Seeed_Arduino_LCD
を併用することでTFT_eSPI.h
をインクルードして利用します。従って、本家のTFT_eSPI
が存在すると、TFT_eSPI.h
という同名のファイルが存在することでエラーになります。
0
とあるので、1
に変更します。
#define LV_USE_TFT_ESPI 1
正規の設定は以上です。
リンクエラーへの対処
設定を終えたらサンプルプログラムで動作確認したいところですが、現段階ではリンクエラーが起こります。
c:/users/⋯/appdata/local/arduino15/packages/seeeduino/tools/arm-none-eabi-gcc/7-2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: error: C:\Users\⋯\AppData\Local\arduino\sketches\2D6F468B41CA3D5D12AB3EBD59EEB1C7\libraries\lvgl\draw\sw\blend\helium\objs.a(lv_blend_helium.S.o): Conflicting CPU architectures 13/0
c:/users/⋯/appdata/local/arduino15/packages/seeeduino/tools/arm-none-eabi-gcc/7-2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: failed to merge target specific data of file C:\Users\⋯\AppData\Local\arduino\sketches\2D6F468B41CA3D5D12AB3EBD59EEB1C7\libraries\lvgl\draw\sw\blend\helium\objs.a(lv_blend_helium.S.o)
c:/users/⋯/appdata/local/arduino15/packages/seeeduino/tools/arm-none-eabi-gcc/7-2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: error: C:\Users\⋯\AppData\Local\arduino\sketches\2D6F468B41CA3D5D12AB3EBD59EEB1C7\libraries\lvgl\draw\sw\blend\neon\objs.a(lv_blend_neon.S.o): Conflicting CPU architectures 13/0
c:/users/⋯/appdata/local/arduino15/packages/seeeduino/tools/arm-none-eabi-gcc/7-2017q4/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: failed to merge target specific data of file C:\Users\⋯\AppData\Local\arduino\sketches\2D6F468B41CA3D5D12AB3EBD59EEB1C7\libraries\lvgl\draw\sw\blend\neon\objs.a(lv_blend_neon.S.o)
collect2.exe: error: ld returned 1 exit status
次のフォルダのライブラリlvglバージョン9.3.0-devを使用中:C:\⋯\libraries\lvgl
exit status 1
Compilation error: exit status 1
原因は、エラーメッセージにある通り二つのアセンブリーファイルです。
私の試行錯誤した限りでは、設定でこのエラーを解消することは出来ないだろうと結論付けます。
対処法その一:削除
原因となる二つのファイルを削除・移動・拡張子変更するなどして、コンパイル対象から除外します。これにより、リンクエラーが解消します。どうせ
対処法その二:編集
各ファイルに次の四行だけ追加します。
#else
.thumb
.text
nop
具体的には次のようになります。
中略
︙
export_set argb8888, argb8888, 32, 32, normal
#else
.thumb
.text
nop
#endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_HELIUM && defined(__ARM_FEATURE_MVE) && __ARM_FEATURE_MVE && LV_USE_NATIVE_HELIUM_ASM*/
中略
︙
export_set argb8888, argb8888, 32, 32, normal
#else
.thumb
.text
nop
#endif /*LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_NEON*/
これで、破壊せずにリンクエラーを解消できました。
動作確認
サンプルプログラムで動作確認したいところですが、そのままでは画面の表示が崩壊します。
原因はこの箇所です。
次の通りに編集することで、意図通り表示されます。
#define TFT_HOR_RES 240
#define TFT_VER_RES 320
#define TFT_ROTATION LV_DISPLAY_ROTATION_270
縦と横が逆になるのは、一体何の不具合なのでしょうか。
プログラム
本記事では、簡単のため次のようにプログラムを修正しました。上述の箇所のみ変更前と後を残しています。
但し、一点変更しています。
この通り、画面にはHello Arduino, I'm LVGL!
と表示されるようになっています。これが味気ないので、バージョン情報を含んだ文字列を表示させることにしました。
#include <lvgl.h>
#include <TFT_eSPI.h>
// before:
// #define TFT_HOR_RES 320
// #define TFT_VER_RES 240
// #define TFT_ROTATION LV_DISPLAY_ROTATION_0
// after:
#define TFT_HOR_RES 240
#define TFT_VER_RES 320
#define TFT_ROTATION LV_DISPLAY_ROTATION_270
#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
void my_disp_flush( lv_display_t *disp, const lv_area_t *area, uint8_t * px_map) { lv_display_flush_ready(disp); }
static uint32_t my_tick(void) { return millis(); }
void setup() {
lv_init();
lv_tick_set_cb(my_tick);
lv_display_t * disp;
disp = lv_tft_espi_create(TFT_HOR_RES, TFT_VER_RES, draw_buf, sizeof(draw_buf));
lv_display_set_rotation(disp, TFT_ROTATION);
String LVGL_Arduino = "Hello Arduino! ";
LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
lv_obj_t *label = lv_label_create( lv_screen_active() );
lv_label_set_text( label, LVGL_Arduino.c_str() );
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
}
void loop()
{
lv_timer_handler();
delay(5);
}
v7.0.2 との比較
これまで、Seeed_Arduino_LvGL
を使っていました。その際用いたサンプルプログラムはこちらになります。
異なるリポジトリーを参照していますが、その経緯は以前投稿したこちらの記事をご覧ください。
さて、こちらも無駄な記述を省いて簡略化しましょう。
#include <lvgl.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors(&color_p->full, w * h, true);
tft.endWrite();
lv_disp_flush_ready(disp);
}
bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data) {
static int32_t last_diff = 0;
int32_t diff = 0;
int btn_state = LV_INDEV_STATE_REL;
data->enc_diff = diff - last_diff;;
data->state = btn_state;
last_diff = diff;
return false;
}
void setup() {
lv_init();
tft.begin();
// before
// tft.setRotation(1);
// after
tft.setRotation(3);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 320;
disp_drv.ver_res = 240;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = read_encoder;
lv_indev_drv_register(&indev_drv);
lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);
// before
// lv_label_set_text(label, "Hello Arduino! (V7.0.X)");
// after
String LVGL_Arduino = String::format("Hello Arduino! V%d.%d.%d", LVGL_VERSION_MAJOR, LVGL_VERSION_MINOR, LVGL_VERSION_PATCH);
lv_label_set_text(label, LVGL_Arduino.c_str());
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
}
void loop() {
lv_task_handler();
delay(5);
}
実際にこれらを実行して分かる違いとして、それぞれの容量があります。
バイト数 | ||
占有率 |
成果物は殆ど同じものであるにも拘らず、その容量は約
正に一長一短と言うべきものですが、容量については気を配って開発する必要がありそうです。
Discussion