Skip to content

Commit ee7502d

Browse files
Merge pull request #434 from arduino/benjamindannegard/display-shield-lvgl-guide
[GIGA-Display-Shield] LVGL guide
2 parents 0142fd1 + 53c1958 commit ee7502d

File tree

9 files changed

+511
-0
lines changed

9 files changed

+511
-0
lines changed
Loading

Diff for: content/hardware/09.mega/shields/giga-display-shield/tutorials/lvgl-guide/assets/button-clicked.svg

+15
Loading

Diff for: content/hardware/09.mega/shields/giga-display-shield/tutorials/lvgl-guide/assets/button.svg

+27
Loading

Diff for: content/hardware/09.mega/shields/giga-display-shield/tutorials/lvgl-guide/assets/checkboxes.svg

+27
Loading

Diff for: content/hardware/09.mega/shields/giga-display-shield/tutorials/lvgl-guide/assets/example-in-ide.svg

+27
Loading

Diff for: content/hardware/09.mega/shields/giga-display-shield/tutorials/lvgl-guide/assets/image.svg

+15
Loading

Diff for: content/hardware/09.mega/shields/giga-display-shield/tutorials/lvgl-guide/assets/radio-buttons.svg

+15
Loading

Diff for: content/hardware/09.mega/shields/giga-display-shield/tutorials/lvgl-guide/assets/slider.svg

+15
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
---
2+
title: Guide for Using LVGL With the Giga Display Shield
3+
description: 'Learn how to use LVGL with the GIGA display shield'
4+
author: Benjamin Dannegård
5+
tags: [Display, LVGL]
6+
---
7+
8+
## Introduction
9+
10+
LVGL is a very powerful graphical framework that is compatible with the Giga Display Shield. It will allow you to put components on the screen like buttons, images, loading bars, sliders, checkboxes etc. It also allows you fully customize the screenspace on the display. This guide will go through the different components in detail so you can learn how to best implement it to your project.
11+
12+
## Hardware & Software Needed
13+
14+
- [GIGA R1 WiFi](/hardware/giga-r1).
15+
- [GIGA Display Shield]()
16+
- [Arduino IDE](https://www.arduino.cc/en/software)
17+
- [Arduino_H7_Video]() library.
18+
- [Arduino_GigaDisplayTouch]() library.
19+
20+
## Downloading the Library and Core
21+
22+
The Giga core includes a library that will help us handle the display, so make sure you have the latest version of the core. This library is called **Arduino_H7_Video**.
23+
24+
In this guide, we will be using three different libraries:
25+
- **Arduino_H7_Video**, this one is bundled with the core, so make sure you have the latest version of the [Mbed core](https://github.com/arduino/ArduinoCore-mbed)
26+
- **Arduino_GigaDisplayTouch**
27+
- **lvgl**
28+
29+
Open the library manager and install the latest version of **Arduino_GigaDisplayTouch** and **lvgl**.
30+
31+
In the sketch include the libraries like this:
32+
33+
```arduino
34+
#include "Arduino_H7_Video.h"
35+
#include "lvgl.h"
36+
37+
#include "Arduino_GigaDisplayTouch.h"
38+
```
39+
40+
## General Set Up
41+
42+
### Display Shield Configuration
43+
44+
We then will also need to define the screen we are using, do this by adding this line of code after the library inclusions. This function will use the **Arduino_H7_Video** library:
45+
46+
```arduino
47+
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
48+
````
49+
50+
And if you want to use touch with your application call the following to use the **Arduino_GigaDisplayTouch** library:
51+
52+
```arduino
53+
Arduino_GigaDisplayTouch TouchDetector;
54+
```
55+
56+
Then we have to start these functions by putting these lines in the `setup()` function:
57+
58+
```arduino
59+
Display.begin();
60+
TouchDetector.begin();
61+
```
62+
63+
### LVGL Screen Configuration
64+
65+
When creating elements, information about the screen and placement needs to be provided. Lets 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()`.
66+
67+
```arduino
68+
lv_obj_t * screen = lv_obj_create(lv_scr_act());
69+
```
70+
71+
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 displays size parameters. To make it easy we can use the entire size:
72+
73+
```arduino
74+
lv_obj_set_size(screen, Display.width(), Display.height());
75+
```
76+
77+
### Creating a Grid Layout
78+
79+
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.
80+
81+
```arduino
82+
static lv_coord_t col_dsc[] = {370, 370, LV_GRID_TEMPLATE_LAST};
83+
static lv_coord_t row_dsc[] = {215, 215, LV_GRID_TEMPLATE_LAST};
84+
```
85+
86+
Then like before a pointer for the screenspace needs to be created. Here it will be called `grid`.
87+
88+
```arduino
89+
lv_obj_t * grid = lv_obj_create(lv_scr_act());
90+
```
91+
92+
To set the grid description that we defined before use:
93+
94+
```arduino
95+
lv_obj_set_grid_dsc_array(grid, col_dsc, row_dsc);
96+
```
97+
98+
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.
99+
100+
```arduino
101+
lv_obj_set_size(grid, Display.width(), Display.height());
102+
```
103+
104+
Then if we want to center the grid on the screen, simply use:
105+
106+
```arduino
107+
lv_obj_center(grid);
108+
```
109+
110+
### Update Loop
111+
112+
Include this in the loop of your sketch to make sure the LVGL engine is running and updating the screen.
113+
114+
```arduino
115+
void loop() {
116+
lv_timer_handler();
117+
}
118+
```
119+
120+
## Visual Elements
121+
122+
### Image
123+
124+
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`.
125+
126+
```arduino
127+
LV_IMG_DECLARE(img_arduinologo);
128+
```
129+
130+
`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.
131+
132+
```arduino
133+
lv_obj_t * obj;
134+
lv_obj_t * img1;
135+
```
136+
137+
Then create the image object with `obj` as a parent. Then we can link the image and image pointer together.
138+
139+
```arduino
140+
img1 = lv_img_create(obj);
141+
lv_img_set_src(img1, &img_arduinologo);
142+
```
143+
144+
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)`.
145+
146+
```arduino
147+
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
148+
lv_obj_set_size(img1, 200, 150);
149+
```
150+
151+
![An image rendered on the display shield with LVGL](assets/image.svg)
152+
153+
## Functional Elements
154+
155+
### Checkbox
156+
157+
`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.
158+
159+
```arduino
160+
lv_obj_t * obj;
161+
lv_obj_t * checkbox;
162+
```
163+
164+
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.
165+
166+
```arduino
167+
obj = lv_obj_create(screen);
168+
checkbox = lv_checkbox_create(obj);
169+
lv_checkbox_set_text(checkbox, "Example");
170+
```
171+
172+
The startup state of the checkbox can be set with `lv_obj_add_state()`. Where the object and state has to be specified:
173+
174+
```arduino
175+
lv_obj_add_state(checkbox, LV_STATE_CHECKED);
176+
```
177+
178+
![Checkboxes rendered on the display shield with LVGL](assets/checkboxes.svg)
179+
180+
### Radio Button
181+
182+
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.
183+
184+
```arduino
185+
static lv_style_t style_radio;
186+
static lv_style_t style_radio_chk;
187+
```
188+
189+
Now initialize the style variable that was set in the previous step:
190+
191+
```arduino
192+
lv_style_init(&style_radio);
193+
```
194+
195+
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`.
196+
197+
```arduino
198+
lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);
199+
lv_style_init(&style_radio_chk);
200+
lv_style_set_bg_img_src(&style_radio_chk, NULL);
201+
```
202+
203+
![Radio buttons rendered on the display shield with LVGL](assets/radio-buttons.svg)
204+
205+
### Slider
206+
207+
`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.
208+
209+
```arduino
210+
lv_obj_t * obj;
211+
lv_obj_t * slider;
212+
lv_obj_t * label;
213+
```
214+
215+
Now the slider can be created with:
216+
217+
```arduino
218+
slider = lv_slider_create(obj);
219+
```
220+
221+
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.
222+
223+
```arduino
224+
lv_slider_set_value(slider, 75, LV_ANIM_OFF);
225+
```
226+
227+
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.](https://docs.lvgl.io/master/widgets/obj.html#coordinates)
228+
229+
```arduino
230+
label = lv_label_create(obj);
231+
lv_label_set_text(label, "Drag me!");
232+
lv_obj_align_to(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
233+
```
234+
235+
![Slider rendered on the display shield with LVGL](assets/slider.svg)
236+
237+
### Bar
238+
239+
To make a bar, for example a loading bar, we need to include some animation. Lets first set up the slider itself and then move on to the animation.
240+
241+
`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.
242+
243+
```arduino
244+
lv_obj_t * obj;
245+
lv_obj_t * bar;
246+
```
247+
248+
Now the bar can be created with:
249+
250+
```arduino
251+
bar = lv_bar_create(obj);
252+
```
253+
254+
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.
255+
256+
```arduino
257+
lv_obj_set_size(bar, 200, 20);
258+
lv_bar_set_value(bar, 70, LV_ANIM_OFF);
259+
```
260+
261+
Now for the animation. First create the slider variable and initialize it:
262+
263+
```arduino
264+
lv_anim_t animation;
265+
lv_anim_init(&animation);
266+
```
267+
268+
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.
269+
270+
```arduino
271+
lv_anim_set_time(&animation, 3000);
272+
lv_anim_set_playback_time(&animation, 3000);
273+
```
274+
275+
To connect the animation to the bar use:
276+
277+
```arduino
278+
lv_anim_set_var(&animation, bar);
279+
```
280+
281+
The start and end values of the animation has to be set, here they are `0` and `100` respectively.
282+
283+
```arduino
284+
lv_anim_set_values(&animation, 0, 100);
285+
```
286+
287+
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`.
288+
289+
```arduino
290+
lv_anim_set_repeat_count(&animation, LV_ANIM_REPEAT_INFINITE);
291+
lv_anim_start(&animation);
292+
```
293+
294+
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`.
295+
296+
```arduino
297+
lv_anim_set_exec_cb(&animation, set_bar_val);
298+
```
299+
300+
In this separate callback function the bar value will be reset and the animation will be turned on again.
301+
302+
```arduino
303+
static void set_bar_val(void * bar, int32_t val) {
304+
lv_bar_set_value((lv_obj_t *)bar, val, LV_ANIM_ON);
305+
}
306+
```
307+
308+
![A bar rendered on the display shield with LVGL](assets/bar.gif)
309+
310+
### Button
311+
312+
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. Lets start with designing the button.
313+
314+
315+
`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.
316+
317+
```arduino
318+
lv_obj_t * obj;
319+
lv_obj_t * button;
320+
lv_obj_t * label;
321+
```
322+
323+
Now the button can be created with:
324+
325+
```arduino
326+
button = lv_btn_create(obj);
327+
```
328+
329+
Set the size of the button with `lv_obj_set_size(btn, WIDTH, HEIGHT)`. For example:
330+
331+
```arduino
332+
lv_obj_set_size(btn, 100, 40);
333+
```
334+
335+
Lets 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.
336+
337+
```arduino
338+
label = lv_label_create(button);
339+
lv_label_set_text(label, "Click me!");
340+
lv_obj_center(label);
341+
```
342+
343+
When the button is clicked we need to assign it a function to execute, lets 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`.
344+
345+
```arduino
346+
lv_obj_add_event_cb(button, button_event_callback, LV_EVENT_CLICKED, NULL);
347+
```
348+
349+
Now lets 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!`.
350+
351+
352+
```arduino
353+
static void button_event_callback(lv_event_t * e) {
354+
lv_obj_t * button = lv_event_get_target(e);
355+
lv_obj_t * label = lv_obj_get_child(button, 0);
356+
lv_label_set_text_fmt(label, "Clicked!");
357+
}
358+
```
359+
360+
![A button rendered on the display shield with LVGL](assets/button.svg)
361+
![Button when it has been clicked](assets/button-clicked.svg)
362+
363+
## Conclusion
364+
365+
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**.
366+
![Example in the IDE](assets/example-in-ide.svg)
367+
This example sketch will show the different components in a 2x2 grid.
368+
369+
## Next Step
370+
If you are interested in finding out how to use LVGL with the on-board IMU check out our [Orientation tutorial](). There are more features of the display shield to discover, for example using the camera connector. For more information on that have a look at our [Camera tutorial](). 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](https://docs.lvgl.io/master/examples.html). These can easily be put in a sketch for the display shield just remember to use the display-specific configuration that was shown at the [start of this tutorial](#Display Shield Configuration).

0 commit comments

Comments
 (0)