2025年8月3日日曜日

EEZ StudioとArduino IDEでGUIを作ってみた

 この前ESP32-S3を張り替えたJC4827W543Cだけど、ROMも8MBにアップグレードしたことだしEEZ StudioでGUIアプリを作ってみることに。逆にArduino IDEだけでGUI作るの大変そう。

まずはEEZ Studioのインストール。とりあえずWindows用のexeファイルをダウンロードしたらインストーラーに従ってインストールできた。
起動するとHomeが表示されるのでLVGLを選んで、Nameにプロジェクト名をいれて、LVGL VerisionはArduino IDEにインストールするLVGLバージョンに合わせて選択する。今回は最新版を使用した。プロジェクトの保存先は覚えておかないとuiフォルダの中身をArduinoのプロジェクトにコピーする時困るので気をつけないと。

プロジェクトを作成したらまずはSettingsでDisplay widthとheightをNV3041Aに合わせるために480と272に変更する。あとはBuildのところでLVGL includeをlvgl.hに変更しておく。Mainタブに戻っても最初に作られた画面の解像度は自動で修正されないのでこちらも同じ画面に修正した。とりあえず適当にボタンを追加してみた。

スパナのマークを押すとソースファイルがプロジェクトフォルダの中のuiフォルダに生成される。これをArduinoのプロジェクトフォルダにコピーしてやる感じ。

ということで次はArduino側のプロジェクトを作成する。lvglライブラリはEEZ Studioで指定したバージョンをArduino IDEからインストールしておく。他にArduino_GFXライブラリとタッチパネルのGT911用にTouchLibライブラリが必要だった。

inoファイルの中身は

#include <lvgl.h>
#include <Arduino.h>
#include <Arduino_GFX_Library.h>
#include "touch.h"
#include "ui.h"

#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272

#define LCD_BL 1

Arduino_DataBus *bus = new Arduino_ESP32QSPI(45, 47, 21, 48, 40, 39);
Arduino_GFX *gfx = new Arduino_NV3041A(bus, GFX_NOT_DEFINED, 0, true);
static lv_color_t buf1[SCREEN_WIDTH * 40];

void my_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
{
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px_map, w, h);

    lv_display_flush_ready(disp);
}

void my_touch_read(lv_indev_t *indev, lv_indev_data_t *data)
{
    if (touch_has_signal() && touch_touched())
    {
        data->state = LV_INDEV_STATE_PRESSED;
        data->point.x = touch_last_x;
        data->point.y = touch_last_y;
    }
    else
    {
        data->state = LV_INDEV_STATE_RELEASED;
    }
}

void backlight_init()
{
    pinMode(LCD_BL, OUTPUT);
    digitalWrite(LCD_BL, HIGH);
}

void lvgl_init_all()
{
    if (!gfx->begin()) {
        Serial.println("gfx begin failed!");
    }
    gfx->fillScreen(0x0000);
    backlight_init();

    touch_init(gfx->width(), gfx->height(), gfx->getRotation());

    lv_init();

    lv_display_t *disp = lv_display_create(SCREEN_WIDTH, SCREEN_HEIGHT);
    lv_display_set_buffers(disp, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);
    lv_display_set_flush_cb(disp, my_flush_cb);
    lv_display_set_default(disp);
    lv_indev_t *indev = lv_indev_create();
    lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
    lv_indev_set_read_cb(indev, my_touch_read);
    lv_indev_set_display(indev, disp);
}

void setup()
{
    Serial.begin(115200);
    Serial.println("START");

    lvgl_init_all();
    ui_init();
    Serial.println("EEZ started");
}

void loop()
{
    lv_timer_handler();
    ui_tick();
    lv_tick_inc(5);
    delay(5);
}

こんな感じにしてみた。バックライトはとりあえず輝度固定。あとはタッチパネル用にtouch.hをDemoから頂戴してきてプロジェクトフォルダに放り込む。そんでもってEEZ Studioで生成したuiフォルダのhファイルとcファイルをすべて同じところに放り込む。

あとはビルドして書き込めば完成。最初なかなか映らなくて困っていたんだけど、loopのなかにlv_tick_inc(5);を入れ忘れいていただけだったorz.

EEZ Studioを使うと簡単にUIが作れるので便利かも。

0 件のコメント:

コメントを投稿