基于ArduinoIDE开发lvgl触摸板

 首先是如何配置好vgl在ArduinoIDE环境,可以参考Arduino — LVGL documentationicon-default.png?t=N7T8https://docs.lvgl.io/master/get-started/platforms/arduino.html#get-the-lvgl-arduino-library

 触摸板的ESP32配置选择ESP32S3 Dev module:其配置需要参照下面文档进行调整:

Sunton ESP32-S3 4.3 inch 800*400 IPS with Touch - Makerfabs Wiki

 ArduinoIDE中需要下载的库“GFX_Library_for_Arduino”,“lvgl”,“TFT_eSPI”,“TAMC_GT911”

本文的lvgl型号在TFT_eSPI函数中找不到配置,所以不需要开启。

只需要将通过“SquareLine_Studio_1.3.0_Setup”软件配置好的界面并输出的函数,放置在链接:

https://pan.baidu.com/s/1thKSFWSKnEtGQOKIohUy6A?pwd=8888 
提取码:8888

下载好的这个文件夹中,将用“SquareLine_Studio_1.3.0_Setup” 软件输出的文件的具体放置位置是将输出的“SquareLine_Project”文件放置到“Sunton_ESP32-8048S043-liu”的“src”文件夹中,再将“sketch_jul30a”文件夹中的“lvgl_conf.h”和“touch.h”文件放置到ui.ino文件旁边,修改ui文件夹中src文件夹中的“ui.c”文件。布局如下:

 

当将文件和函数的位置弄好后,需要最重要的一步就是将sketch_jul30a文件夹中的“sketch_jul30a.ino”里面,void setup()上面的函数全部复制,替代“ui.ino”里面对应的函数部分,同时将多余的自定义变量删除,同时将touch、TFT、GFX初始化函数写入值setup中,请参考以下主函数代码:

注意:将原来的“#include <ui.h>”改为“#include "src/ui.h""

#include <lvgl.h>
#include <TFT_eSPI.h>
#include "src/ui.h"

/*Don't forget to set Sketchbook location in File/Preferencesto the path of your UI project (the parent foder of this INO file)*/
/*Change to your screen resolution*/
static const uint16_t screenWidth  = 800;
static const uint16_t screenHeight = 480;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * screenHeight / 10 ];
#define pin0  17
#define pin1  18

TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */

#if LV_USE_LOG != 0
/* Serial debugging */
void my_print(const char * buf)
{
    Serial.printf(buf);
    Serial.flush();
}
#endif

/*******************************************************************************
 * LVGL Widgets
 * This is a widgets demo for LVGL - Light and Versatile Graphics Library
 * import from: https://github.com/lvgl/lv_demos.git
 *
 * This was created from the project here 
 * https://www.makerfabs.com/sunton-esp32-s3-4-3-inch-ips-with-touch.html
 * 
 * Dependent libraries:
 * LVGL: https://github.com/lvgl/lvgl.git

 * Touch libraries:
 * FT6X36: https://github.com/strange-v/FT6X36.git
 * GT911: https://github.com/TAMCTec/gt911-arduino.git
 * XPT2046: https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
 *
 * LVGL Configuration file:
 * Copy your_arduino_path/libraries/lvgl/lv_conf_template.h
 * to your_arduino_path/libraries/lv_conf.h
 * Then find and set:
 * #define LV_COLOR_DEPTH     16
 * #define LV_TICK_CUSTOM     1
 *
 * For SPI display set color swap can be faster, parallel screen don't set!
 * #define LV_COLOR_16_SWAP   1
 *
 * Optional: Show CPU usage and FPS count
 * #define LV_USE_PERF_MONITOR 1
 ******************************************************************************/
//#include "lv_demo_widgets.h"
#include <demos/lv_demos.h>
/*******************************************************************************
 ******************************************************************************/
#include <Arduino_GFX_Library.h>
#define TFT_BL 2
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin

