esp8266 NodeMcu硬件环境下使用lvgl

前言

本文,介绍如何在esp8266 Node MCU的硬件上部署LVGL项目。使用的屏幕使用型号是ST7735 TFT 128x128屏幕
lvgl的简单入门,可以参考我的另一篇博文

目录

(一)arduinoIDE esp8266环境配置
(二)配置lvgl在arduino的开发环境
(三)配置TFT_eSPI与lv_arduino的配置文件
(四)esp8266连接ST7735屏幕
(五)测试代码

(一)arduinoIDE esp8266环境配置

自行参考这篇博文,添加esp8266 在arduinoIDE开发环境。

(二)配置lvgl在arduino的开发环境

LVGL的官方已经将LVGL项目移植到了arduinoIDE,我们可以直接在arduinoIDE的库管理器添加lvgl图形库在arduino上发布的第三方库lv_arduino.

(1)安装TFT_eSPI

lvgl在arduinoIDE编程环境下,使用的驱动库是TFT_eSPI,这个库需要自己另外装。
esp8266 NodeMcu硬件环境下使用lvgl

(2)安装lv_arduino

lvgl官方发布的arduinoIDE第三方库为lv_arduino
esp8266 NodeMcu硬件环境下使用lvgl

(三)配置TFT_eSPI与lv_arduino的配置文件

(1)配置User_Setup_Select.h

我的配置文件位置如下图,打开User_Setup_Select.h
esp8266 NodeMcu硬件环境下使用lvgl
给下面语句注释

#include <User_Setup.h>           // Default setup is root library folder

取消下面语句的注释

//#include <User_Setups/Setup2_ST7735.h>   // Setup file configured for my ST7735

esp8266 NodeMcu硬件环境下使用lvgl

(2)配置lv_conf.h

该配置文件是lv_arduino第三方库的配置文件,我的配置文件位置如下图
esp8266 NodeMcu硬件环境下使用lvgl

该文件lv_conf.h需要改的地方有两处
第一处是修改屏幕的大小,改为128x128,如下图
esp8266 NodeMcu硬件环境下使用lvgl
第二处是改lvgl的缓存,可以减少芯片的flash动态内存
esp8266 NodeMcu硬件环境下使用lvgl

(四)esp8266连接ST7735屏幕

连线的照下面的对应引脚连接就行,注意屏幕上的NC引脚为悬空引脚不需要连线。

// Typical setup for ESP8266 NodeMCU ESP-12 is :
// Display SDO/MISO  to NodeMCU pin D6 (or leave disconnected if not reading TFT)
// Display LED       to NodeMCU pin VIN (or 5V, see below)
// Display SCK       to NodeMCU pin D5
// Display SDI/MOSI  to NodeMCU pin D7
// Display DC (RS/AO)to NodeMCU pin D3
// Display RESET     to NodeMCU pin D4 (or RST, see below)
// Display CS        to NodeMCU pin D8 (or GND, see below)
// Display GND       to NodeMCU pin GND (0V)
// Display VCC       to NodeMCU 5V or 3.3V
// The TFT RESET pin can be connected to the NodeMCU RST pin or 3.3V to free up a control pin

(五)测试代码

直接保存为 test.ino 直接运行了。

#include <lvgl.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];

//basic variables
static uint8_t test_data = 0;
static lv_obj_t * label1;

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

/* Reading input device (simulated encoder here) */
bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data)
{
    static int32_t last_diff = 0;
    int32_t diff = 0; /* Dummy - no movement */
    int btn_state = LV_INDEV_STATE_REL; /* Dummy - no press */

    data->enc_diff = diff - last_diff;;
    data->state = btn_state;

    last_diff = diff;

    return false;
}
//task循环执行的函数
static void task_cb(lv_task_t* task)
{
    uint8_t *user_data = (uint8_t*)task->user_data;
    (*user_data)++;
    //Serial.println("helloworld!");
    lv_label_set_text_fmt(label1, "\n\n%d", *user_data);
}


void setup()
{

    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(0); /* Landscape orientation */

    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 = 128;
    disp_drv.ver_res = 128;
    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_ENCODER;
    indev_drv.read_cb = read_encoder;
    lv_indev_drv_register(&indev_drv);

    /*界面的代码*/
    label1 = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_long_mode(label1, LV_LABEL_LONG_BREAK);     /*Break the long lines*/
    lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER);                /*Center aligned lines*/
    lv_label_set_text(label1, "Hello World!");
    lv_obj_set_width(label1, 150);
    lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, -30);
    
    lv_task_t * t = lv_task_create(task_cb,100,LV_TASK_PRIO_MID, &test_data);
}

void loop()
{
    lv_task_handler(); /* let the GUI do its work */
    delay(5);
}
上一篇:SUSE11安装系统后,做LVM挂文件系统后,重启报错提示LV不存在


下一篇:网络流24题(七)