11_Arduino-ESP32_LVGL_按钮,图片,选项卡

1,258 阅读4分钟

安装库

github.com/lvgl/lvgl

必要设置

复制lvgl/lv_conf_template.h拷贝到文件夹外,,并重命名为 lv_conf.h,打开该文件:

    • 第 15 行, #if 0 改为 #if 1
    • 第 27 行,根据设备设置颜色深度 ``#define LV_COLOR_DEPTH 16`。
    • 第 88 行,改为 #define LV_TICK_CUSTOM 1 。
  • 仍然在 lvgl 文件夹中,把 demos 两个文件夹拷贝到 lvgl/src 下。

启动示例

2022-04-23 19-57-48屏幕截图.png

#define LGFX_USE_V1

#include <lvgl.h>
#include "demos/lv_demos.h"
#include <LovyanGFX.hpp>

class LGFX : public lgfx::LGFX_Device
{

   lgfx::Panel_ILI9481 _panel_instance; //R61529兼容ILI9481驱动

   lgfx::Bus_Parallel16 _bus_instance;

   lgfx::Light_PWM _light_instance;

   lgfx::Touch_FT5x06  _touch_instance; 

public:
   LGFX(void)
   {
      {  
         auto cfg = _bus_instance.config();

         cfg.port = 0;  
         cfg.freq_write = 20000000; 
         cfg.pin_wr = 15;           // WR を接続しているピン番号
         cfg.pin_rd = -1;           // RD を接続しているピン番号
         cfg.pin_rs = 16;           // RS(D/C)を接続しているピン番号
         cfg.pin_d0 = 37;            // D0を接続しているピン番号
         cfg.pin_d1 = 36;            // D1を接続しているピン番号
         cfg.pin_d2 = 35;            // D2を接続しているピン番号
         cfg.pin_d3 = 34;            // D3を接続しているピン番号
         cfg.pin_d4 = 33;            // D4を接続しているピン番号
         cfg.pin_d5 = 48;            // D5を接続しているピン番号
         cfg.pin_d6 = 21;            // D6を接続しているピン番号
         cfg.pin_d7 = 18;            // D7を接続しているピン番号
         cfg.pin_d8 = 17;            // D8を接続しているピン番号
         cfg.pin_d9 = 39;            // D9を接続しているピン番号
         cfg.pin_d10 = 38;            // D10を接続しているピン番号
         cfg.pin_d11 = 2;            // D11を接続しているピン番号
         cfg.pin_d12 = 7;            // D12を接続しているピン番号
         cfg.pin_d13 = 12;            // D13を接続しているピン番号
         cfg.pin_d14 = 6;            // D14を接続しているピン番号
         cfg.pin_d15 = 10;            // D15を接続しているピン番号
         
         _bus_instance.config(cfg);              // 設定値をバスに反映します。
         _panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
      }

      {                                       // 表示パネル制御の設定を行います。
         auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。

         cfg.pin_cs = -1;   // CSが接続されているピン番号   (-1 = disable)
         cfg.pin_rst = -1;  // RSTが接続されているピン番号  (-1 = disable)
         cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)

         // ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。

         cfg.memory_width = 320;   // ドライバICがサポートしている最大の幅
         cfg.memory_height = 480;  // ドライバICがサポートしている最大の高さ
         cfg.panel_width = 320;    // 実際に表示可能な幅
         cfg.panel_height = 480;   // 実際に表示可能な高さ
         cfg.offset_x = 0;         // パネルのX方向オフセット量
         cfg.offset_y = 0;         // パネルのY方向オフセット量
         cfg.offset_rotation = 0;  //值在旋转方向的偏移0~7(4~7是倒置的)
         cfg.dummy_read_pixel = 8; // 在读取像素之前读取的虚拟位数
         cfg.dummy_read_bits = 1;  // 读取像素以外的数据之前的虚拟读取位数
         cfg.readable = false;      // 如果可以读取数据,则设置为 true
         cfg.invert = false;       // 如果面板的明暗反转,则设置为 true
         cfg.rgb_order = false;    // 如果面板的红色和蓝色被交换,则设置为 true
         cfg.dlen_16bit = true;   // 对于以 16 位单位发送数据长度的面板,设置为 true
         cfg.bus_shared = false;    // 如果总线与 SD 卡共享,则设置为 true(使用 drawJpgFile 等执行总线控制)

         _panel_instance.config(cfg);
      }

