본문 바로가기

ESP32

ESP32에서 LVGL을 사용하는 단계별 가이드

반응형

 

ESP32에서 LVGL을 사용하는 단계별 가이드

 

LVGL(Light and Versatile Graphics Library)은 임베디드 시스템에 매력적이고 상호작용성이 뛰어난 사용자 인터페이스를 제공하도록 설계된 오픈 소스 임베디드 그래픽 사용자 인터페이스(GUI) 라이브러리입니다. LVGL GUI 라이브러리를 사용하면 개발자는 ESP32에서 인상적인 그래픽 인터페이스를 쉽게 제작하여 사용자 경험을 향상시킬 수 있습니다. ESP32에서 LVGL GUI 라이브러리를 사용하는 방법에 대한 이 튜토리얼은 "Arduino IDE에서 ESP32를 사용하여 LCD 디스플레이 제어"를 기반으로 합니다. LCD 화면을 사용하기 전에 TFT_eSPI 라이브러리가 3.5인치 LCD 화면을 제대로 구동하는지 확인하는 것이 좋습니다.

 

 

LVGL 및 lv_examples 라이브러리 설치

 

  1. Arduino IDE를 엽니다.
  2. "도구" 메뉴로 이동하여 "라이브러리 관리..."를 선택합니다.
  3. 라이브러리 관리자의 검색 상자에 "lvgl"을 입력하고 Enter 키를 누릅니다.
  4. 라이브러리 관리자에 사용 가능한 LVGL 라이브러리가 표시됩니다. "lvgl" 라이브러리를 찾아 오른쪽의 "설치" 버튼을 클릭하세요. 설치가 완료될 때까지 기다리세요.
  5. 같은 과정을 반복하여 "lv_examples"를 검색하여 설치하세요.

 

LVGL 구성

 

  1. Arduino IDE에서 프로젝트를 엽니다.
  2. "스케치" 메뉴 -> "스케치 폴더 표시"로 이동하여 프로젝트가 있는 폴더를 엽니다.
  3. 프로젝트 폴더의 상위 디렉터리로 이동하여 "libraries" 폴더를 찾아 해당 폴더로 이동합니다.
  4. "lvgl" 폴더로 이동하여 "lv_conf_template.h" 파일을 찾아 복사합니다.
  5. 상위 디렉터리, 즉 "libraries" 폴더로 돌아갑니다.
  6. "libraries" 폴더에 복사한 "lv_conf_template.h" 파일을 붙여넣고 이름을 "lv_conf.h"로 바꿉니다.

 

lv_conf.h 파일을 다음과 같이 수정합니다.

 

10 line  1로 설정

 

#if 1 /*Set it to "1" to enable content*/

 

 

23번째 줄에 모니터 크기를 입력합니다.

 

#define LV_HOR_RES_MAX          (480)
#define LV_VER_RES_MAX          (320)

 

303번째 줄에서 LV_TICK_CUSTOM을 1로 설정합니다.

 

#define LV_TICK_CUSTOM     1

 

384번째 줄에서 나열된 모든 글꼴을 1로 설정합니다.

 

#define LV_FONT_MONTSERRAT_8     1
#define LV_FONT_MONTSERRAT_10    1
#define LV_FONT_MONTSERRAT_12    1
#define LV_FONT_MONTSERRAT_14    1
#define LV_FONT_MONTSERRAT_16    1
#define LV_FONT_MONTSERRAT_18    1
#define LV_FONT_MONTSERRAT_20    1
#define LV_FONT_MONTSERRAT_22    1
#define LV_FONT_MONTSERRAT_24    1
#define LV_FONT_MONTSERRAT_26    1
#define LV_FONT_MONTSERRAT_28    1
#define LV_FONT_MONTSERRAT_30    1
#define LV_FONT_MONTSERRAT_32    1
#define LV_FONT_MONTSERRAT_34    1
#define LV_FONT_MONTSERRAT_36    1
#define LV_FONT_MONTSERRAT_38    1
#define LV_FONT_MONTSERRAT_40    1
#define LV_FONT_MONTSERRAT_42    1
#define LV_FONT_MONTSERRAT_44    1
#define LV_FONT_MONTSERRAT_46    1
#define LV_FONT_MONTSERRAT_48    1

 