Arduino_ESP32RGBPanel *bus = new Arduino_ESP32RGBPanel(
    GFX_NOT_DEFINED /* CS */, GFX_NOT_DEFINED /* SCK */, GFX_NOT_DEFINED /* SDA */,
    40 /* DE */, 41 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
    45 /* R0 */, 48 /* R1 */, 47 /* R2 */, 21 /* R3 */, 14 /* R4 */,
    5 /* G0 */, 6 /* G1 */, 7 /* G2 */, 15 /* G3 */, 16 /* G4 */, 4 /* G5 */,
    8 /* B0 */, 3 /* B1 */, 46 /* B2 */, 9 /* B3 */, 1 /* B4 */
);

//  ST7262 IPS LCD 800x480
Arduino_RPi_DPI_RGBPanel *gfx = new Arduino_RPi_DPI_RGBPanel(
    bus,
    800 /* width */, 0 /* hsync_polarity */, 8 /* hsync_front_porch */, 4 /* hsync_pulse_width */, 8 /* hsync_back_porch */,
    480 /* height */, 0 /* vsync_polarity */, 8 /* vsync_front_porch */, 4 /* vsync_pulse_width */, 8 /* vsync_back_porch */,
    1 /* pclk_active_neg */, 14000000 /* prefer_speed */, true /* auto_flush */);

#include "touch.h"

/* Change to your screen resolution */
static lv_disp_drv_t disp_drv;

/* 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);

#if (LV_COLOR_16_SWAP != 0)
  gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
  gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif

  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  if (touch_has_signal())
  {
    if (touch_touched())
    {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touch_last_x;
      data->point.y = touch_last_y;
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
}

void openleft(void)
{
  if(lv_obj_has_state(ui_Switchopenleft, LV_STATE_CHECKED)==1) // 返回 bool 类型, 开-1 ; 关-2
  {
    pinMode(pin0,OUTPUT);
      
    digitalWrite(pin0,HIGH);
    
  }  
}

void openright(void)
{
  if(lv_obj_has_state(ui_Switchopenright, LV_STATE_CHECKED)==1) // 返回 bool 类型, 开-1 ; 关-2
  {
   
    pinMode(pin1,OUTPUT);    
    
    digitalWrite(pin1,HIGH);
  }  
}

void brakeleft(void)
{
  if(lv_obj_has_state(ui_Switchbrakeleft, LV_STATE_CHECKED)==1) // 返回 bool 类型, 开-1 ; 关-2
  {
    pinMode(pin0,OUTPUT);
      
    digitalWrite(pin0,LOW);
    
  }  
}

void brakeright(void)
{
  if(lv_obj_has_state(ui_Switchbrakeright, LV_STATE_CHECKED)==1) // 返回 bool 类型, 开-1 ; 关-2
  {
    
    pinMode(pin1,OUTPUT);
   
    digitalWrite(pin1,LOW);
  }  
}
void setup()
{
    Serial.begin( 115200 ); /* prepare for possible serial debug */
      gfx->begin();
#ifdef TFT_BL
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
#endif


    String LVGL_Arduino = "Hello Arduino! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();

    Serial.println( LVGL_Arduino );
    Serial.println( "I am LVGL_Arduino" );

    lv_init();
    delay(10);
  touch_init();


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

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

    lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * screenHeight / 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 );


    ui_init();
    Serial.println( "Setup done" );
    openleft();
    openright();
    brakeleft();
    brakeright();
    }

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

以下列出的是一些模块代码:

开关函数可以参考

LVGL学习笔记17 - 开关Switch_lvgl switch_pq113_6的博客-CSDN博客

滑块函数可以参考:

LVGL(72)-v8--滑块slider-CSDN博客

按钮模块函数可以参考: 

lvgl-按钮学习篇(三)_lvgl 按钮_无为扫地僧的博客-CSDN博客

标签函数请参考:

 ESP32开发路程LVGL篇(四)——常用函数介绍,屏幕、标签_lvgl 设置背景色-CSDN博客

这些函数的调用需要在ui.c文件中调用,调用前,如果需要做一些改动,清先到“screen.h”文件中,看看你需要修改的模块是否有重合的命令。本文的ui.c代码:

