From 73226d7ee3e2a5f31942f05811bc7aee6d3a8be1 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 18 Jan 2020 22:42:49 -0800 Subject: [PATCH] =?UTF-8?q?ESP32=20|=20LittlevGL=20|=20Arduino=20IDE=20-?= =?UTF-8?q?=20[Part.1]=20Basic=20LittlevGL=20for=20Simple=20Note=20App?= =?UTF-8?q?=F0=9F=93=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Part1/0_lv_slider/0_lv_slider.ino | 200 ++++++++ .../1_lv_theme_night/1_lv_theme_night.ino | 437 ++++++++++++++++++ .../2_lv_button_test/2_lv_button_test.ino | 159 +++++++ .../3_simple_note_step1.ino | 170 +++++++ 4 files changed, 966 insertions(+) create mode 100644 ESP32_LITTLEVGL_ARDUINO_IDE/Part1/0_lv_slider/0_lv_slider.ino create mode 100644 ESP32_LITTLEVGL_ARDUINO_IDE/Part1/1_lv_theme_night/1_lv_theme_night.ino create mode 100644 ESP32_LITTLEVGL_ARDUINO_IDE/Part1/2_lv_button_test/2_lv_button_test.ino create mode 100644 ESP32_LITTLEVGL_ARDUINO_IDE/Part1/3_simple_note_step1/3_simple_note_step1.ino diff --git a/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/0_lv_slider/0_lv_slider.ino b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/0_lv_slider/0_lv_slider.ino new file mode 100644 index 0000000..a202098 --- /dev/null +++ b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/0_lv_slider/0_lv_slider.ino @@ -0,0 +1,200 @@ +#include +#include +#include + +#define LVGL_TICK_PERIOD 60 + +Ticker tick; /* timer for interrupt handler */ +TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ +static lv_disp_buf_t disp_buf; +static lv_color_t buf[LV_HOR_RES_MAX * 10]; + +lv_obj_t * slider_label; +int screenWidth = 480; +int screenHeight = 320; + +/* Display flushing */ +void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) +{ + uint16_t c; + + tft.startWrite(); /* Start new TFT transaction */ + tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */ + for (int y = area->y1; y <= area->y2; y++) { + for (int x = area->x1; x <= area->x2; x++) { + c = color_p->full; + tft.writeColor(c, 1); + color_p++; + } + } + tft.endWrite(); /* terminate TFT transaction */ + lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ +} + +bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) +{ + uint16_t touchX, touchY; + + bool touched = tft.getTouch(&touchX, &touchY, 600); + + if(!touched) + { + return false; + } + + if(touchX>screenWidth || touchY > screenHeight) + { + Serial.println("Y or y outside of expected parameters.."); + Serial.print("y:"); + Serial.print(touchX); + Serial.print(" x:"); + Serial.print(touchY); + } + else + { + + data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + + /*Save the state and save the pressed coordinate*/ + //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 = touchX; + data->point.y = touchY; + + Serial.print("Data x"); + Serial.println(touchX); + + Serial.print("Data y"); + Serial.println(touchY); + + } + + return false; /*Return `false` because we are not buffering and no more data to read*/ +} + +/* Interrupt driven periodic handler */ +static void lv_tick_handler(void) +{ + + lv_tick_inc(LVGL_TICK_PERIOD); +} + + + +void slider_event_cb(lv_obj_t * slider, lv_event_t event) +{ + + printEvent("Slider", event); + + if(event == LV_EVENT_VALUE_CHANGED) { + static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte */ + snprintf(buf, 4, "%u", lv_slider_get_value(slider)); + lv_label_set_text(slider_label, buf); /*Refresh the text*/ + } +} + +void printEvent(String Event, lv_event_t event) +{ + + Serial.print(Event); + printf(" "); + + switch(event) { + case LV_EVENT_PRESSED: + printf("Pressed\n"); + break; + + case LV_EVENT_SHORT_CLICKED: + printf("Short clicked\n"); + break; + + case LV_EVENT_CLICKED: + printf("Clicked\n"); + break; + + case LV_EVENT_LONG_PRESSED: + printf("Long press\n"); + break; + + case LV_EVENT_LONG_PRESSED_REPEAT: + printf("Long press repeat\n"); + break; + + case LV_EVENT_RELEASED: + printf("Released\n"); + break; + } +} + + +void setup() { + + Serial.begin(115200); /* prepare for possible serial debug */ + + lv_init(); + + tft.begin(); /* TFT init */ + tft.setRotation(3); + + //uint16_t calData[5] = { 275, 3620, 264, 3532, 1 }; + uint16_t calData[5] = {299, 3588, 348, 3474, 1}; + tft.setTouch(calData); + + lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); + + /*Initialize the display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = screenWidth; + disp_drv.ver_res = screenHeight; + disp_drv.flush_cb = my_disp_flush; + disp_drv.buffer = &disp_buf; + lv_disp_drv_register(&disp_drv); + + lv_indev_drv_t indev_drv; + 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*/ + + + /*Initialize the graphics library's tick*/ + tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler); + + //Set the theme.. + lv_theme_t * th = lv_theme_night_init(210, NULL); //Set a HUE value and a Font for the Night Theme + lv_theme_set_current(th); + + lv_obj_t * scr = lv_cont_create(NULL, NULL); + lv_disp_load_scr(scr); + + //lv_obj_t * tv = lv_tabview_create(scr, NULL); + //lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL)); + + /* Create simple label */ + lv_obj_t *label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(label, "Hello Arduino! (V6.1)"); + lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -50); + + /* Create a slider in the center of the display */ + lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL); + lv_obj_set_width(slider, screenWidth-50); /*Set the width*/ + lv_obj_set_height(slider, 50); + lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the center of the parent (screen)*/ + lv_obj_set_event_cb(slider, slider_event_cb); /*Assign an event function*/ + + /* Create a label below the slider */ + slider_label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(slider_label, "0"); + lv_obj_set_auto_realign(slider, true); + lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); + +} + + +void loop() { + + lv_task_handler(); /* let the GUI do its work */ + delay(5); +} diff --git a/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/1_lv_theme_night/1_lv_theme_night.ino b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/1_lv_theme_night/1_lv_theme_night.ino new file mode 100644 index 0000000..3e802fc --- /dev/null +++ b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/1_lv_theme_night/1_lv_theme_night.ino @@ -0,0 +1,437 @@ +#include +#include +#include + +#define LVGL_TICK_PERIOD 60 + +Ticker tick; /* timer for interrupt handler */ +TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ +static lv_disp_buf_t disp_buf; +static lv_color_t buf[LV_HOR_RES_MAX * 10]; + +lv_obj_t * slider_label; +int screenWidth = 480; +int screenHeight = 320; + +/* Display flushing */ +void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) +{ + uint16_t c; + + tft.startWrite(); /* Start new TFT transaction */ + tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */ + for (int y = area->y1; y <= area->y2; y++) { + for (int x = area->x1; x <= area->x2; x++) { + c = color_p->full; + tft.writeColor(c, 1); + color_p++; + } + } + tft.endWrite(); /* terminate TFT transaction */ + lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ +} + +bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) +{ + uint16_t touchX, touchY; + + bool touched = tft.getTouch(&touchX, &touchY, 600); + + if(!touched) + { + return false; + } + + if(touchX>screenWidth || touchY > screenHeight) + { + Serial.println("Y or y outside of expected parameters.."); + Serial.print("y:"); + Serial.print(touchX); + Serial.print(" x:"); + Serial.print(touchY); + } + else + { + + data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + + /*Save the state and save the pressed coordinate*/ + //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 = touchX; + data->point.y = touchY; + + Serial.print("Data x"); + Serial.println(touchX); + + Serial.print("Data y"); + Serial.println(touchY); + + } + + return false; /*Return `false` because we are not buffering and no more data to read*/ +} + +/* Interrupt driven periodic handler */ +static void lv_tick_handler(void) +{ + + lv_tick_inc(LVGL_TICK_PERIOD); +} + + +void setup() { + + Serial.begin(115200); /* prepare for possible serial debug */ + + lv_init(); + + tft.begin(); /* TFT init */ + tft.setRotation(3); + + //uint16_t calData[5] = { 275, 3620, 264, 3532, 1 }; + uint16_t calData[5] = {299, 3588, 348, 3474, 1}; + tft.setTouch(calData); + + lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); + + /*Initialize the display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = screenWidth; + disp_drv.ver_res = screenHeight; + disp_drv.flush_cb = my_disp_flush; + disp_drv.buffer = &disp_buf; + lv_disp_drv_register(&disp_drv); + + lv_indev_drv_t indev_drv; + 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*/ + + + /*Initialize the graphics library's tick*/ + tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler); + + //Set the theme.. + lv_theme_t * th = lv_theme_night_init(210, NULL); //Set a HUE value and a Font for the Night Theme + lv_test_theme_1(th); + +} + + +void loop() { + + lv_task_handler(); /* let the GUI do its work */ + delay(5); +} + + +/********************** + * STATIC PROTOTYPES + **********************/ +static void create_tab1(lv_obj_t * parent); +static void create_tab2(lv_obj_t * parent); +static void create_tab3(lv_obj_t * parent); + + + +void lv_test_theme_1(lv_theme_t * th) +{ + lv_theme_set_current(th); + th = lv_theme_get_current(); /*If `LV_THEME_LIVE_UPDATE 1` `th` is not used directly so get the real theme after set*/ + lv_obj_t * scr = lv_cont_create(NULL, NULL); + lv_disp_load_scr(scr); + + lv_obj_t * tv = lv_tabview_create(scr, NULL); + lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL)); + lv_obj_t * tab1 = lv_tabview_add_tab(tv, "Tab 1"); + lv_obj_t * tab2 = lv_tabview_add_tab(tv, "Tab 2"); + lv_obj_t * tab3 = lv_tabview_add_tab(tv, "Tab 3"); + + create_tab1(tab1); + create_tab2(tab2); + create_tab3(tab3); +} + + +/********************** + * STATIC FUNCTIONS + **********************/ +static void create_tab1(lv_obj_t * parent) +{ + lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY); + + lv_theme_t * th = lv_theme_get_current(); + + static lv_style_t h_style; + lv_style_copy(&h_style, &lv_style_transp); + h_style.body.padding.inner = LV_DPI / 10; + h_style.body.padding.left = LV_DPI / 4; + h_style.body.padding.right = LV_DPI / 4; + h_style.body.padding.top = LV_DPI / 10; + h_style.body.padding.bottom = LV_DPI / 10; + + lv_obj_t * h = lv_cont_create(parent, NULL); + lv_obj_set_style(h, &h_style); + lv_obj_set_click(h, false); + lv_cont_set_fit(h, LV_FIT_TIGHT); + lv_cont_set_layout(h, LV_LAYOUT_COL_M); + + lv_obj_t * btn = lv_btn_create(h, NULL); + lv_btn_set_fit(btn, LV_FIT_TIGHT); + lv_btn_set_toggle(btn, true); + lv_obj_t * btn_label = lv_label_create(btn, NULL); + lv_label_set_text(btn_label, "Button"); + + btn = lv_btn_create(h, btn); + lv_btn_toggle(btn); + btn_label = lv_label_create(btn, NULL); + lv_label_set_text(btn_label, "Toggled"); + + btn = lv_btn_create(h, btn); + lv_btn_set_state(btn, LV_BTN_STATE_INA); + btn_label = lv_label_create(btn, NULL); + lv_label_set_text(btn_label, "Inactive"); + + lv_obj_t * label = lv_label_create(h, NULL); + lv_label_set_text(label, "Primary"); + lv_obj_set_style(label, th->style.label.prim); + + label = lv_label_create(h, NULL); + lv_label_set_text(label, "Secondary"); + lv_obj_set_style(label, th->style.label.sec); + + label = lv_label_create(h, NULL); + lv_label_set_text(label, "Hint"); + lv_obj_set_style(label, th->style.label.hint); + + static const char * btnm_str[] = {"1", "2", "3", LV_SYMBOL_OK, LV_SYMBOL_CLOSE, ""}; + lv_obj_t * btnm = lv_btnm_create(h, NULL); + lv_obj_set_size(btnm, lv_disp_get_hor_res(NULL) / 4, 2 * LV_DPI / 3); + lv_btnm_set_map(btnm, btnm_str); + lv_btnm_set_btn_ctrl_all(btnm, LV_BTNM_CTRL_TGL_ENABLE); + lv_btnm_set_one_toggle(btnm, true); + + lv_obj_t * table = lv_table_create(h, NULL); + lv_table_set_col_cnt(table, 3); + lv_table_set_row_cnt(table, 4); + lv_table_set_col_width(table, 0, LV_DPI / 3); + lv_table_set_col_width(table, 1, LV_DPI / 2); + lv_table_set_col_width(table, 2, LV_DPI / 2); + lv_table_set_cell_merge_right(table, 0, 0, true); + lv_table_set_cell_merge_right(table, 0, 1, true); + + lv_table_set_cell_value(table, 0, 0, "Table"); + lv_table_set_cell_align(table, 0, 0, LV_LABEL_ALIGN_CENTER); + + lv_table_set_cell_value(table, 1, 0, "1"); + lv_table_set_cell_value(table, 1, 1, "13"); + lv_table_set_cell_align(table, 1, 1, LV_LABEL_ALIGN_RIGHT); + lv_table_set_cell_value(table, 1, 2, "ms"); + + lv_table_set_cell_value(table, 2, 0, "2"); + lv_table_set_cell_value(table, 2, 1, "46"); + lv_table_set_cell_align(table, 2, 1, LV_LABEL_ALIGN_RIGHT); + lv_table_set_cell_value(table, 2, 2, "ms"); + + lv_table_set_cell_value(table, 3, 0, "3"); + lv_table_set_cell_value(table, 3, 1, "61"); + lv_table_set_cell_align(table, 3, 1, LV_LABEL_ALIGN_RIGHT); + lv_table_set_cell_value(table, 3, 2, "ms"); + + h = lv_cont_create(parent, h); + + lv_obj_t * sw_h = lv_cont_create(h, NULL); + lv_cont_set_style(sw_h, LV_CONT_STYLE_MAIN, &lv_style_transp); + lv_cont_set_fit2(sw_h, LV_FIT_NONE, LV_FIT_TIGHT); + lv_obj_set_width(sw_h, LV_HOR_RES / 4); + lv_cont_set_layout(sw_h, LV_LAYOUT_PRETTY); + + lv_obj_t * sw = lv_sw_create(sw_h, NULL); + lv_sw_set_anim_time(sw, 250); + + sw = lv_sw_create(sw_h, sw); + lv_sw_on(sw, LV_ANIM_OFF); + + + lv_obj_t * bar = lv_bar_create(h, NULL); + lv_bar_set_value(bar, 70, false); + + lv_obj_t * slider = lv_slider_create(h, NULL); + lv_bar_set_value(slider, 70, false); + + lv_obj_t * line = lv_line_create(h, NULL); + static lv_point_t line_p[2]; + line_p[0].x = 0; + line_p[0].y = 0; + line_p[1].x = lv_disp_get_hor_res(NULL) / 5; + line_p[1].y = 0; + + lv_line_set_points(line, line_p, 2); + lv_line_set_style(line, LV_LINE_STYLE_MAIN, th->style.line.decor); + + lv_obj_t * cb = lv_cb_create(h, NULL); + + cb = lv_cb_create(h, cb); + lv_btn_set_state(cb, LV_BTN_STATE_TGL_REL); + + lv_obj_t * ddlist = lv_ddlist_create(h, NULL); + lv_ddlist_set_fix_width(ddlist, lv_obj_get_width(ddlist) + LV_DPI / 2); /*Make space for the arrow*/ + lv_ddlist_set_draw_arrow(ddlist, true); + + h = lv_cont_create(parent, h); + + lv_obj_t * list = lv_list_create(h, NULL); + lv_obj_set_size(list, lv_disp_get_hor_res(NULL) / 4, lv_disp_get_ver_res(NULL) / 2); + lv_obj_t * list_btn; + list_btn = lv_list_add_btn(list, LV_SYMBOL_GPS, "GPS"); + lv_btn_set_toggle(list_btn, true); + + lv_list_add_btn(list, LV_SYMBOL_WIFI, "WiFi"); + lv_list_add_btn(list, LV_SYMBOL_GPS, "GPS"); + lv_list_add_btn(list, LV_SYMBOL_AUDIO, "Audio"); + lv_list_add_btn(list, LV_SYMBOL_VIDEO, "Video"); + lv_list_add_btn(list, LV_SYMBOL_CALL, "Call"); + lv_list_add_btn(list, LV_SYMBOL_BELL, "Bell"); + lv_list_add_btn(list, LV_SYMBOL_FILE, "File"); + lv_list_add_btn(list, LV_SYMBOL_EDIT, "Edit"); + lv_list_add_btn(list, LV_SYMBOL_CUT, "Cut"); + lv_list_add_btn(list, LV_SYMBOL_COPY, "Copy"); + + lv_obj_t * roller = lv_roller_create(h, NULL); + lv_roller_set_options(roller, "Monday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday", true); + lv_roller_set_selected(roller, 1, false); + lv_roller_set_visible_row_count(roller, 3); + + +} + +static void create_tab2(lv_obj_t * parent) +{ + lv_coord_t w = lv_page_get_scrl_width(parent); + + lv_obj_t * chart = lv_chart_create(parent, NULL); + lv_chart_set_type(chart, LV_CHART_TYPE_AREA); + lv_obj_set_size(chart, w / 3, lv_disp_get_ver_res(NULL) / 3); + lv_obj_set_pos(chart, LV_DPI / 10, LV_DPI / 10); + lv_chart_series_t * s1 = lv_chart_add_series(chart, LV_COLOR_RED); + lv_chart_set_next(chart, s1, 30); + lv_chart_set_next(chart, s1, 20); + lv_chart_set_next(chart, s1, 10); + lv_chart_set_next(chart, s1, 12); + lv_chart_set_next(chart, s1, 20); + lv_chart_set_next(chart, s1, 27); + lv_chart_set_next(chart, s1, 35); + lv_chart_set_next(chart, s1, 55); + lv_chart_set_next(chart, s1, 70); + lv_chart_set_next(chart, s1, 75); + + + lv_obj_t * gauge = lv_gauge_create(parent, NULL); + lv_gauge_set_value(gauge, 0, 40); + lv_obj_set_size(gauge, w / 4, w / 4); + lv_obj_align(gauge, chart, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4); + + + lv_obj_t * arc = lv_arc_create(parent, NULL); + lv_obj_align(arc, gauge, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_DPI / 8); + + lv_obj_t * ta = lv_ta_create(parent, NULL); + lv_obj_set_size(ta, w / 3, lv_disp_get_ver_res(NULL) / 4); + lv_obj_align(ta, NULL, LV_ALIGN_IN_TOP_RIGHT, -LV_DPI / 10, LV_DPI / 10); + lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK); + + lv_obj_t * kb = lv_kb_create(parent, NULL); + lv_obj_set_size(kb, 2 * w / 3, lv_disp_get_ver_res(NULL) / 3); + lv_obj_align(kb, ta, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, LV_DPI); + lv_kb_set_ta(kb, ta); + +#if LV_USE_ANIMATION + lv_obj_t * loader = lv_preload_create(parent, NULL); + lv_obj_align(loader, NULL, LV_ALIGN_CENTER, 0, - LV_DPI); +#endif +} + + +static void create_tab3(lv_obj_t * parent) +{ + /*Create a Window*/ + lv_obj_t * win = lv_win_create(parent, NULL); + lv_obj_t * win_btn = lv_win_add_btn(win, LV_SYMBOL_CLOSE); + lv_obj_set_event_cb(win_btn, lv_win_close_event_cb); + lv_win_add_btn(win, LV_SYMBOL_DOWN); + lv_obj_set_size(win, lv_disp_get_hor_res(NULL) / 2, lv_disp_get_ver_res(NULL) / 2); + lv_obj_set_pos(win, LV_DPI / 20, LV_DPI / 20); + lv_obj_set_top(win, true); + + + /*Create a Label in the Window*/ + lv_obj_t * label = lv_label_create(win, NULL); + lv_label_set_text(label, "Label in the window"); + + /*Create a Line meter in the Window*/ + lv_obj_t * lmeter = lv_lmeter_create(win, NULL); + lv_obj_align(lmeter, label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 2); + lv_lmeter_set_value(lmeter, 70); + + /*Create a 2 LEDs in the Window*/ + lv_obj_t * led1 = lv_led_create(win, NULL); + lv_obj_align(led1, lmeter, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0); + lv_led_on(led1); + + lv_obj_t * led2 = lv_led_create(win, NULL); + lv_obj_align(led2, led1, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0); + lv_led_off(led2); + + /*Create a Page*/ + lv_obj_t * page = lv_page_create(parent, NULL); + lv_obj_set_size(page, lv_disp_get_hor_res(NULL) / 3, lv_disp_get_ver_res(NULL) / 2); + lv_obj_set_top(page, true); + lv_obj_align(page, win, LV_ALIGN_IN_TOP_RIGHT, LV_DPI, LV_DPI); + + label = lv_label_create(page, NULL); + lv_label_set_text(label, "Lorem ipsum dolor sit amet, repudiare voluptatibus pri cu.\n" + "Ei mundi pertinax posidonium eum, cum tempor maiorum at,\n" + "mea fuisset assentior ad. Usu cu suas civibus iudicabit.\n" + "Eum eu congue tempor facilisi. Tale hinc unum te vim.\n" + "Te cum populo animal eruditi, labitur inciderint at nec.\n\n" + "Eius corpora et quo. Everti voluptaria instructior est id,\n" + "vel in falli primis. Mea ei porro essent admodum,\n" + "his ei malis quodsi, te quis aeterno his.\n" + "Qui tritani recusabo reprehendunt ne,\n" + "per duis explicari at. Simul mediocritatem mei et."); + + /*Create a Calendar*/ + lv_obj_t * cal = lv_calendar_create(parent, NULL); + lv_obj_set_size(cal, 5 * LV_DPI / 2, 5 * LV_DPI / 2); + lv_obj_align(cal, page, LV_ALIGN_OUT_RIGHT_TOP, -LV_DPI / 2, LV_DPI / 3); + lv_obj_set_top(cal, true); + + static lv_calendar_date_t highlighted_days[2]; + highlighted_days[0].day = 5; + highlighted_days[0].month = 5; + highlighted_days[0].year = 2018; + + highlighted_days[1].day = 8; + highlighted_days[1].month = 5; + highlighted_days[1].year = 2018; + + lv_calendar_set_highlighted_dates(cal, highlighted_days, 2); + lv_calendar_set_today_date(cal, &highlighted_days[0]); + lv_calendar_set_showed_date(cal, &highlighted_days[0]); + + /*Create a Message box*/ + static const char * mbox_btn_map[] = {" ", "Got it!", " ", ""}; + lv_obj_t * mbox = lv_mbox_create(parent, NULL); + lv_mbox_set_text(mbox, "Click on the window or the page to bring it to the foreground"); + lv_mbox_add_btns(mbox, mbox_btn_map); + lv_btnm_set_btn_ctrl(lv_mbox_get_btnm(mbox), 0, LV_BTNM_CTRL_HIDDEN); + lv_btnm_set_btn_width(lv_mbox_get_btnm(mbox), 1, 7); + lv_btnm_set_btn_ctrl(lv_mbox_get_btnm(mbox), 2, LV_BTNM_CTRL_HIDDEN); + lv_obj_set_top(mbox, true); + + +} diff --git a/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/2_lv_button_test/2_lv_button_test.ino b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/2_lv_button_test/2_lv_button_test.ino new file mode 100644 index 0000000..d100f3e --- /dev/null +++ b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/2_lv_button_test/2_lv_button_test.ino @@ -0,0 +1,159 @@ +#include +#include +#include + +#define LVGL_TICK_PERIOD 60 + +Ticker tick; /* timer for interrupt handler */ +TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ +static lv_disp_buf_t disp_buf; +static lv_color_t buf[LV_HOR_RES_MAX * 10]; + +lv_obj_t * slider_label; +int screenWidth = 480; +int screenHeight = 320; + +/* Display flushing */ +void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) +{ + uint16_t c; + + tft.startWrite(); /* Start new TFT transaction */ + tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */ + for (int y = area->y1; y <= area->y2; y++) { + for (int x = area->x1; x <= area->x2; x++) { + c = color_p->full; + tft.writeColor(c, 1); + color_p++; + } + } + tft.endWrite(); /* terminate TFT transaction */ + lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ +} + +bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) +{ + uint16_t touchX, touchY; + + bool touched = tft.getTouch(&touchX, &touchY, 600); + + if(!touched) + { + return false; + } + + if(touchX>screenWidth || touchY > screenHeight) + { + Serial.println("Y or y outside of expected parameters.."); + Serial.print("y:"); + Serial.print(touchX); + Serial.print(" x:"); + Serial.print(touchY); + } + else + { + + data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + + /*Save the state and save the pressed coordinate*/ + //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 = touchX; + data->point.y = touchY; + + Serial.print("Data x"); + Serial.println(touchX); + + Serial.print("Data y"); + Serial.println(touchY); + + } + + return false; /*Return `false` because we are not buffering and no more data to read*/ +} + +/* Interrupt driven periodic handler */ +static void lv_tick_handler(void) +{ + + lv_tick_inc(LVGL_TICK_PERIOD); +} + + +void setup() { + + Serial.begin(115200); /* prepare for possible serial debug */ + + lv_init(); + + tft.begin(); /* TFT init */ + tft.setRotation(3); + + //uint16_t calData[5] = { 275, 3620, 264, 3532, 1 }; + uint16_t calData[5] = {299, 3588, 348, 3474, 1}; + tft.setTouch(calData); + + lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); + + /*Initialize the display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = screenWidth; + disp_drv.ver_res = screenHeight; + disp_drv.flush_cb = my_disp_flush; + disp_drv.buffer = &disp_buf; + lv_disp_drv_register(&disp_drv); + + lv_indev_drv_t indev_drv; + 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*/ + + + /*Initialize the graphics library's tick*/ + tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler); + + lv_ex_btn_1(); + +} + + +void loop() { + + lv_task_handler(); /* let the GUI do its work */ + delay(5); +} + +static void event_handler(lv_obj_t * obj, lv_event_t event) +{ + if(event == LV_EVENT_CLICKED) { + printf("Clicked\n"); + } + else if(event == LV_EVENT_VALUE_CHANGED) { + printf("Toggled\n"); + } +} + +void lv_ex_btn_1(void) +{ + lv_obj_t * label; + + lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL); + lv_obj_set_event_cb(btn1, event_handler); + lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, -40); + + label = lv_label_create(btn1, NULL); + lv_label_set_text(label, "Button"); + + lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), NULL); + lv_obj_set_event_cb(btn2, event_handler); + lv_obj_align(btn2, NULL, LV_ALIGN_CENTER, 0, 40); + lv_btn_set_toggle(btn2, true); + lv_btn_toggle(btn2); + lv_btn_set_fit2(btn2, LV_FIT_NONE, LV_FIT_TIGHT); + + label = lv_label_create(btn2, NULL); + lv_label_set_text(label, "Toggled"); +} diff --git a/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/3_simple_note_step1/3_simple_note_step1.ino b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/3_simple_note_step1/3_simple_note_step1.ino new file mode 100644 index 0000000..525c292 --- /dev/null +++ b/ESP32_LITTLEVGL_ARDUINO_IDE/Part1/3_simple_note_step1/3_simple_note_step1.ino @@ -0,0 +1,170 @@ +#include +#include +#include + +#define LVGL_TICK_PERIOD 60 + +Ticker tick; /* timer for interrupt handler */ +TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ +static lv_disp_buf_t disp_buf; +static lv_color_t buf[LV_HOR_RES_MAX * 10]; + +lv_obj_t * slider_label; +int screenWidth = 480; +int screenHeight = 320; + +/* Display flushing */ +void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) +{ + uint16_t c; + + tft.startWrite(); /* Start new TFT transaction */ + tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */ + for (int y = area->y1; y <= area->y2; y++) { + for (int x = area->x1; x <= area->x2; x++) { + c = color_p->full; + tft.writeColor(c, 1); + color_p++; + } + } + tft.endWrite(); /* terminate TFT transaction */ + lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ +} + +bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) +{ + uint16_t touchX, touchY; + + bool touched = tft.getTouch(&touchX, &touchY, 600); + + if(!touched) + { + return false; + } + + if(touchX>screenWidth || touchY > screenHeight) + { + Serial.println("Y or y outside of expected parameters.."); + Serial.print("y:"); + Serial.print(touchX); + Serial.print(" x:"); + Serial.print(touchY); + } + else + { + + data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + + /*Save the state and save the pressed coordinate*/ + //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 = touchX; + data->point.y = touchY; + + Serial.print("Data x"); + Serial.println(touchX); + + Serial.print("Data y"); + Serial.println(touchY); + + } + + return false; /*Return `false` because we are not buffering and no more data to read*/ +} + +/* Interrupt driven periodic handler */ +static void lv_tick_handler(void) +{ + + lv_tick_inc(LVGL_TICK_PERIOD); +} + + +void setup() { + + Serial.begin(115200); /* prepare for possible serial debug */ + + lv_init(); + + tft.begin(); /* TFT init */ + tft.setRotation(3); + + //uint16_t calData[5] = { 275, 3620, 264, 3532, 1 }; + uint16_t calData[5] = {299, 3588, 348, 3474, 1}; + tft.setTouch(calData); + + lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); + + /*Initialize the display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = screenWidth; + disp_drv.ver_res = screenHeight; + disp_drv.flush_cb = my_disp_flush; + disp_drv.buffer = &disp_buf; + lv_disp_drv_register(&disp_drv); + + lv_indev_drv_t indev_drv; + 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*/ + + + /*Initialize the graphics library's tick*/ + tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler); + + lv_main(); +} + +void loop() { + + lv_task_handler(); /* let the GUI do its work */ + delay(5); +} + +static lv_obj_t *kb; + +static void lv_main(){ + lv_obj_t * scr = lv_cont_create(NULL, NULL); + lv_disp_load_scr(scr); + + lv_obj_t * tv = lv_tabview_create(scr, NULL); + lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL)); + lv_obj_t * tab1 = lv_tabview_add_tab(tv, "LIST TAB"); + lv_obj_t * tab2 = lv_tabview_add_tab(tv, "WRITE TAB"); + + create_tab1(tab1); + create_tab2(tab2); +} + +static void create_tab1(lv_obj_t * parent){ + //List Tab + lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY); +} + +static void create_tab2(lv_obj_t * parent){ + //Write Tab + lv_obj_t * ta = lv_ta_create(parent, NULL); + lv_obj_set_size(ta, lv_obj_get_width(parent) - 10, lv_obj_get_height(parent) / 2); + lv_ta_set_cursor_type(ta, LV_CURSOR_BLOCK); + lv_ta_set_text(ta, "hello!"); + + /*Create a keyboard and apply the styles*/ + kb = lv_kb_create(parent, NULL); + lv_obj_set_size(kb, lv_obj_get_width(parent) -10, lv_obj_get_height(parent) / 2 - 20); + lv_obj_set_event_cb(kb, keyboard_event_cb); + /*Assign the text area to the keyboard*/ + lv_kb_set_ta(kb, ta); + +} + +static void keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event){ + lv_kb_def_event_cb(kb, event); + if(event == LV_EVENT_APPLY){ + printf("LV_EVENT_APPLY\n"); + }else if(event == LV_EVENT_CANCEL){ + printf("LV_EVENT_CANCEL\n"); + } +}