lv_examples 구성

 

LVGL 구성과 마찬가지로 "lv_examples" 폴더를 찾아 복사하여 "libraries" 폴더에 붙여넣고 이름을 "lv_ex_conf.h"로 바꿉니다.

 

lv_ex_conf.h 파일을 다음과 같이 수정합니다.

 

라인 10에서 1로 설정

 

#if 1 /*Set it to "1" to enable the content*/

 

 

여기서는 성능 테스트에 사용되는 benchmark와 music을 활성화하고, 음악 플레이어인 music을 활성화하려면 다음 값을 1로 설정합니다.

 

#define LV_USE_DEMO_BENCHMARK   1

 

#define LV_USE_DEMO_MUSIC      1

 

 

메인 파일 작성

 

다음 내용이 포함된 main.ino 파일을 엽니다.

 

#include <Arduino.h>
//#include "./includes/oled.h"
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <lv_examples.h>
// extern Adafruit_SH1106G display;
TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
#if USE_LV_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char *file, uint32_t line, const char *dsc)
{
  Serial.printf("%s@%d->%s\r\n", file, line, dsc);
  Serial.flush();
}
#endif
/* Display flushing */
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);
}
/*Read the touchpad*/
bool my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  uint16_t touchX, touchY;
  bool touched = tft.getTouch(&touchX, &touchY, 600);
  if (!touched)
  {
    data->state = LV_INDEV_STATE_REL;
  }
  else
  {
    data->state = LV_INDEV_STATE_PR;
    /*Set the coordinates*/
    data->point.x = touchX;
    data->point.y = touchY;
    Serial.print("Data x");
    Serial.println(touchX);
    Serial.print("Data y");
    Serial.println(touchY);
  }
  return false; /*Return `false` because we are not buffering and no more data to read*/
}
void setup()
{
  // put your setup code here, to run once:
  // Serial.begin(9600);
  // //testdrawcircle();
  // display.begin(i2c_Address,true);
  // testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
  Serial.begin(115200); /* prepare for possible serial debug */
  lv_init();
#if USE_LV_LOG != 0
  lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif
  tft.begin();        /* TFT init */
  tft.setRotation(1); /* Landscape orientation */
  uint16_t calData[5] = {275, 3620, 264, 3532, 1};
  tft.setTouch(calData);
  lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
  /*Initialize the display*/
  lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = 480;
  disp_drv.ver_res = 320;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.buffer = &disp_buf;
  lv_disp_drv_register(&disp_drv);
  /*Initialize the (dummy) input device driver*/
  lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);
  // lv_demo_benchmark();
  lv_demo_music();
}
void loop()
{
  // put your main code here, to run repeatedly:
  // testdrawcircle();
  // Serial.println("hello");
  // delay(1000);
  // Serial.println(getCpuFrequencyMhz());
  // delay(1000);
  lv_task_handler();
  delay(5);
}

 

위 코드의 105행과 106행은 각각 benchmark와 music에 대한 테스트 코드입니다. 최종 결과는 이 글의 시작 부분에 있는 그림에 나와 있습니다. 벤치마크 테스트는 다음과 같습니다. 

 

 

 

원문 튜토리얼 출처는 이곳을 따라가시면 만나실 수 있습니다. 재미있는 프로젝트가 많습니다. 

 

How to use LVGL library – Arduino on an ESP-32 and SPI LCD 

 

LVGL Tutorials for STM32 and ESP32 | Build GUI with LVGL 

 

시간이 많은 건지, 머리가 좋은 건지 모르겠지만 잘하는 건 사실입니다.

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^