// This file was generated by SquareLine Studio
// SquareLine Studio version: SquareLine Studio 1.3.0
// LVGL version: 8.3.6
// Project name: SquareLine_Project

#include "ui.h"
#include "ui_helpers.h"
/ VARIABLES 

// SCREEN: ui_Screen1
void ui_Screen1_screen_init(void);
void ui_event_Screen1(lv_event_t * e);
lv_obj_t * ui_Screen1;
lv_obj_t * ui_Left;
lv_obj_t * ui_Right;
lv_obj_t * ui_Switchopenleft;
lv_obj_t * ui_Label1;
lv_obj_t * ui_Switchopenright;
lv_obj_t * ui_Label2;
lv_obj_t * ui_Switchbrakeleft;
lv_obj_t * ui_Switchbrakeright;
lv_obj_t * ui_Leftslide;
lv_obj_t * ui_Rightslide;
lv_obj_t * ui_Label3;
lv_obj_t * ui_Label4;
lv_obj_t * ui_Label5;
lv_obj_t * ui_Label6;
lv_obj_t * ui_Label8;
lv_obj_t * ui_Stop;
lv_obj_t * ui_Label10;
lv_obj_t * ui_Label9;
lv_obj_t * ui_Image1;
lv_obj_t * ui_Label12;
lv_obj_t * ui_Label11;
lv_obj_t * ui_Label7;
lv_obj_t * ui_Label13;
lv_obj_t * ui_Label14;
lv_obj_t * ui_Leftspeed;
lv_obj_t * ui_Rightspeed;
lv_obj_t * ui_Label16;
lv_obj_t * ui_Label15;
lv_obj_t * ui____initial_actions0;
const lv_img_dsc_t * ui_imgset_337415967[1] = {&ui_img_1806934165};
const lv_img_dsc_t * ui_imgset_392147749[3] = {&ui_img_999838862, &ui_img_355854617, &ui_img_1807947869};
/ TEST LVGL SETTINGS 
#if LV_COLOR_DEPTH != 32
#endif
#if LV_COLOR_16_SWAP !=0
    #error "LV_COLOR_16_SWAP should be 0 to match SquareLine Studio's settings"
#endif

/ ANIMATIONS 

/ FUNCTIONS 

void ui_event_Screen1(lv_event_t * e)
{
    lv_event_code_t event_code = lv_event_get_code(e);
    lv_obj_t * target = lv_event_get_target(e);
    if(event_code == LV_EVENT_CLICKED) {
        (e);
    }
}
//brake开关
void ui_event_Switchbrakeleft(lv_event_t * e)//左制动
{
  lv_event_code_t event_code = lv_event_get_code(e);
  lv_obj_t * target = lv_event_get_target(e);
   if(event_code == LV_EVENT_VALUE_CHANGED)
     {
       if(lv_obj_has_state(target,LV_STATE_CHECKED) == true )
         {
           lv_obj_add_state(target, LV_STATE_CHECKED);//将brake设为开状态,此时的open失效,滑块为0
           lv_obj_add_state(ui_Switchopenleft, LV_STATE_DISABLED); 
           lv_slider_set_value(ui_Leftslide,000,LV_ANIM_ON);
           lv_label_set_text_fmt(ui_Leftspeed,"%s","OFF");
          
           
         }
       else{lv_obj_clear_state(target, LV_STATE_CHECKED);//将brake设为关状态,此时open生效
            lv_obj_clear_state(ui_Switchopenleft, LV_STATE_DISABLED);}
       }
}
void ui_switchbrakeleft()
{
  lv_obj_clear_state(ui_Switchbrakeleft, LV_STATE_CHECKED);//brake初始值为关闭
  lv_obj_add_event_cb(ui_Switchbrakeleft,ui_event_Switchbrakeleft,LV_EVENT_VALUE_CHANGED,NULL);
}

