GIGA Display Shield LVGL Guide

Learn how to use LVGL with the GIGA Display Shield.

Introduction

LVGL is a graphical framework for building powerful UIs, and is fully compatible with the GIGA Display Shield. It allows you to build UIs, using pre-made widgets like buttons, images, loading bars, sliders, checkboxes, etc. It also allows you to fully customize the screenspace on the display. In this guide, we will go through some of the different components, so you can learn how to best implement it in your projects.

LVGL is a large framework, and the aim of this guide is to get you familiar with it. For much more information, visit the LVGL documentation.

Hardware & Software Needed

Downloading the Library and Board Package

The GIGA R1 Board Package includes the Arduino_H7_Video library that handles the display.

In this guide, we will be using three different libraries:

To install them, open the library manager and install the latest version by searching for "Arduino_GigaDisplayTouch" and "lvgl".

In the sketch include the libraries like this:

1#include "Arduino_H7_Video.h"
2#include "lvgl.h"
3#include "Arduino_GigaDisplayTouch.h"

General Set Up

In this section, we will go through the fundamental elements of an LVGL sketch:

  • How to define & configure the display,
  • how to create a grid layout,
  • how to add an object to the grid,
  • how to update the display.

At the end of this section, you will find a complete example which implements a grid layout. You can skip directly to the example, but if you have no prior experience with LVGL, we recommend you follow the information below.

Display Shield Configuration

The first thing we need to do is to define the display we are using, by creating a object using the

Arduino_H7_Video
class, specifying the height, width and type of display.

1Arduino_H7_Video Display(800, 480, GigaDisplayShield);

And if you want to use touch with your application, we need to create an object using the

Arduino_GigaDisplayTouch
class.

1Arduino_GigaDisplayTouch TouchDetector;

In the

setup()
, we begin by initializing the display and the touch detector.

1void setup(){
2 Display.begin();
3 TouchDetector.begin();
4}

With these things set up, we can go on to configure the LVGL elements.

LVGL Screen Configuration

When creating elements, information about the screen and placement needs to be provided. Let's create a pointer variable that can be used whenever the screenspace needs to be used. The pointer variable will be named

screen
and to use the current screen for the pointer use
lv_scr_act()
. This code should also be added inside
setup()
.

1lv_obj_t * screen = lv_obj_create(lv_scr_act());

The size of the screen space needs to be set for the pointer that is declared. The size can be set to anything within the display's size parameters. To make it easy we can use the entire size:

1lv_obj_set_size(screen, Display.width(), Display.height());

Creating a Grid Layout

Creating a grid that you can then fill with elements will consist of a defined column and row. This

col_dsc[] = {370, 370, LV_GRID_TEMPLATE_LAST};
will create two columns with 370 px width. To add more columns simply add more values, like so
col_dsc[] = {100, 100, 100, 100, LV_GRID_TEMPLATE_LAST};
, this will create four columns with 100 px width. The same logic is applied to the row definition.

1static lv_coord_t col_dsc[] = {370, 370, LV_GRID_TEMPLATE_LAST};
2 static lv_coord_t row_dsc[] = {215, 215, LV_GRID_TEMPLATE_LAST};

Then like before a pointer for the screenspace needs to be created. Here it will be called

grid
.

1lv_obj_t * grid = lv_obj_create(lv_scr_act());

To set the grid description that we defined before use:

1lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);

Now that the columns and rows have been defined the overall screen needs to be taken into account. This is achieved by using

lv_obj_set_size(grid, Display.width(), Display.height())
, to make it easy we will allow the
grid
to use the entire screen.

1lv_obj_set_size(grid, Display.width(), Display.height());

Then, just to test it out, let's add an object to the grid:

  • first declare the
    obj
    pointer add it to the
    grid
    ,
  • then we set the grid cell via
    lv_obj_set_grid_cell()
    method.
1lv_obj_t* obj;
2obj = lv_obj_create(grid);
3lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, //column
4 LV_GRID_ALIGN_STRETCH, 0, 1); //row

The

lv_obj_set_grid_cell())
have a set of parameters related to how the object is positioned and aligned. In this case, we have created a 2x2 grid, where the
0
(column) and
0
(row) indicates where on the grid it should go.

Take a look at this graphic to understand it better:

How grids work in LVGL.
How grids work in LVGL.

Update Loop

Include this in the loop of your sketch to make sure the LVGL engine is running and updating the screen. The

