前言
本文,介绍如何在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,这个库需要自己另外装。
(2)安装lv_arduino
lvgl官方发布的arduinoIDE第三方库为lv_arduino
(三)配置TFT_eSPI与lv_arduino的配置文件
(1)配置User_Setup_Select.h
我的配置文件位置如下图,打开User_Setup_Select.h,
给下面语句注释
#include <User_Setup.h> // Default setup is root library folder
取消下面语句的注释
//#include <User_Setups/Setup2_ST7735.h> // Setup file configured for my ST7735
(2)配置lv_conf.h
该配置文件是lv_arduino第三方库的配置文件,我的配置文件位置如下图
该文件lv_conf.h需要改的地方有两处
第一处是修改屏幕的大小,改为128x128,如下图
第二处是改lvgl的缓存,可以减少芯片的flash动态内存
(四)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);
}