mirror of https://github.com/arendst/Tasmota.git
Merge pull request #14849 from s-hadinger/lv_berry_readme
Add README for lv_berry
This commit is contained in:
commit
c0cc81cd26
|
@ -0,0 +1,237 @@
|
|||
# LVGL + Berry
|
||||
|
||||
This repo contains a full binding of LVGL to the Berry language. This project is similar to the Micropython+lvgl project in its spirit, and provides easy to use scripting for lvgl on embedded devices. It is used by the Tasmota open-source project for ESP32 based devices.
|
||||
|
||||
**Supported version**: LVGL 8.2.0
|
||||
|
||||
## Why use LVGL + Berry
|
||||
|
||||
LVGL + Berry mapping provides an easy-to-use programming language on top of LVGL powerful APIs. This is ideal for rapid scripting as well as production applications. The Berry mapping comes from the open-source [Tasmota](https://tasmota.github.io/docs/) project for ESP32 based devices, and leverages a vivid ecosystem.
|
||||
|
||||
![lvgl_info](https://user-images.githubusercontent.com/49731213/153846806-2571f872-f85f-4f31-becb-b6bebc10a324.png)
|
||||
|
||||
Quickstart with this short tutorial [LVGL in less than 10 minutes with Tasmota](https://tasmota.github.io/docs/LVGL_in_10_minutes/).
|
||||
|
||||
[Berry](https://github.com/berry-lang/berry) is an ultra-lightweight dynamically typed embedded scripting language. It is designed for lower-performance embedded devices. The interpreter of Berry includes a one-pass compiler and register-based VM, all the code is written in ANSI C99. Berry offers a syntax very similar to Python, and is inspired from LUA VM.
|
||||
|
||||
|
||||
## Quickstart
|
||||
|
||||
Let's start with a simple example:
|
||||
|
||||
```
|
||||
#- start LVGL and init environment (can be called multiple times) -#
|
||||
lv.start()
|
||||
|
||||
hres = lv.get_hor_res() # horizontal resolution of default display
|
||||
vres = lv.get_ver_res() # vertical resolution of default display
|
||||
|
||||
scr = lv.scr_act() # default screen object
|
||||
|
||||
#- Background with a gradient from black #000000 (bottom) to dark blue #0000A0 (top) -#
|
||||
scr.set_style_bg_color(lv.color(0x0000A0), lv.PART_MAIN | lv.STATE_DEFAULT)
|
||||
scr.set_style_bg_grad_color(lv.color(0x000000), lv.PART_MAIN | lv.STATE_DEFAULT)
|
||||
scr.set_style_bg_grad_dir(lv.GRAD_DIR_VER, lv.PART_MAIN | lv.STATE_DEFAULT)
|
||||
```
|
||||
|
||||
Let's add a label:
|
||||
|
||||
```
|
||||
t = lv.label(scr)
|
||||
t.set_style_text_color(lv.color(0xFFFFFF), lv.PART_MAIN | lv.STATE_DEFAULT)
|
||||
t.set_text("Hello LVGL + Berry!")
|
||||
t.set_align(lv.ALIGN_TOP_MID)
|
||||
```
|
||||
|
||||
Let's add a style for buttons:
|
||||
|
||||
```
|
||||
#- create a style for the buttons -#
|
||||
btn_style = lv.style()
|
||||
btn_style.set_radius(10) # radius of rounded corners
|
||||
btn_style.set_bg_opa(lv.OPA_COVER) # 100% background opacity
|
||||
btn_style.set_bg_color(lv.color(0x1fa3ec)) # background color #1FA3EC (Tasmota Blue)
|
||||
btn_style.set_border_color(lv.color(0x0000FF)) # border color #0000FF
|
||||
btn_style.set_text_color(lv.color(0xFFFFFF)) # text color white #FFFFFF
|
||||
```
|
||||
|
||||
Let's add a single button with using a symbol:
|
||||
|
||||
```
|
||||
home_btn = lv.btn(scr) # center button
|
||||
home_btn.set_size(80, 30)
|
||||
home_btn.add_style(btn_style, lv.PART_MAIN | lv.STATE_DEFAULT)
|
||||
home_btn.set_align(lv.ALIGN_BOTTOM_MID)
|
||||
home_label = lv.label(home_btn)
|
||||
home_label.set_text(lv.SYMBOL_HOME) # set text as Home icon
|
||||
home_label.center()
|
||||
```
|
||||
|
||||
|
||||
Let's now add a colorwheel widget:
|
||||
|
||||
```
|
||||
colw = lv.colorwheel(scr, false)
|
||||
colw.set_size(100, 100)
|
||||
colw.set_pos(20,30)
|
||||
```
|
||||
|
||||
![LVGL_Berry](https://user-images.githubusercontent.com/49731213/153846625-52855e95-b1a2-4a68-a495-1759f490794e.png)
|
||||
|
||||
|
||||
As a general rule:
|
||||
|
||||
- calls to general APIs are mapped to module `lv`. E.g. `lv_get_hor_res()` translates to
|
||||
- enums are also mapped to module `lv`
|
||||
- widgets constructors are classes in module `lv`
|
||||
- calls to widgets are object methods (skip the first argument which is implicit)
|
||||
|
||||
|
||||
C call|Berry call
|
||||
:---|:---
|
||||
`lv_get_hor_res()`|`lv.get_hor_res()`
|
||||
`LV_ALIGN_BOTTOM_MID`|`lv.ALIGN_BOTTOM_MID`
|
||||
`lv_colorwheel_create(scr, false)`|`lv.colorwheel(scr, false)` or `lv.lv_colorwheel(scr, false)`
|
||||
`lv_obj_set_size(colw, 100, 100)`|`colw.set_size(100, 100)`
|
||||
|
||||
## Supported features
|
||||
|
||||
lv_berry provides an object-oriented interface for LVGL, and covers over 99% of LVGL's APIs, noticeably:
|
||||
|
||||
- access to almost all LVGL APIs (over 1000+ calls)
|
||||
- automatic type checking and type conversion based on `C` headers
|
||||
- access to all `C` ENUMs constants (500+)
|
||||
- full support for C callbacks in Berry
|
||||
- full support for LVGL internal memory structures
|
||||
- ability to create pure Berry custom widgets and custom classes
|
||||
- supports only 16 bits display (swapped or not)
|
||||
|
||||
What is currently not supported (but could be if there is demand):
|
||||
|
||||
- multi-screen devices (no support in Tasmota anyways)
|
||||
- bidirectional text support
|
||||
- LVGL tasks (Berry has its own task system)
|
||||
- non-16 bits display
|
||||
|
||||
## Type system
|
||||
|
||||
### Widgets classes
|
||||
|
||||
Although LVGL is C code and is not formally object oriented, LVGL widget follow an inheritance model. Each widget is a virtual subclass of `lv_obj` structure.
|
||||
|
||||
Berry builds an actual Object Oriented class system, with a base class `lv_obj` and subclasses.
|
||||
|
||||
The class names supported are defined in `convert.py` and are currently standard widgets:
|
||||
|
||||
```
|
||||
'lv_arc', 'lv_bar', 'lv_btn', 'lv_btnmatrix', 'lv_canvas', 'lv_checkbox', 'lv_dropdown', 'lv_img', 'lv_label', 'lv_line', 'lv_roller', 'lv_slider', 'lv_switch', 'lv_table', 'lv_textarea'
|
||||
```
|
||||
|
||||
And extra widgets:
|
||||
|
||||
```
|
||||
'lv_chart', 'lv_colorwheel', 'lv_imgbtn', 'lv_led', 'lv_meter', 'lv_msgbox', 'lv_spinbox', 'lv_spinner'
|
||||
```
|
||||
|
||||
Additional 'special' classes are (they do not inherit from `lv_obj`):
|
||||
|
||||
```
|
||||
'lv_obj', 'lv_group', 'lv_style', 'lv_indev', 'lv_disp'
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
An exception for LVGL colors, they are defined as 32 bits RGB values as follows, and not based on their C representation:
|
||||
|
||||
```C
|
||||
COLOR_WHITE=0xFFFFFF
|
||||
COLOR_SILVER=0xC0C0C0
|
||||
COLOR_GRAY=0x808080
|
||||
COLOR_BLACK=0x000000
|
||||
COLOR_RED=0xFF0000
|
||||
COLOR_MAROON=0x800000
|
||||
COLOR_YELLOW=0xFFFF00
|
||||
COLOR_OLIVE=0x808000
|
||||
COLOR_LIME=0x00FF00
|
||||
COLOR_GREEN=0x008000
|
||||
COLOR_CYAN=0x00FFFF
|
||||
COLOR_AQUA=0x00FFFF
|
||||
COLOR_TEAL=0x008080
|
||||
COLOR_BLUE=0x0000FF
|
||||
COLOR_NAVY=0x000080
|
||||
COLOR_MAGENTA=0xFF00FF
|
||||
COLOR_PURPLE=0x800080
|
||||
```
|
||||
|
||||
Example: `lv.COLOR_RED`
|
||||
|
||||
`lv_color` is a simple class that maps RGB 32 bits colors (as 32 bits int) to the internal representation of colors (usually 16 bits).
|
||||
|
||||
Don't be surprised that getting back a value is the 16 bits color converted to 32 bits - rounding errors may occur:
|
||||
|
||||
```
|
||||
[Berry Console]
|
||||
> c = lv_color(0x808080)
|
||||
> c
|
||||
lv_color(0xff838183 - native:0x1084)
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
- 0xff838183 - is the 32 bits color, with alpha channel (opaque)
|
||||
- 0x1084 - is the native internal representation as 16 bits color with swapped bytes
|
||||
|
||||
## Build system
|
||||
|
||||
More details about the mapping are provided in [Tasmota LVGL Internals](https://tasmota.github.io/docs/LVGL_Internals/)
|
||||
|
||||
`lv_berry` uses a semi-automated parsing of lvgl's `C` headers to generate the Berry mapping. The process is automated, but may require small parser adjustments with new versions.
|
||||
|
||||
This module relies on [berry_mapping](https://github.com/berry-lang/berry_mapping) module to automate the mapping of C functions.
|
||||
|
||||
**Phase 1: Parse LVGL source**
|
||||
|
||||
This first phase parses most C headers from the LVGL source tree and generates two files:
|
||||
|
||||
- `mapping/lv_enum.h` containing all the `enum` values from LVGL (constants)
|
||||
- `mapping/lv_funcs.h` containing all the functions of the LVGL API normalized to 1 function per line, and with cleaned argument signature.
|
||||
|
||||
```
|
||||
(`cd` in folder tools)
|
||||
|
||||
❯ python3 preprocessor.py
|
||||
(no output)
|
||||
```
|
||||
|
||||
**Phase 2: Generate automatic Berry mapping**
|
||||
|
||||
From the two files created in the previous step, all the requires C files are created for the Berry mapping.
|
||||
|
||||
```
|
||||
(`cd`in folder tools)
|
||||
|
||||
> python3 convert.py
|
||||
| callback types['lv_group_focus_cb', 'lv_event_cb', 'lv_constructor_cb', 'lv_layout_update_cb', 'lv_obj_tree_walk_cb', 'lv_theme_apply_cb', 'lv_color_filter_cb', 'lv_anim_path_cb']
|
||||
```
|
||||
|
||||
The output should look as above, and indicates the C function that have been ignored (if any) if their return type is listed above. It also lists the callback types supported.
|
||||
|
||||
|
||||
**Phase 3: Generate the Berry pre-compiled stubs**
|
||||
|
||||
This phase is specific to Berry pre-compiled modules and classes.
|
||||
|
||||
```
|
||||
(berry)
|
||||
|
||||
> python3 tools/pycoc/main.py -o generate src default ../berry_mapping/src ../lv_berry/src ../lv_berry/generate -c default/berry_conf.h
|
||||
(no output)
|
||||
```
|
||||
|
||||
**Phase 4: compile Tasmota using platform.io as usual**
|
||||
|
||||
## Future projects
|
||||
|
||||
There is an on-going project to provide [OpenHASP](https://openhasp.haswitchplate.com/) emulation using LVGL+Berry. This will provide a super-easy to use JSON graphical description of UI interfaces, with no or very low knowledge of LVGL APIs.
|
||||
|
||||
Stay tuned!
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "Berry mapping to LVGL",
|
||||
"version": "1.0",
|
||||
"description": "Mapping of LVGL functions to Berry. Currently supporting LVGL 8.0.2",
|
||||
"description": "Mapping of LVGL functions to Berry. Currently supporting LVGL 8.2.0",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/lvgl/lv_berry",
|
||||
"frameworks": "arduino",
|
||||
|
|
Loading…
Reference in New Issue