lv_timer_handler()
function should be called at max every 5 milliseconds. If it would be called more frequently than that please use a non-blocking method to delay it.

1void loop() {
2 lv_timer_handler();
3}

Minimal Example

The summary of all code snippets in this section can be found in the example below. It implements a 2x2 grid, as well as adds an object in each slot.

1#include "Arduino_H7_Video.h"
2#include "lvgl.h"
3#include "Arduino_GigaDisplayTouch.h"
4
5Arduino_H7_Video Display(800, 480, GigaDisplayShield);
6Arduino_GigaDisplayTouch TouchDetector;
7
8void setup() {
9 Display.begin();
10 TouchDetector.begin();
11
12 //Display & Grid Setup
13 lv_obj_t* screen = lv_obj_create(lv_scr_act());
14 lv_obj_set_size(screen, Display.width(), Display.height());
15
16 static lv_coord_t col_dsc[] = { 370, 370, LV_GRID_TEMPLATE_LAST };
17 static lv_coord_t row_dsc[] = { 215, 215, 215, 215, LV_GRID_TEMPLATE_LAST };
18
19 lv_obj_t* grid = lv_obj_create(lv_scr_act());
20 lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
21 lv_obj_set_size(grid, Display.width(), Display.height());
22
23 //top left
24 lv_obj_t* obj;
25 obj = lv_obj_create(grid);
26 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, //column
27 LV_GRID_ALIGN_STRETCH, 0, 1); //row
28
29 //bottom left
30 obj = lv_obj_create(grid);
31 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1, //column
32 LV_GRID_ALIGN_STRETCH, 1, 1); //row
33 //top right
34 obj = lv_obj_create(grid);
35 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 1, 1, //column
36 LV_GRID_ALIGN_STRETCH, 0, 1); //row
37
38 //bottom right
39 obj = lv_obj_create(grid);
40 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 1, 1, //column
41 LV_GRID_ALIGN_STRETCH, 1, 1); //row
42}
43
44void loop() {
45 lv_timer_handler();
46}

Visual Elements

Image

To display an image on the screen we first need to define what that image that should be. Take the desired image, convert it into the correct format and place the image in the same folder as the sketch. Now use

LV_IMG_DECLARE(filename);
. For example the image we use will be named
img_arduinologo
.

1LV_IMG_DECLARE(img_arduinologo);

obj
will be a pointer that will be used to hold the information about the screenspace information for the image. The
img1
pointer will be used for the elements of the image itself.

1lv_obj_t * obj;
2 lv_obj_t * img1;

Then create the image object with

obj
as a parent. Then we can link the image and image pointer together.

1img1 = lv_img_create(obj);
2 lv_img_set_src(img1, &img_arduinologo);

To make sure we see the image use the align function to make it centered. Then at last set the size of image with

lv_obj_set_size(img1, WIDTH, HEIGHT)
.

1lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
2 lv_obj_set_size(img1, 200, 150);

An image rendered on the GIGA Display Shield with LVGL
An image rendered on the GIGA Display Shield with LVGL

Full Example:

1#include "Arduino_H7_Video.h"
2#include "lvgl.h"
3
4Arduino_H7_Video Display(800, 480, GigaDisplayShield);
5
6void setup() {
7 Display.begin();
8
9 lv_obj_t * screen = lv_obj_create(lv_scr_act());
10 lv_obj_set_size(screen, Display.width(), Display.height());
11
12 static lv_coord_t col_dsc[] = { 500, LV_GRID_TEMPLATE_LAST};
13 static lv_coord_t row_dsc[] = { 400, LV_GRID_TEMPLATE_LAST};
14
15 lv_obj_t * grid = lv_obj_create(lv_scr_act());
16
17 lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
18
19 lv_obj_set_size(grid, Display.width(), Display.height());
20
21 lv_obj_center(grid);
22
23 lv_obj_t * obj;
24 lv_obj_t * img1;
25
26 obj = lv_obj_create(grid);
27 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
28 LV_GRID_ALIGN_STRETCH, 0, 1);
29
30 LV_IMG_DECLARE(img_arduinologo);
31
32 img1 = lv_img_create(obj);
33 lv_img_set_src(img1, &img_arduinologo);
34
35 lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
36 lv_obj_set_size(img1, 200, 150);
37}
38
39void loop() {
40 lv_timer_handler();
41}

Text

