-
Notifications
You must be signed in to change notification settings - Fork 224
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #141 from ncmreynolds/LVGL9_example
LVGL9 example
- Loading branch information
Showing
6 changed files
with
1,223 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
/* Using LVGL with Arduino requires some extra steps... | ||
* | ||
* Be sure to read the docs here: https://docs.lvgl.io/master/integration/framework/arduino.html | ||
* but note you should use the lv_conf.h from the repo as it is pre-edited to work. | ||
* | ||
* You can always edit your own lv_conf.h later and exclude the example options once the build environment is working. | ||
* | ||
* Note you MUST move the 'examples' and 'demos' folders into the 'src' folder inside the lvgl library folder | ||
* otherwise this will not compile, please see README.md in the repo. | ||
* | ||
*/ | ||
#include <lvgl.h> | ||
|
||
#include <TFT_eSPI.h> | ||
|
||
#include <examples/lv_examples.h> | ||
#include <demos/lv_demos.h> | ||
|
||
#include <XPT2046_Touchscreen.h> | ||
// A library for interfacing with the touch screen | ||
// | ||
// Can be installed from the library manager (Search for "XPT2046") | ||
//https://github.com/PaulStoffregen/XPT2046_Touchscreen | ||
// ---------------------------- | ||
// Touch Screen pins | ||
// ---------------------------- | ||
|
||
// The CYD touch uses some non default | ||
// SPI pins | ||
|
||
#define XPT2046_IRQ 36 | ||
#define XPT2046_MOSI 32 | ||
#define XPT2046_MISO 39 | ||
#define XPT2046_CLK 25 | ||
#define XPT2046_CS 33 | ||
SPIClass touchscreenSpi = SPIClass(VSPI); | ||
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ); | ||
uint16_t touchScreenMinimumX = 200, touchScreenMaximumX = 3700, touchScreenMinimumY = 240,touchScreenMaximumY = 3800; | ||
|
||
/*Set to your screen resolution*/ | ||
#define TFT_HOR_RES 320 | ||
#define TFT_VER_RES 240 | ||
|
||
/*LVGL draw into this buffer, 1/10 screen size usually works well. The size is in bytes*/ | ||
#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8)) | ||
|
||
#if LV_USE_LOG != 0 | ||
void my_print( lv_log_level_t level, const char * buf ) | ||
{ | ||
LV_UNUSED(level); | ||
Serial.println(buf); | ||
Serial.flush(); | ||
} | ||
#endif | ||
|
||
/* LVGL calls it when a rendered image needs to copied to the display*/ | ||
void my_disp_flush( lv_display_t *disp, const lv_area_t *area, uint8_t * px_map) | ||
{ | ||
/*Call it to tell LVGL you are ready*/ | ||
lv_disp_flush_ready(disp); | ||
} | ||
/*Read the touchpad*/ | ||
void my_touchpad_read( lv_indev_t * indev, lv_indev_data_t * data ) | ||
{ | ||
if(touchscreen.touched()) | ||
{ | ||
TS_Point p = touchscreen.getPoint(); | ||
//Some very basic auto calibration so it doesn't go out of range | ||
if(p.x < touchScreenMinimumX) touchScreenMinimumX = p.x; | ||
if(p.x > touchScreenMaximumX) touchScreenMaximumX = p.x; | ||
if(p.y < touchScreenMinimumY) touchScreenMinimumY = p.y; | ||
if(p.y > touchScreenMaximumY) touchScreenMaximumY = p.y; | ||
//Map this to the pixel position | ||
data->point.x = map(p.x,touchScreenMinimumX,touchScreenMaximumX,1,TFT_HOR_RES); /* Touchscreen X calibration */ | ||
data->point.y = map(p.y,touchScreenMinimumY,touchScreenMaximumY,1,TFT_VER_RES); /* Touchscreen Y calibration */ | ||
data->state = LV_INDEV_STATE_PRESSED; | ||
/* | ||
Serial.print("Touch x "); | ||
Serial.print(data->point.x); | ||
Serial.print(" y "); | ||
Serial.println(data->point.y); | ||
*/ | ||
} | ||
else | ||
{ | ||
data->state = LV_INDEV_STATE_RELEASED; | ||
} | ||
} | ||
|
||
lv_indev_t * indev; //Touchscreen input device | ||
uint8_t* draw_buf; //draw_buf is allocated on heap otherwise the static area is too big on ESP32 at compile | ||
uint32_t lastTick = 0; //Used to track the tick timer | ||
|
||
void setup() | ||
{ | ||
//Some basic info on the Serial console | ||
String LVGL_Arduino = "LVGL demo "; | ||
LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch(); | ||
Serial.begin(115200); | ||
Serial.println(LVGL_Arduino); | ||
|
||
//Initialise the touchscreen | ||
touchscreenSpi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); /* Start second SPI bus for touchscreen */ | ||
touchscreen.begin(touchscreenSpi); /* Touchscreen init */ | ||
touchscreen.setRotation(3); /* Inverted landscape orientation to match screen */ | ||
|
||
//Initialise LVGL | ||
lv_init(); | ||
draw_buf = new uint8_t[DRAW_BUF_SIZE]; | ||
lv_display_t * disp; | ||
disp = lv_tft_espi_create(TFT_HOR_RES, TFT_VER_RES, draw_buf, DRAW_BUF_SIZE); | ||
|
||
//Initialize the XPT2046 input device driver | ||
indev = lv_indev_create(); | ||
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); | ||
lv_indev_set_read_cb(indev, my_touchpad_read); | ||
|
||
/* Try an example. See all the examples | ||
* online: https://docs.lvgl.io/master/examples.html | ||
*/ | ||
// lv_example_animimg_1(); | ||
// lv_example_arc_1(); | ||
// lv_example_arc_2(); | ||
// lv_example_bar_1(); | ||
// lv_example_bar_2(); | ||
// lv_example_bar_3(); | ||
// lv_example_bar_4(); | ||
// lv_example_bar_5(); | ||
// lv_example_bar_6(); | ||
// lv_example_btn_1(); | ||
// lv_example_btn_2(); | ||
// lv_example_btn_3(); | ||
// lv_example_btnmatrix_1(); | ||
// lv_example_btnmatrix_2(); | ||
// lv_example_btnmatrix_3(); | ||
// lv_example_calendar_1(); | ||
// lv_example_chart_1(); | ||
// lv_example_chart_2(); | ||
// lv_example_chart_3(); | ||
// lv_example_chart_4(); | ||
// lv_example_chart_5(); | ||
// lv_example_chart_6(); | ||
// lv_example_chart_7(); | ||
// lv_example_chart_8(); | ||
// lv_example_chart_9(); | ||
// lv_example_checkbox_1(); | ||
// lv_example_checkbox_2(); | ||
// lv_example_dropdown_1(); | ||
// lv_example_dropdown_2(); | ||
// lv_example_dropdown_3(); | ||
// lv_example_keyboard_1(); | ||
// lv_example_label_1(); | ||
// lv_example_label_2(); | ||
// lv_example_label_3(); | ||
// lv_example_label_4(); | ||
// lv_example_label_5(); | ||
// lv_example_line_1(); | ||
// lv_example_list_1(); | ||
// lv_example_list_2(); | ||
// lv_example_msgbox_1(); | ||
// lv_example_roller_1(); | ||
// lv_example_roller_2(); | ||
// lv_example_roller_3(); | ||
// lv_example_slider_1(); | ||
// lv_example_slider_2(); | ||
// lv_example_slider_3(); | ||
// lv_example_span_1(); | ||
// lv_example_spinbox_1(); | ||
// lv_example_spinner_1(); | ||
// lv_example_switch_1(); | ||
// lv_example_table_1(); | ||
// lv_example_table_2(); | ||
// lv_example_tabview_1(); | ||
// lv_example_tabview_2(); | ||
// lv_example_textarea_1(); | ||
// lv_example_textarea_2(); | ||
// lv_example_textarea_3(); | ||
// lv_example_tileview_1(); | ||
// lv_example_win_1(); | ||
|
||
//Or try out the large standard widgets demo | ||
lv_demo_widgets(); | ||
// lv_demo_benchmark(); | ||
// lv_demo_keypad_encoder(); | ||
|
||
//Done | ||
Serial.println( "Setup done" ); | ||
} | ||
|
||
void loop() | ||
{ | ||
lv_tick_inc(millis() - lastTick); //Update the tick timer. Tick is new for LVGL 9 | ||
lastTick = millis(); | ||
lv_timer_handler(); //Update the UI | ||
delay(5); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# LVGL examples | ||
|
||
[LVGL](https://lvgl.io/) is a popular library for creating user interfaces on resource constrained devices like the ESP32. | ||
|
||
You can install LVGL through the Arduino Library manager, but it will not compile 'out of the box'. Similarly to TFT_eSPI it needs manual editing of the configuration files and this is a slightly awkward process. | ||
|
||
Also, LVGL on Arduino tends to assume that you are using the touchscreen component of the TFT_eSPI display library. However the original CYD cannot use this built in touchscreen support as the XPT2046 touchscreen controller is connected to a different SPI bus from the display. | ||
|
||
The LVGL_Arduino example in here is a copy of the default LVGL Arduino example edited slightly to make the examples easier to try and include support for the XPT2046 driver used elsewhere in this repository. | ||
|
||
## Version information | ||
|
||
This has been tested with the following as of 27/02/2024 and may not work with other versions. All were installed via the Arduino IDE or Library Manager rather than manual custom installation. | ||
|
||
- Arduino IDE v1.8.19 on Windows 11 | ||
- [ESP32 Arduino Core](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html) v2.0.14 | ||
- TFT_eSPI v2.5.34, already configured and tested against the CYD | ||
- XPT2046_touchscreen v1.4.0, already configured and tested against the CYD | ||
- LVGL version v9.0.0 | ||
|
||
## Installation | ||
|
||
To be able to use the LVGL examples and demos in this repo with the Arduino IDE, take the following steps. | ||
|
||
- Install TFT_eSPI from the Arduino Library Manager and [make sure your display works with the examples](https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/blob/main/SETUP.md), as described elsewhere in this repo. | ||
|
||
<img src="libraryManager2.png" style="zoom:67%;" /> | ||
|
||
- Install XPT2046_Touchscreen from the Arduino Library Manager and [make sure your touchscreen works](https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/tree/main/Examples/Basics/2-TouchTest), as described elsewhere in this repo. | ||
|
||
<img src="libraryManager3.png" style="zoom:67%;" /> | ||
|
||
- Install LVGL from the Arduino Library Manager, search for 'lvgl' and install the one marked. Note this is version 9.0.0, these instructions may not work with other versions, especially later ones. See other examples for other versions. | ||
|
||
<img src="libraryManager1.png" style="zoom: 67%;" /> | ||
|
||
- **Do not** install 'lv_examples' from the Arduino Library Manager, it is for older versions of LVGL than 8.3.x. | ||
- **Do not** install 'lv_arduino' from the Arduino Library Manager, it is a different port of lvgl than the one this example works with. | ||
|
||
- Copy **lv_conf.h** from the folder "**/ESP32-Cheap-Yellow-Display/Examples/LVGL9/**" in this repository to the Arduino 'libraries' folder. Do not place it in the LVGL library folder, place it in the folder 'above' that which is the container for all of your Arduino library folders. See the [Arduino documentation](https://docs.arduino.cc/software/ide-v1/tutorials/installing-libraries) for help in locating the 'libraries' folder as it can vary between systems. Yes, this is an unusual step but it is necessary. | ||
|
||
- Within the LVGL library directory **move the 'examples' directory into the 'src' directory**. This is due to a limitation of the Arduino IDE build system compared to other build systems used by LVGL. You will need to repeat this process if you reinstall or change the version of LVGL. Yes, this is an unusual step but it is necessary. | ||
|
||
- Within the LVGL library directory **move the 'demos' directory into the 'src' directory**, as above. | ||
|
||
## Touchscreen calibration | ||
|
||
Lines 38 defines variable that map the readings from the resistive touchscreen to screen locations. These values were chosen based off an example CYD, **you will need to change them slightly** to make your touchscreen work accurately. There is no calibration routine built into the example. | ||
|
||
```c++ | ||
uint16_t touchScreenMinimumX = 200, touchScreenMaximumX = 3700, touchScreenMinimumY = 240,touchScreenMaximumY = 3800; | ||
``` | ||
|
||
You can use the '[TouchTest.ino](https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/tree/main/Examples/Basics/2-TouchTest)' example from elsewhere in this repository to get reasonable values for your touchscreen. Resistive touchscreens are never perfect and can drift over time. | ||
|
||
## Choosing an example | ||
|
||
The LVGL examples are not separate sketches, they are function calls you uncomment inside the single example sketch. Uncomment one line at a time and compile and upload the sketch again to see each example or demo. The build process for LVGL is quite long as it's a large library. | ||
|
||
- Lines 121-179 are examples of a particular style of widget. Some are animated or mildly interactive. | ||
- Lines 182-184 are more complete demos with multiple widgets of various types. The benchmark demo does a benchmark. | ||
|
||
The sketch comes with the 'lv_demo_widgets' demo ready to go. | ||
|
||
Not all of the examples/demos mentioned in the LVGL docs work, but the ones that do are included in the sketch for you to uncomment and try. | ||
|
||
## Disabling example/demo compilation | ||
|
||
Once you are done with the examples and demos you should probably remove support for them as it will reduce compile time. | ||
|
||
To do this, edit 'lv_conf.h' in the Arduino 'libraries' folder and change '#define LV_BUILD_EXAMPLES 1' to '#define LV_BUILD_EXAMPLES 0' and '#define LV_USE_DEMO_WIDGETS 1' to '#define LV_USE_DEMO_WIDGETS 0'. | ||
|
||
See the LVGL documentation for proper detail on what this involves, but it is not absolutely necessary. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.