    { // バックライト制御の設定を行います。(必要なければ削除)
      auto cfg = _light_instance.config();    // バックライト設定用の構造体を取得します。

      cfg.pin_bl = 5;              // バックライトが接続されているピン番号
      cfg.invert = false;           // バックライトの輝度を反転させる場合 true
      cfg.freq   = 44100;           // バックライトのPWM周波数
      cfg.pwm_channel = 1;          // 使用するPWMのチャンネル番号

      _light_instance.config(cfg);
      _panel_instance.setLight(&_light_instance);  // バックライトをパネルにセットします。
    }
    
    { // タッチスクリーン制御の設定を行います。(必要なければ削除)
      auto cfg = _touch_instance.config();

      cfg.x_min      = 0;    // タッチスクリーンから得られる最小のX値(生の値)
      cfg.x_max      = 319;  // タッチスクリーンから得られる最大のX値(生の値)
      cfg.y_min      = 0;    // タッチスクリーンから得られる最小のY値(生の値)
      cfg.y_max      = 479;  // タッチスクリーンから得られる最大のY値(生の値)
      cfg.pin_int    = -1;   // INTが接続されているピン番号
      cfg.bus_shared = false; // 画面と共通のバスを使用している場合 trueを設定
      cfg.offset_rotation = 0;// 显示和触摸方向不匹配时的调整 设置为 0 到 7 的值

// I2C接続の場合
      cfg.i2c_port = 0;      // 使用するI2Cを選択 (0 or 1)
      cfg.i2c_addr = 0x38;   // I2Cデバイスアドレス番号
      cfg.pin_sda  = 40;     // SDAが接続されているピン番号
      cfg.pin_scl  = 41;     // SCLが接続されているピン番号
      cfg.freq = 400000;     // I2Cクロックを設定

      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);  // タッチスクリーンをパネルにセットします。
    }

      setPanel(&_panel_instance); // 使用するパネルをセットします。
   }
};

// 準備したクラスのインスタンスを作成します。
LGFX tft;

/*更改为您的屏幕分辨率*/
static const uint32_t screenWidth = 480;
static const uint32_t screenHeight = 320;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * 10];

#if LV_USE_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char *file, uint32_t line, const char *fn_name, const char *dsc)
{
   Serial.printf("%s(%s)@%d->%s\r\n", file, fn_name, 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)
{
   int w = (area->x2 - area->x1 + 1);
   int h = (area->y2 - area->y1 + 1);

   tft.startWrite();                            /* Start new TFT transaction */
   tft.setAddrWindow(area->x1, area->y1, w, h); /* set the working window */

   tft.writePixels((lgfx::rgb565_t *)&color_p->full, w * h);

   tft.endWrite();            /* terminate TFT transaction */
   lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
   uint16_t touchX, touchY;

   bool touched =tft.getTouch(&touchX, &touchY);

   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 );
   }
}

void setup()
{
   Serial.begin(115200); /* prepare for possible serial debug */
   Serial.println("Hello Arduino! (V8.2.X)");
   Serial.println("I am LVGL_Arduino");

   lv_init();

#if LV_USE_LOG != 0
   lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif

   tft.init();         /* TFT init */
   tft.setRotation(1); /* Landscape orientation, flipped */

   lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * 10);

   /*Initialize the display*/
   static lv_disp_drv_t disp_drv;
   lv_disp_drv_init(&disp_drv);
   /*Change the following line to your display resolution*/
   disp_drv.hor_res = screenWidth;
   disp_drv.ver_res = screenHeight;
   disp_drv.flush_cb = my_disp_flush;
   disp_drv.draw_buf = &draw_buf;
   lv_disp_drv_register(&disp_drv);

   /*Initialize the (dummy) input device driver*/
   static 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);