Displaying text is usually done with labels. These are used in most of the other examples to put text on buttons and switches. Like any other element you first have to create the object with:

1lv_obj_t * label;

Then the labels text can be set with:

1lv_label_set_text(label, "Label!");

If you want to insert a variable that is not a string, use:

1//This will make the label show the number 13
2lv_label_set_text_fmt(label, "%d", 13)

To use bigger font sizes it has to be enabled in the

lv_conf.h
file. This file can be found in the mbed_giga/libraries/Arduino_H7_Video/src folder. Find the FONT USAGE section, here you can see all the font sizes. If you want to enable any size simply change the
0
next to any of the font sizes into a
1
. Like this:

lv_config font section

Functional Elements

Checkbox

obj
will be a pointer that will be used to hold the information about the screenspace information for the checkbox. The
checkbox
pointer will be used for the elements in the checkbox itself.

1lv_obj_t * obj;
2 lv_obj_t * checkbox;

Assign the screenspace info to

obj
, that was detailed in the Screen Configuration section. To create the checkbox object use
lv_checkbox_create(obj)
and assign it to a suitable variable, here we use the
checkbox
pointer. Next set the text that will appear next to the checkbox by using
lv_checkbox_set_text(checkbox, "Example");
, here
Example
will be printed next to the checkbox.

1obj = lv_obj_create(screen);
2 checkbox = lv_checkbox_create(obj);
3 lv_checkbox_set_text(checkbox, "Example");

The startup state of the checkbox can be set with

lv_obj_add_state()
. Where the object and state has to be specified:

1lv_obj_add_state(checkbox, LV_STATE_CHECKED);

Checkboxes rendered on the GIGA Display Shield with LVGL
Checkboxes rendered on the GIGA Display Shield with LVGL

Full Example:

1#include "Arduino_H7_Video.h"
2#include "lvgl.h"
3#include "Arduino_GigaDisplayTouch.h"
4
5Arduino_H7_Video Display(800, 480, GigaDisplayShield);
6Arduino_GigaDisplayTouch TouchDetector;
7
8void setup() {
9 Display.begin();
10 TouchDetector.begin();
11
12 lv_obj_t * screen = lv_obj_create(lv_scr_act());
13 lv_obj_set_size(screen, Display.width(), Display.height());
14
15 static lv_coord_t col_dsc[] = { 500, LV_GRID_TEMPLATE_LAST};
16 static lv_coord_t row_dsc[] = { 400, LV_GRID_TEMPLATE_LAST};
17
18 lv_obj_t * grid = lv_obj_create(lv_scr_act());
19
20 lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
21
22 lv_obj_set_size(grid, Display.width(), Display.height());
23
24 lv_obj_center(grid);
25
26 lv_obj_t * obj;
27
28 obj = lv_obj_create(grid);
29 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
30 LV_GRID_ALIGN_STRETCH, 0, 1);
31 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
32
33 lv_obj_t * cb;
34 cb = lv_checkbox_create(obj);
35 lv_checkbox_set_text(cb, "Apple");
36
37 cb = lv_checkbox_create(obj);
38 lv_checkbox_set_text(cb, "Banana");
39 lv_obj_add_state(cb, LV_STATE_CHECKED);
40}
41
42void loop() {
43 lv_timer_handler();
44}

Radio Button

A radio button is created in the same way as a checkbox, but with some additional calls to change the style of the element. Adding these two style elements will allow for them to be added to the checkbox options.

1static lv_style_t style_radio;
2 static lv_style_t style_radio_chk;

Now initialize the style variable that was set in the previous step:

1lv_style_init(&style_radio);

The size of the radio button is set with

lv_style_set_radius
. To make the radio button checkable use
lv_style_init(&style_radio_chk);
. And the color or background of the filled radio check can be set with
lv_style_set_bg_img_src
.

1lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);
2 lv_style_init(&style_radio_chk);
3 lv_style_set_bg_img_src(&style_radio_chk, NULL);

Radio buttons rendered on the GIGA Display Shield with LVGL
Radio buttons rendered on the GIGA Display Shield with LVGL

Full Example:

1#include "Arduino_H7_Video.h"
2#include "lvgl.h"
3#include "Arduino_GigaDisplayTouch.h"
4
5Arduino_H7_Video Display(800, 480, GigaDisplayShield);
6Arduino_GigaDisplayTouch TouchDetector;
7
8void setup() {
9 Display.begin();
10 TouchDetector.begin();
11
12 lv_obj_t * screen = lv_obj_create(lv_scr_act());
13 lv_obj_set_size(screen, Display.width(), Display.height());
14
15 static lv_coord_t col_dsc[] = { 500, LV_GRID_TEMPLATE_LAST};
16 static lv_coord_t row_dsc[] = { 400, LV_GRID_TEMPLATE_LAST};
17
18 lv_obj_t * grid = lv_obj_create(lv_scr_act());
19
20 lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
21
22 lv_obj_set_size(grid, Display.width(), Display.height());
23
24 lv_obj_center(grid);
25
26 lv_obj_t * obj;
27
28 obj = lv_obj_create(grid);
29 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
30 LV_GRID_ALIGN_STRETCH, 0, 1);
31 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
32
33 lv_obj_t * cb;
34
35 static lv_style_t style_radio;
36 static lv_style_t style_radio_chk;
37 lv_style_init(&style_radio);
38 lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);
39 lv_style_init(&style_radio_chk);
40 lv_style_set_bg_img_src(&style_radio_chk, NULL);
41
42 cb = lv_checkbox_create(obj);
43 lv_checkbox_set_text(cb, "Lemon");
44 lv_obj_add_flag(cb, LV_OBJ_FLAG_EVENT_BUBBLE);
45 lv_obj_add_style(cb, &style_radio, LV_PART_INDICATOR);
46 lv_obj_add_style(cb, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
47
48 cb = lv_checkbox_create(obj);
49 lv_checkbox_set_text(cb, "Melon");
50 lv_obj_add_flag(cb, LV_OBJ_FLAG_EVENT_BUBBLE);
51 lv_obj_add_style(cb, &style_radio, LV_PART_INDICATOR);
52 lv_obj_add_style(cb, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
53 lv_obj_add_state(cb, LV_STATE_CHECKED);
54}
55
56void loop() {
57 lv_timer_handler();
58}

Slider

obj
will be a pointer that will be used to hold the information about the screenspace information for the slider. The
slider
pointer will be used for the elements of the slider itself. The
label
pointer will be used for the text that will attached to the slider.

1lv_obj_t * obj;
2 lv_obj_t * slider;
3 lv_obj_t * label;

Now the slider can be created with:

1slider = lv_slider_create(obj);

Now the value of the slider needs to be defined, here the max value of the slider will be

75
and the animation will be default set as off as it is only needed when it is interacted with.

1lv_slider_set_value(slider, 75, LV_ANIM_OFF);

If you want a label by your slider it can be created like you would create any other label. Using

lv_obj_align_to
allows for the label to be attached to the slider element. Changing the
LV_ALIGN_OUT_BOTTOM_MID
to determine where the text will be relative to the slider. You can find all the different options for alignment here.

1label = lv_label_create(obj);
2 lv_label_set_text(label, "Drag me!");
3 lv_obj_align_to(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

Slider rendered on the GIGA Display Shield with LVGL
Slider rendered on the GIGA Display Shield with LVGL

Full Example:

1#include "Arduino_H7_Video.h"
2#include "Arduino_GigaDisplayTouch.h"
3
4#include "lvgl.h"
5
6Arduino_H7_Video Display(800, 480, GigaDisplayShield); /* Arduino_H7_Video Display(1024, 768, USBCVideo); */
7Arduino_GigaDisplayTouch TouchDetector;
8
9void setup() {
10 Display.begin();
11 TouchDetector.begin();
12
13 lv_obj_t * screen = lv_obj_create(lv_scr_act());
14 lv_obj_set_size(screen, Display.width(), Display.height());
15
16 static lv_coord_t col_dsc[] = { 500, LV_GRID_TEMPLATE_LAST};
17 static lv_coord_t row_dsc[] = { 400, LV_GRID_TEMPLATE_LAST};
18
19 lv_obj_t * grid = lv_obj_create(lv_scr_act());
20
21 lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
22
23 lv_obj_set_size(grid, Display.width(), Display.height());
24
25 lv_obj_center(grid);
26
27 lv_obj_t * label;
28 lv_obj_t * obj;
29
30 obj = lv_obj_create(grid);
31 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
32 LV_GRID_ALIGN_STRETCH, 0, 1);
33 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
34
35 lv_obj_t * slider = lv_slider_create(obj);
36 lv_slider_set_value(slider, 75, LV_ANIM_OFF);
37 lv_obj_center(slider);
38 label = lv_label_create(obj);
39 lv_label_set_text(label, "Drag me!");
40 lv_obj_align_to(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
41
42}
43
44void loop() {
45 lv_timer_handler();
46}

Bar

To make a bar, like a loading bar, we need to include some animation. Let's first set up the slider itself and then move on to the animation.

obj
will be a pointer that will be used to hold the information about the screenspace information for the bar. The
bar
pointer will be used for the elements of the bar itself.

1lv_obj_t * obj;
2 lv_obj_t * bar;

Now the bar can be created with:

1bar = lv_bar_create(obj);

Set the desired size of the bar with

lv_obj_set_size
. The value of the bar needs to be defined, here the max value of the bar will be
70
and the animation will be default set as off.

1lv_obj_set_size(bar, 200, 20);
2 lv_bar_set_value(bar, 70, LV_ANIM_OFF);

Now for the animation. First create the slider variable and initialize it:

1lv_anim_t animation;
2 lv_anim_init(&animation);

The animation time needs to be defined. It can be set with

lv_anim_set_time
which sets the duration of the animation and
lv_anim_set_playback_time
which makes the animation play back to when the forward direction is ready. The animation variable and the time in milliseconds has to be defined.

1lv_anim_set_time(&animation, 3000);
2 lv_anim_set_playback_time(&animation, 3000);

To connect the animation to the bar use:

1lv_anim_set_var(&animation, bar);

The start and end values of the animation has to be set, here they are

0
and
100
respectively.

1lv_anim_set_values(&animation, 0, 100);

How many times the animation will repeat can also be set, with this code the animation will repeat forever. And then at last we can create the animation with

lv_anim_start
.

1lv_anim_set_repeat_count(&animation, LV_ANIM_REPEAT_INFINITE);
2 lv_anim_start(&animation);

When the bar animates we can set it so that a separate callback function will be called. Here that function will be named

set_bar_val
.

1lv_anim_set_exec_cb(&animation, set_bar_val);

In this separate callback function the bar value will be reset and the animation will be turned on again.

1static void set_bar_val(void * bar, int32_t val) {
2 lv_bar_set_value((lv_obj_t *)bar, val, LV_ANIM_ON);
3}

A bar rendered on the GIGA Display Shield with LVGL

Full Example:

1#include "Arduino_H7_Video.h"
2#include "Arduino_GigaDisplayTouch.h"
3
4#include "lvgl.h"
5
6Arduino_H7_Video Display(800, 480, GigaDisplayShield); /* Arduino_H7_Video Display(1024, 768, USBCVideo); */
7Arduino_GigaDisplayTouch TouchDetector;
8
9static void set_slider_val(void * bar, int32_t val) {
10 lv_bar_set_value((lv_obj_t *)bar, val, LV_ANIM_ON);
11}
12
13void setup() {
14 Display.begin();
15 TouchDetector.begin();
16
17 lv_obj_t * screen = lv_obj_create(lv_scr_act());
18 lv_obj_set_size(screen, Display.width(), Display.height());
19
20 static lv_coord_t col_dsc[] = { 500, LV_GRID_TEMPLATE_LAST};
21 static lv_coord_t row_dsc[] = { 400, LV_GRID_TEMPLATE_LAST};
22
23 lv_obj_t * grid = lv_obj_create(lv_scr_act());
24
25 lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
26
27 lv_obj_set_size(grid, Display.width(), Display.height());
28
29 lv_obj_center(grid);
30
31 lv_obj_t * label;
32 lv_obj_t * obj;
33
34 obj = lv_obj_create(grid);
35 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
36 LV_GRID_ALIGN_STRETCH, 0, 1);
37 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
38
39 lv_obj_t * bar = lv_bar_create(obj);
40 lv_obj_set_size(bar, 200, 20);
41 lv_obj_center(bar);
42 lv_bar_set_value(bar, 70, LV_ANIM_OFF);
43
44 lv_anim_t a;
45 lv_anim_init(&a);
46 lv_anim_set_exec_cb(&a, set_slider_val);
47 lv_anim_set_time(&a, 3000);
48 lv_anim_set_playback_time(&a, 3000);
49 lv_anim_set_var(&a, bar);
50 lv_anim_set_values(&a, 0, 100);
51 lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
52 lv_anim_start(&a);
53
54}
55
56void loop() {
57 lv_timer_handler();
58}

Button

A button will need two parts, the design of the button itself and the callback event function which determines what happens when the button is pressed. Let's start with designing the button.

obj
will be a pointer that will be used to hold the information about the screenspace information for the button. The
button
pointer will be used for the elements in the button itself. The
label
pointer will be used for the text that will be put on the button.

1lv_obj_t * obj;
2 lv_obj_t * button;
3 lv_obj_t * label;

Now the button can be created with:

1button = lv_btn_create(obj);

Set the size of the button with

lv_obj_set_size(btn, WIDTH, HEIGHT)
. For example:

1lv_obj_set_size(btn, 100, 40);

Let's make the label on the button a child of the button by using

label = lv_label_create(button)
. Then the label can be set to whatever text it needs to be and center the text on top of the button so that it looks correct. The button will now say
Click me!
at the center of it.

1label = lv_label_create(button);
2 lv_label_set_text(label, "Click me!");
3 lv_obj_center(label);

When the button is clicked we need to assign it a function to execute, let's call this function

button_event_callback
. Assign it to the correct button and set it to be executed when the button is clicked with
LV_EVENT_CLICKED
.

1lv_obj_add_event_cb(button, button_event_callback, LV_EVENT_CLICKED, NULL);

Now let's create the callback function that will be called when the button is clicked. By creating pointers that will point to the original elements we can change them easily in our function. This function will make it so that when the button is clicked the label text on the button will be changed to

Clicked!
.

1static void button_event_callback(lv_event_t * e) {
2 lv_obj_t * button = lv_event_get_target(e);
3 lv_obj_t * label = lv_obj_get_child(button, 0);
4 lv_label_set_text_fmt(label, "Clicked!");
5}

A button rendered on the GIGA Display Shield with LVGL
A button rendered on the GIGA Display Shield with LVGL

Button when it has been pressed
Button when it has been pressed

Full Example:

1#include "Arduino_H7_Video.h"
2#include "lvgl.h"
3#include "Arduino_GigaDisplayTouch.h"
4
5Arduino_H7_Video Display(800, 480, GigaDisplayShield);
6Arduino_GigaDisplayTouch TouchDetector;
7
8static void btn_event_cb(lv_event_t * e) {
9 lv_obj_t * btn = lv_event_get_target(e);
10 lv_obj_t * label = lv_obj_get_child(btn, 0);
11 lv_label_set_text_fmt(label, "Clicked!");
12}
13
14void setup() {
15 Display.begin();
16 TouchDetector.begin();
17
18 lv_obj_t * screen = lv_obj_create(lv_scr_act());
19 lv_obj_set_size(screen, Display.width(), Display.height());
20
21 static lv_coord_t col_dsc[] = { 500, LV_GRID_TEMPLATE_LAST};
22 static lv_coord_t row_dsc[] = { 400, LV_GRID_TEMPLATE_LAST};
23
24 lv_obj_t * grid = lv_obj_create(lv_scr_act());
25
26 lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
27
28 lv_obj_set_size(grid, Display.width(), Display.height());
29
30 lv_obj_center(grid);
31
32 lv_obj_t * label;
33 lv_obj_t * obj;
34
35 obj = lv_obj_create(grid);
36 lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, 0, 1,
37 LV_GRID_ALIGN_STRETCH, 0, 1);
38 lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
39
40 lv_obj_t * btn = lv_btn_create(obj);
41 lv_obj_set_size(btn, 100, 40);
42 lv_obj_center(btn);
43 lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
44
45 label = lv_label_create(btn);
46 lv_label_set_text(label, "Click me!");
47 lv_obj_center(label);
48
49}
50
51void loop() {
52 lv_timer_handler();
53}

Conclusion

This guide went through the building blocks of the different components that can be implemented with LVGL. To see these examples in a full running example sketch go to File > Examples > Arduino_H7_Video > LVGLDemo.

Example in the IDE
Example in the IDE

This example sketch will show the different components in a 2x2 grid.

Next Step

LVGL has a lot of customizability, if you are interested in playing around more with this, you can find many different examples on the official website for LVGL. These can easily be put in a sketch for the GIGA Display Shield, just remember to use the display-specific configuration that was shown at the start of this tutorial.

The GIGA Display Shield features some on-board sensors, like an IMU and a microphone. To see how these can be used with LVGL check out our Orientation tutorial, which will show you how to use the on-board IMU to rotate an image. Or have a look at our Microphone tutorial, which will show you how to merge microphone readings with LVGL components.

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.