//brake开关
void ui_event_Switchbrakeright(lv_event_t * e)//右制动
{
  lv_event_code_t event_code = lv_event_get_code(e);
  lv_obj_t * target = lv_event_get_target(e);
   if(event_code == LV_EVENT_VALUE_CHANGED)
     {
       if(lv_obj_has_state(target,LV_STATE_CHECKED) == true )
         {
           
           lv_obj_add_state(target, LV_STATE_CHECKED);//将brake设为开状态,此时的open失效,滑块为0
           lv_obj_add_state(ui_Switchopenright, LV_STATE_DISABLED); 
           lv_slider_set_value(ui_Rightslide,000,LV_ANIM_ON);
           lv_label_set_text_fmt(ui_Rightspeed,"%s","OFF");
         }
       else{lv_obj_clear_state(target, LV_STATE_CHECKED);//将brake设为关状态,此时open生效
            lv_obj_clear_state(ui_Switchopenright, LV_STATE_DISABLED);}
       }
}
void ui_switchbrakeright()
{
  lv_obj_clear_state(ui_Switchbrakeright, LV_STATE_CHECKED);//brake初始值为关闭
  lv_obj_add_event_cb(ui_Switchbrakeright,ui_event_Switchbrakeright,LV_EVENT_VALUE_CHANGED,NULL);
}

//open开关
void ui_event_leftopenswitch(lv_event_t * e)  //左开关
{
   lv_event_code_t event_code = lv_event_get_code(e);
   lv_obj_t * target = lv_event_get_target(e);
   if(event_code == LV_EVENT_VALUE_CHANGED)
     {
       if(lv_obj_has_state(target,LV_STATE_CHECKED) == 1 ) 
         {
          
           lv_obj_add_state(target, LV_STATE_CHECKED);
            ui_slideleftspeed(); 
           lv_obj_clear_state(ui_Switchbrakeleft, LV_STATE_DISABLED);	
           
         }
        if(lv_obj_has_state(target,LV_STATE_CHECKED) == 0){
           lv_obj_add_state(ui_Switchbrakeleft, LV_STATE_DISABLED); 
           lv_obj_clear_state(target, LV_STATE_CHECKED); 
           lv_slider_set_value(ui_Leftslide,000,LV_ANIM_ON);
           lv_label_set_text_fmt(ui_Leftspeed,"%s","OFF");
           
              }
      }
}
void ui_leftopenswitch(void)
{
  
  lv_obj_add_state(ui_Switchopenleft, LV_STATE_CHECKED);	// 开
    ui_slideleftspeed();
  lv_obj_add_event_cb(ui_Switchopenleft,ui_event_leftopenswitch,LV_EVENT_VALUE_CHANGED,NULL);
}

void ui_event_rightopenswitch(lv_event_t * e)   //右开关
{
   lv_event_code_t event_code = lv_event_get_code(e);
   lv_obj_t * target = lv_event_get_target(e);
   if(event_code == LV_EVENT_VALUE_CHANGED)
    {
     if(lv_obj_has_state(target,LV_STATE_CHECKED) == 0 )
     {
        lv_obj_add_state(ui_Switchbrakeright, LV_STATE_DISABLED); 
        lv_obj_clear_state(target, LV_STATE_CHECKED);
        lv_slider_set_value(ui_Rightslide,000,LV_ANIM_ON);
        lv_label_set_text_fmt(ui_Rightspeed,"%s","OFF");
      }
     if(lv_obj_has_state(target,LV_STATE_CHECKED) == 1){ 
           	
           lv_obj_clear_state(ui_Switchbrakeright, LV_STATE_DISABLED);
           lv_obj_add_state(target, LV_STATE_CHECKED);
           ui_sliderightspeed();}
     }
}
void ui_rightopenswitch(void)
{
  lv_obj_add_state(ui_Switchopenright, LV_STATE_CHECKED);	// 开
    ui_sliderightspeed();
  lv_obj_add_event_cb(ui_Switchopenright,ui_event_rightopenswitch,LV_EVENT_VALUE_CHANGED,NULL);
}


