Go to file
Gabor Kiss-Vamosi 88b54456ef
Update README.md
2020-05-31 21:46:12 +02:00
.github Update config.yml 2020-05-25 05:44:24 +02:00
docs Update CODING_STYLE.md 2020-05-25 06:35:00 +02:00
porting comment update littlevgl -> lvgl 2020-05-18 14:55:39 +02:00
scripts CJK: fix built-in SimSun font and wrong UTF-8 decoding in Arabic processor 2020-05-21 10:40:16 +02:00
src keyboard: allow backspace to auto-repeat in numeric mode (lv_examples#58) 2020-05-31 08:33:21 -04:00
tests minor formatting 2020-05-24 13:14:42 +02:00
.editorconfig editorconfig: remove duplicated insert_final_newline 2019-01-21 07:04:44 +01:00
.gitignore add CJK built-in font 2020-04-28 22:10:19 +02:00
.gitmodules remove historic pycparser. It is here before micropython sources moved to another repository and history rewritten 2019-01-24 00:17:37 +02:00
CHANGELOG.md Update CHANGELOG.md 2020-05-19 10:59:21 +02:00
library.json Update library.json 2020-05-20 14:50:02 +02:00
LICENCE.txt add top level lvgl.mk 2019-02-01 05:03:35 +01:00
lv_conf_template.h fixed RGB palette name in config template 2020-05-24 01:38:05 +02:00
lvgl.h set version number to 7.0.1-dev 2020-05-19 10:31:49 +02:00
lvgl.mk more dma2d to a separate file 2020-04-16 16:12:35 +02:00
README.md Update README.md 2020-05-31 21:46:12 +02:00

LVGL - Little and Versatile Graphics Library

LVGL provides everything you need to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint.

Website · Live demo · Docs · Forum · Blog


Features

  • Powerful building blocks buttons, charts, lists, sliders, images, etc.
  • Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling
  • Simultaneously use various input devices touchscreen, mouse, keyboard, encoder, buttons, etc.
  • Simultaneously use multiple displays i.e. monochrome and color display
  • Multi-language support with UTF-8 encoding, Bidirectional support, and Arabic text handling
  • Fully customizable graphical elements
  • Hardware independent to use with any microcontroller or display
  • Scalable to operate with little memory (64 kB Flash, 10 kB RAM)
  • OS, External memory and GPU supported but not required
  • Single frame buffer operation even with advances graphical effects
  • Written in C for maximal compatibility (C++ compatible)
  • Micropython Binding exposes LVGL API in Micropython
  • Simulator to develop on PC without embedded hardware
  • Tutorials, examples, themes for rapid development
  • Documentation and API references

Supported devices

Basically, every modern controller (which is able to drive a display( is suitable to run LVGL. The minimal requirements are:

  • 16, 32 or 64 bit microcontroller or processor
  • > 16 MHz clock speed is recommended
  • Flash/ROM: > 64 kB for the very essential components (> 180 kB is recommended)
  • RAM:
    • Static RAM usage: ~2 kB depending on the used features and objects types
    • Stack: > 2kB (> 8 kB is recommended)
    • Dynamic data (heap): > 2 KB (> 16 kB is recommended if using several objects). Set by LV_MEM_SIZE in lv_conf.h.
    • Display buffer: > "Horizontal resolution" pixels (> 10 × "Horizontal resolution" is recommended)
  • C99 or newer compiler

Note that the memory usage might vary depending on the architecture, compiler and build options.

Just to mention some platforms:

Quick start in a simulator

The easiest way to get started with LVGL is to run it in a simulator on your PC without any embedded hardware.

Choose a project with your favourite IDE:

Eclipse CodeBlocks Visual Studio PlatformIO Qt Creator
Eclipse CodeBlocks VisualStudio PlatformIO QtCreator
Cross-platform
with SDL
(Recommended on
Linux and Mac)
Native Windows Windows
with SDL
Cross-platform
with SDL
Cross-platform
with SDL

Add LVGL to your project

The steps below show how to setup LVGL on an embedded system with a display and a touchpad. You can use the Simulators to get ready to use projects which can be run on your PC.

  1. Download or Clone the library
  2. Copy the lvgl folder into your project
  3. Copy lvgl/lv_conf_template.h as lv_conf.h next to the lvgl folder and set at least LV_HOR_RES_MAX, LV_VER_RES_MAX and LV_COLOR_DEPTH. Don't forget to change the #if 0 statement near the top of the file to #if 1, otherwise you will get compilation errors.
  4. Include lvgl/lvgl.h where you need to use LVGL related functions.
  5. Call lv_tick_inc(x) every x milliseconds in a Timer or Task (x should be between 1 and 10). It is required for the internal timing of LVGL.
  6. Call lv_init()
  7. Create a display buffer for LVGL
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];                     /*Declare a buffer for 10 lines*/
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);    /*Initialize the display buffer*/
  1. Implement and register a function which can copy a pixel array to an area of your display:
lv_disp_drv_t disp_drv;               /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv);          /*Basic initialization*/
disp_drv.flush_cb = my_disp_flush;    /*Set your driver function*/
disp_drv.buffer = &disp_buf;          /*Assign the buffer to the display*/
lv_disp_drv_register(&disp_drv);      /*Finally register the driver*/
    