#if 0
   /* Create simple label */
   lv_obj_t *label = lv_label_create( lv_scr_act() );
   lv_label_set_text( label, "Hello Arduino! (V8.0.X)" );
   lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
   /* Try an example from the lv_examples Arduino library
      make sure to include it as written above.
   lv_example_btn_1();
   */

   // uncomment one of these demos
   lv_demo_widgets();            // OK
   //lv_demo_benchmark();          // OK
   //lv_demo_keypad_encoder(); 
   // works, but I haven't an encoder
   //lv_demo_music();              // NOK
   //lv_demo_printer();
   //lv_demo_stress();             // seems to be OK
#endif
   Serial.println("Setup done");
}

void loop()
{
   lv_timer_handler(); /* let the GUI do its work */
   delay(5);
}

开发板型号

TTGO T-Watch

1_按钮


#include "config.h"

TTGOClass *ttgo;

static lv_obj_t * label_text;

int text_value=0;

static void event_handler(lv_obj_t *obj, lv_event_t event)
{
    if (event == LV_EVENT_CLICKED) {
        lv_label_set_text_fmt(label_text, "%d",++text_value);
    }
}

void setup()
{
    Serial.begin(115200);
    ttgo = TTGOClass::getWatch();
    ttgo->begin();
    ttgo->openBL();
    ttgo->lvgl_begin();

    label_text = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(label_text, "0");
    lv_obj_set_auto_realign(label_text, true);
    lv_obj_align(label_text,NULL, LV_ALIGN_CENTER, 0,-40);


    lv_obj_t *label;

    lv_obj_t *btn1 = lv_btn_create(lv_scr_act(), NULL);
    lv_obj_set_event_cb(btn1, event_handler);
    lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0,40);

    label = lv_label_create(btn1, NULL);
    lv_label_set_text(label, "Button");

}

void loop()
{
    lv_task_handler();
    delay(5);
}

2_图片


安装GIMP

https://www.gimp.org/

#include "config.h"

TTGOClass *ttgo;

LV_IMG_DECLARE(build);

void lv_ex_img_1(void)
{
    lv_obj_t * img1 = lv_img_create(lv_scr_act(), NULL);
    lv_img_set_src(img1, &build);
    lv_obj_align(img1, NULL, LV_ALIGN_CENTER, 0,0);
}

void setup()
{
    Serial.begin(115200);
    ttgo = TTGOClass::getWatch();
    ttgo->begin();
    ttgo->openBL();
    ttgo->lvgl_begin();
    lv_ex_img_1();
}

void loop()
{
    lv_task_handler();
    delay(5);
}

3_选项卡


#include "config.h"

TTGOClass *ttgo;

void lv_ex_tabview_1(void)
{
    /*Create a Tab view object*/
    lv_obj_t *tabview;
    tabview = lv_tabview_create(lv_scr_act(), NULL);

    /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/
    lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1");
    lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Tab 2");
    lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Tab 3");


    /*Add content to the tabs*/
    lv_obj_t * label = lv_label_create(tab1, NULL);
    lv_label_set_text(label, "This the first tab\n\n"
                             "If the content\n"
                             "of a tab\n"
                             "become too long\n"
                             "the it \n"
                             "automatically\n"
                             "become\n"
                             "scrollable.");

    label = lv_label_create(tab2, NULL);
    lv_label_set_text(label, "Second tab");

    label = lv_label_create(tab3, NULL);
    lv_label_set_text(label, "Third tab");
}

void setup()
{
    Serial.begin(115200);
    ttgo = TTGOClass::getWatch();
    ttgo->begin();
    ttgo->openBL();
    ttgo->lvgl_begin();
    lv_ex_tabview_1();
}

void loop()
{
    lv_task_handler();
    delay(5);
}