//按钮stop
void ui_event_stop(lv_event_t * e)
{
   lv_event_code_t event_code = lv_event_get_code(e);
lv_obj_t * target = lv_event_get_target(e);
  if(event_code == LV_EVENT_PRESSED) {
        lv_slider_set_value(ui_Leftslide,000,LV_ANIM_ON);
        lv_label_set_text_fmt(ui_Leftspeed,"%s","OFF");
        lv_slider_set_value(ui_Rightslide,000,LV_ANIM_ON);
        lv_label_set_text_fmt(ui_Rightspeed,"%s","OFF");
      }
}


void ui_stop(void)
{
   lv_obj_add_event_cb(ui_Stop,ui_event_stop,LV_EVENT_PRESSED,NULL);
}
//滑块部分
void ui_slideleftspeed(void) //左滑块初始值,范围设置
{
lv_slider_set_value(ui_Leftslide,000,LV_ANIM_OFF);
lv_slider_set_range(ui_Leftslide, 0, 800); // 设置滑块值的变化范围0-800
lv_obj_add_event_cb(ui_Leftslide, ui_event_receive_left, LV_EVENT_VALUE_CHANGED, NULL);
        
}



void ui_sliderightspeed(void)  //右滑块初始值,范围设置
{
lv_slider_set_value(ui_Rightslide,000,LV_ANIM_OFF);
lv_slider_set_range(ui_Rightslide, 0, 800); // 设置滑块值的变化范围0-800 
  
lv_obj_add_event_cb(ui_Rightslide, ui_event_receive_right, LV_EVENT_VALUE_CHANGED,NULL);
}

void ui_event_receive_left(lv_event_t *e)  //左滑块标签数据显示
{
   lv_event_code_t event_code = lv_event_get_code(e);
   lv_obj_t *target = lv_event_get_target(e);
   if(event_code == LV_EVENT_VALUE_CHANGED)
   {
    if(lv_obj_has_state(ui_Switchopenleft,LV_STATE_CHECKED) == 1)
      {
          if(lv_obj_has_state(ui_Switchbrakeleft,LV_STATE_CHECKED) == 0 )
          {
             
         lv_label_set_text_fmt(ui_Leftspeed,"%d",lv_slider_get_value(target));
        
          }        
      }
   }
}

void ui_event_receive_right(lv_event_t *e) //右滑块标签数据显示
{ 
  lv_event_code_t event_code = lv_event_get_code(e);
  lv_obj_t *target = lv_event_get_target(e);
   if(event_code == LV_EVENT_VALUE_CHANGED)
   {
      if(lv_obj_has_state(ui_Switchopenright,LV_STATE_CHECKED) == 1)
      {
      if(lv_obj_has_state(ui_Switchbrakeright,LV_STATE_CHECKED) == 0 )
       {
      
             lv_label_set_text_fmt(ui_Rightspeed,"%d",lv_slider_get_value(target));
         
        }
      }
    }
}

void ui_event_speedback(void)
{
  lv_label_set_text_fmt(ui_Label16,"%d",50);
  lv_label_set_text_fmt(ui_Label15,"%d",300);
}

/ SCREENS 

void ui_init(void)
{
    lv_disp_t * dispp = lv_disp_get_default();
    lv_theme_t * theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED),
                                               false, LV_FONT_DEFAULT);
    lv_disp_set_theme(dispp, theme);
    ui_Screen1_screen_init();
    ui____initial_actions0 = lv_obj_create(NULL);
    lv_disp_load_scr(ui_Screen1);
    ui_event_speedback();
    ui_stop();
    ui_leftopenswitch();
    ui_rightopenswitch();
    ui_switchbrakeleft();
    ui_switchbrakeright();
    
}

切记一定要将前面写好的函数放在ui_init()函数里。 

“screen.c”文件可能会出现报错,一个是字体只能用默认值14,全部改为“&lv_font_montserrat_14”所以改过来就好了。

“ui.c”文件也有一个坑,就是“LV_COLOR_DEPTH|=32”下面的“ERROR”部分删除就行了。

写好之后,需要单独引用的函数一定要放在ui.h头文件中声明,然后再调用到主函数中

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值