void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
    int32_t x, y;
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            set_pixel(x, y, *color_p);  /* Put a pixel to the display.*/
            color_p++;
        }
    }

    lv_disp_flush_ready(disp);         /* Indicate you are ready with the flushing*/
}
    
  1. Implement and register a function which can read an input device. E.g. for a touch pad:
lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /*Save the state and save the pressed coordinate*/
    data->state = touchpad_is_pressed() ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
    if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
   
    /*Set the coordinates (if released use the last pressed coordinates)*/
    data->point.x = last_x;
    data->point.y = last_y;

    return false; /*Return `false` because we are not buffering and no more data to read*/
}
  1. Call lv_task_handler() periodically every few milliseconds in the main while(1) loop, in Timer interrupt or in an Operation system task. It will redraw the screen if required, handle input devices etc.

Learn the basics

In this section you can ready the very basics. For a more detailed guide check the Quick overview in the documentation.

Widgets (Objects)

The graphical elements like Buttons, Labels, Sliders, Charts etc are called objects in LittelvGL. Go to Object types to see the full list of available types.

Every object has a parent object. The child object moves with the parent and if you delete the parent the children will be deleted too. Children can be visible only on their parent.

The screen are the "root" parents. To get the current screen call lv_scr_act().

You can create a new object with lv_<type>_create(parent, obj_to_copy). It will return an lv_obj_t * variable which should be used as a reference to the object to set its parameters. The first parameter is the desired parent, the second parameters can be an object to copy (NULL if unused). For example:

lv_obj_t * slider1 = lv_slider_create(lv_scr_act(), NULL);

To set some basic attribute lv_obj_set_<paramters_name>(obj, <value>) function can be used. For example:

lv_obj_set_x(btn1, 30);
lv_obj_set_y(btn1, 10);
lv_obj_set_size(btn1, 200, 50);

The objects has type specific parameters too which can be set by lv_<type>_set_<paramters_name>(obj, <value>) functions. For example:

lv_slider_set_value(slider1, 70, LV_ANIM_ON);

To see the full API visit the documentation of the object types or the related header file (e.g. lvgl/src/lv_objx/lv_slider.h).

Styles

Widgets are created with a default appearance but it can be changed by adding new styles to the object. A new style can be created like this:

static lv_style_t style1; /*Should be static, global or dynamically allocated*/
lv_style_init(&style1);
lv_style_set_bg_color(&style1, LV_STATE_DEFAULT, LV_COLOR_RED);  /*Default background color*/ 
lv_style_set_bg_color(&style1, LV_STATE_PRESSED, LV_COLOR_BLUE); /*Pressed background color*/

The wigedt have parts which can be referenced via LV_<TYPE>_PART_<PART_NAME>. E.g. LV_BRN_PART_MAIN or LV_SLIDER_PART_KNOB. See the documentation of the widgets to see the exisitng parts.

To add the style to a button:

lv_obj_add_style(btn1, LV_BTN_PART_MAIN, &style1);

To remove all styles from an object use:

lv_obj_reset_style_list(obj, LV_OBJ_PART_MAIN);

Learn more in Style overview section.

Events

Events are used to inform the user if something has happened with an object. You can assign a callback to an object which will be called if the object is clicked, released, dragged, being deleted etc. It should look like this:

lv_obj_set_event_cb(btn, btn_event_cb);                 /*Assign a callback to the button*/

...

void btn_event_cb(lv_obj_t * btn, lv_event_t event)
{
    if(event == LV_EVENT_CLICKED) {
        printf("Clicked\n");
    }
}

Learn more about the events in the Event overview section.

Examples

Button with label

lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL);     /*Add a button the current screen*/
lv_obj_set_pos(btn, 10, 10);                            /*Set its position*/
lv_obj_set_size(btn, 100, 50);                          /*Set its size*/
lv_obj_set_event_cb(btn, btn_event_cb);                 /*Assign a callback to the button*/

lv_obj_t * label = lv_label_create(btn, NULL);          /*Add a label to the button*/
lv_label_set_text(label, "Button");                     /*Set the labels text*/

...

void btn_event_cb(lv_obj_t * btn, lv_event_t event)
{
    if(event == LV_EVENT_CLICKED) {
        printf("Clicked\n");
    }
}

LVGL button with label example

Use LVGL from Micropython

Learn more about Micropython.

# Create a Button and a Label
scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")

# Load the screen
lv.scr_load(scr)

Contributing

To ask questions please use the Forum. For development-related things (bug reports, feature suggestions) use GitHub's Issue tracker.

If you are interested in contributing to LVGL you can

  • Help others in the Forum.
  • Inspire people by speaking about your project in My project category in the Forum.
  • Improve and/or translate the documentation. Go to the Documentation repository to learn more
  • Write a blog post about your experiences. See how to do it in the Blog repository
  • Report and/or fix bugs in GitHub's issue tracker
  • Help in the developement. Check the Open issues especially the ones with Help wanted label and tell your ideas about a topic or implement a feature.

Before sending Pull requests, please read the following guides: