3 Use LVGL library to create UI interface and light up lights¶
1. Introduce LVGL¶
LVGL (LittlevGL) is an open-source, lightweight, high-performance embedded graphics library designed specifically for devices with limited resources. It supports multi platform porting, provides rich controls, animations, touch support, and highly customizable styles, suitable for fields such as smart homes, industrial equipment, medical instruments, etc. LVGL is centered around modular design and can run on bare metal or operating systems, accelerating GUI development through powerful community support and tools such as SquareLine Studio.
SquareLine Studio is a next-generation user interface (UI) solution for individuals and professionals, allowing users to quickly and easily design and develop aesthetically pleasing UI for embedded devices. This software provides integrated design, prototyping, and development capabilities, supporting the export of platform independent C or MicroPython code for LVGL (Lightweight Graphics Library), which can be compiled and run on any vendor's device.
2.Install SquareLine Studio¶
2.1 Installation Guide¶
Enter the https://squareline.io/ to download the SquareLine installation file.
Download the version 1.4.0
Double-click the setup.exe file.
Click install.
Wait for installation.
Installation finish.
There is a 30-day trial period for the first time you use it. Please follow the prompts to register an account. You will continue to use it when you log in to your account next time.
2.2 Software Function Introduction¶
Open the software
The historical project page: open the project built earlier.
Create a project page: choose different platforms according to different hardware of the project.
When select the Arduino framwork, there's only one option "Arduino with TFT_eSPI". By choosing this, the squareline studio will generate a template code suitable for the TFT_eSPI library. However, squareline studio not only supports the TFT_eSPI library, it supports a variety of libraries to suit different hardware and application needs. For example, Adafruit_GFX library, LovyanGFX etc.¶
After using SLS to generate UI code, we then use different graphics libraries according to different hardware and modify the corresponding code to display the content you design.¶
Example page. This page has several official examples for reference.
The project settings bar is used to make basic settings for the project, including property settings such as project name, screen size, display angle, etc.
Note: Please select the corresponding resolution and color depth according to the screen specifications.¶
①Toolbar, including File, Export, and Help. Basic file operation bar, create or open files, export UI files and other operations. Click help and there are related introductory documents.¶
②Screen bar, the project screen will be listed here.¶
③Widget area, all widgets are here and can be selected and used according to project needs.¶
④Hierarchy area, it will show every widget used in each screen.¶
⑤This area shows the actual display effect, you can adjust the widgets or screen here.¶
⑥Material column, the added materials are displayed here.¶
⑦Setting bar, where you can make basic settings for each part, including the basic attributes and trigger operations of the part.¶
⑧Theme bar, different themes can be set.¶
3 Use SquareLine Studio to create UI control interfaces¶
Firstly, open the SquareLine Studio software and create a case study
Choose the correct resolution based on the different sizes you are using
Here, I take a 2.4-inch screen as an example. After determining the resolution, I fill it in
After selecting the parameters, click Create
Open the photo of the desk lamp we provided and add it in. (Of course, you can also choose the image you want to use)
The lamp_28 image size is available for both 2.4-inch and 2.8-inch screens.
Table_lamp image sizes are available for 3.5-inch, 4.3-inch, 5.0-inch, and 7-inch screens.
After adding it, drag and drop the image in.
The task we need to complete is to turn on and off the lights by clicking on the buttons on the graphical interface. So we need to design two buttons
From the left sidebar, select Button and drag it into the interface.
You can adjust the border of the button with the mouse, which can adjust the size of the button, and you can also drag and drop the button to adjust its position.
Then, by selecting Background, choose the background color of the Button.
We have made the button patterns, and now we need to add labels to the button patterns in order to distinguish their functions.
Drag and drop from the left sidebar, select Label, and drag into the interface.
Modify the text content of the label
And modify the font size and text color of the text
The Button and Label have been designed. Click on the Hierarchy in the right-hand column and drag the Label onto the Button line to merge them into one.
At this point, if you drag the buttons again, you will find that they are dragged together
Next, we will copy a completed button, right-click, and paste it in.
Click the second button ON to change the text content to Off. Used to achieve the effect of turning off lights.
4 Add functions to the buttons to enable them to turn on and off lights¶
Select 'event' to add in the right sidebar
Select 'released' as the triggering condition and 'Call function' as the action.
After selecting, click ADD.
And add a function name to the CALL Function. (Customization is sufficient)
Similarly, add an event to the Off button. The operation process is the same as above.
After adding, run
5 UI interface design completed, exporting UI files for easy use in subsequent code¶
Click on Project Setting
Set export path
Complete the setup and export file
Copy and paste the exported code into the code folder we need to open
Then double-click 2_4LVGL.ino and open it using Arduino IDE
6 Connect the light bulb and add code to control the light bulb to turn on and off¶
Connect the light bulb at the UART1 interface
Observing the schematic diagram of this size, it is known that the pin for UART1 to control the light bulb to turn on and off is 18
So in the code, set pin 18 as the output mode.
A large-sized screen requires setting 19 pins as the output mode.
The code for size 2.4 is the same as the code for size 3.5, only the UI display file configured is different
And add the function of turning on and off the light bulb in the ui_ event. c file.
(When the On button is clicked, the light is on; when the Off button is clicked, the light is off)
7 Configure the code running environment and upload the code¶
(!! Before uploading the code, please use different library files according to the size you are using. You can review the content of Lesson 2)
(For large-sized screens of 4.3 inches, 5.0 inches, and 7.0 inches, be sure to switch the mode to 0 1 state before uploading the code, because the pins of UART1 and W-M mode are both used in 0 1 mode, so that you can use the pins of UART1)
So you can see the UI interface you just designed
You can click the On and Off buttons to control the on/off of the lights
8 Code presentation¶
2.4 inchs¶
#include "pins_config.h"
#include "LovyanGFX_Driver.h"
#include <lvgl.h>
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <stdbool.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include "ui.h"
LGFX gfx;
/* Change to your screen resolution */
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *buf;
static lv_color_t *buf1;
// Display refresh
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
if (gfx.getStartCount() > 0) {
gfx.endWrite();
}
gfx.pushImageDMA(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1, (lgfx::rgb565_t *)&color_p->full);
lv_disp_flush_ready(disp); //Tell lvgl that the refresh is complete
}
uint16_t touchX, touchY;
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
data->state = LV_INDEV_STATE_REL;
if ( gfx.getTouch( &touchX, &touchY ) ) {
data->state = LV_INDEV_STATE_PR;
//Set coordinates (the Y-axis of the screen on Longxian is opposite, and the X-axis of the screen on Puyang is opposite)
data->point.x = LCD_H_RES - touchX;
data->point.y = touchY; //After rotation, the Y-axis is reversed
Serial.print( "Data x " );
Serial.println( data->point.x );
Serial.print( "Data y " );
Serial.println( data->point.y );
}
}
void setup()
{
Serial.begin(115200);
pinMode(18, OUTPUT);
Wire.begin(15, 16);
delay(50);
//GT911 power on timing --->0x5D
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
digitalWrite(1, LOW);
digitalWrite(2, LOW);
delay(20);
digitalWrite(2, HIGH);
delay(100);
pinMode(1, INPUT);
/*end*/
// Init Display
gfx.init();
gfx.initDMA();
gfx.startWrite();
gfx.fillScreen(TFT_BLACK);
lv_init();
size_t buffer_size = sizeof(lv_color_t) * LCD_H_RES * LCD_V_RES;
buf = (lv_color_t *)heap_caps_malloc(buffer_size, MALLOC_CAP_SPIRAM);
buf1 = (lv_color_t *)heap_caps_malloc(buffer_size, MALLOC_CAP_SPIRAM);
assert(buf);
assert(buf1);
lv_disp_draw_buf_init(&draw_buf, buf, buf1, LCD_H_RES * LCD_V_RES);
//Initialize display
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
//Change the following lines to your display resolution
disp_drv.hor_res = LCD_H_RES;
disp_drv.ver_res = LCD_V_RES;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
//Initialize input device driver program
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);
delay(100);
/* Turn on backlight */
pinMode(38, OUTPUT);
digitalWrite(38, HIGH);
// Init touch device
// gt911_address = 0x5D;
// touch_init(gt911_address);
gfx.fillScreen(TFT_BLACK);
// lv_demo_widgets();
ui_init();
Serial.println( "Setup done" );
}
void loop()
{
lv_timer_handler(); /* let the GUI do its work */
delay(5);
}