diff --git a/dependencies.lock b/dependencies.lock index b09cb0b..8130993 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -11,11 +11,11 @@ dependencies: type: idf version: 5.0.1 lvgl/lvgl: - component_hash: 2567762b19953712ee38789ad8f8de57ad1f6e39283adefbbfc7184ffe662831 + component_hash: 0f2006e7b800eee17b73ed4f92ffbaa76d61c02ba4779ec9efbcd5f453bb0102 source: service_url: https://api.components.espressif.com/ type: service - version: 8.2.0 -manifest_hash: bef1e4573234ace0f846d8355b65d9ec82a4aeada7c2fa638efbec574f134e54 + version: 8.3.6~1 +manifest_hash: 9a88337b9db92c26041847f5fd4efc58df1dcf0e9c6b8758da96aaac2e63c2a2 target: esp32c3 version: 1.0.0 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 664b5c7..04d7f5c 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -20,5 +20,6 @@ idf_component_register( "led_strip_encoder/led_strip_encoder.c" "gui.c" "lvgl_demo_ui.c" + "app_icon_8.c" INCLUDE_DIRS "." ) \ No newline at end of file diff --git a/main/app_icon_8.c b/main/app_icon_8.c new file mode 100644 index 0000000..b9efeb2 --- /dev/null +++ b/main/app_icon_8.c @@ -0,0 +1,157 @@ +/******************************************************************************* + * Size: 8 px + * Bpp: 1 + * Opts: + ******************************************************************************/ +#pragma once + +#include "lvgl.h" + +#ifndef APP_ICON_8 +#define APP_ICON_8 1 +#endif + +#if APP_ICON_8 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+E1CB "" */ + 0x38, 0x31, 0x88, 0xfa, 0x49, 0x54, 0x44, 0x10, 0xf8, + + /* U+E1CC "" */ + 0x80, 0x1f, 0xa, 0x22, 0x6b, 0xd4, 0x44, 0xd0, 0xc8, 0x1, + + /* U+E29E "" */ + 0xe, 0x4, 0xa8, 0x32, 0x18, 0xe, 0xd, 0x8c, 0x7c, + + /* U+F1EB "" */ + 0x1e, 0x18, 0x68, 0x4, 0x78, 0x21, 0x0, 0x0, 0xc0, 0x0, + + /* U+F6AA "" */ + 0xc0, + + /* U+F6AB "" */ + 0x79, 0x8, 0x1, 0x80}; + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, + .adv_w = 0, + .box_w = 0, + .box_h = 0, + .ofs_x = 0, + .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, + .adv_w = 160, + .box_w = 10, + .box_h = 7, + .ofs_x = 0, + .ofs_y = 0}, + {.bitmap_index = 9, + .adv_w = 160, + .box_w = 10, + .box_h = 8, + .ofs_x = 0, + .ofs_y = -1}, + {.bitmap_index = 19, + .adv_w = 128, + .box_w = 9, + .box_h = 8, + .ofs_x = 0, + .ofs_y = -1}, + {.bitmap_index = 28, + .adv_w = 160, + .box_w = 10, + .box_h = 8, + .ofs_x = 0, + .ofs_y = -1}, + {.bitmap_index = 38, + .adv_w = 32, + .box_w = 2, + .box_h = 2, + .ofs_x = 4, + .ofs_y = -1}, + {.bitmap_index = 39, + .adv_w = 112, + .box_w = 7, + .box_h = 4, + .ofs_x = 2, + .ofs_y = 0}}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_0[] = {0x0, 0x1, 0xd3, + 0x1020, 0x14df, 0x14e0}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = { + {.range_start = 57803, + .range_length = 5345, + .glyph_id_start = 1, + .unicode_list = unicode_list_0, + .glyph_id_ofs_list = NULL, + .list_length = 6, + .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY}}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LV_VERSION_CHECK(8, 0, 0) +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 1, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0, +#if LV_VERSION_CHECK(8, 0, 0) + .cache = &cache +#endif +}; + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LV_VERSION_CHECK(8, 0, 0) +const lv_font_t app_icon_8 = { +#else +lv_font_t app_icon_8 = { +#endif + .get_glyph_dsc = + lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = + lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 8, /*The maximum line height required by the font*/ + .base_line = 1, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 0, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by + `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if APP_ICON_8*/ diff --git a/main/gui.c b/main/gui.c index 8b8c5ea..f7194fe 100644 --- a/main/gui.c +++ b/main/gui.c @@ -6,6 +6,7 @@ #include +#include "app_icon_8.c" #include "ch1116.c" #include "driver/i2c.h" #include "esp_err.h" @@ -19,10 +20,6 @@ static const char *GUI_TAG = "LVGL_GUI"; #define I2C_HOST 0 -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// Please update the following configuration according to your -/// LCD spec ////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define EXAMPLE_LCD_PIXEL_CLOCK_HZ (400 * 1000) #define EXAMPLE_LCD_H_RES CH1116_WIDTH @@ -30,6 +27,21 @@ static const char *GUI_TAG = "LVGL_GUI"; #define EXAMPLE_LVGL_TICK_PERIOD_MS 2 +// EF 9A AA +#define APP_WIFI_WEAK_SYMBOL "\xEF\x9A\xAA" +// EF 9A AB +#define APP_WIFI_FAIR_SYMBOL "\xEF\x9A\xAB" +// EF 87 AB +#define APP_WIFI_GOOD_SYMBOL "\xEF\x87\xAB" + +// EE 87 8C +#define APP_CONNECTED_SYMBOL "\xEE\x87\x8C" +// EE 87 8B +#define APP_DISCONNECTED_SYMBOL "\xEE\x87\x8B" + +// EE 8A 9E +#define APP_TIMER_SYMBOL "\xEE\x8A\x9E" + extern void example_lvgl_demo_ui(lv_disp_t *disp); static void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, @@ -56,6 +68,15 @@ static void example_lvgl_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, } } +static lv_obj_t *wifi_label; +static lv_anim_t wifi_animate; + +static lv_obj_t *timer_label; +static lv_anim_t timer_animate; + +static lv_obj_t *desktop_label; +static lv_anim_t desktop_animate; + static void example_lvgl_rounder(lv_disp_drv_t *disp_drv, lv_area_t *area) { area->y1 = area->y1 & (~0x7); area->y2 = area->y2 | 0x7; @@ -70,6 +91,86 @@ static void set_value(void *bar, int32_t v) { lv_bar_set_value(bar, v, LV_ANIM_OFF); } +static void set_visible(void *obj, int32_t v) { + if (v) { + lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN); + } +} + +static void set_obj_blink_animate(lv_obj_t *obj, lv_anim_t *a) { + lv_anim_init(a); + lv_anim_set_exec_cb(a, set_visible); + lv_anim_set_time(a, 100); + lv_anim_set_playback_time(a, 100); + lv_anim_set_playback_delay(a, 200); + lv_anim_set_repeat_delay(a, 200); + lv_anim_set_values(a, 0, 1); + lv_anim_set_var(a, obj); + lv_anim_set_repeat_count(a, LV_ANIM_REPEAT_INFINITE); + lv_anim_start(a); +} + +static void change_wifi_icon(void *obj, int32_t v) { + switch (v) { + case 0: + lv_label_set_text(obj, APP_WIFI_WEAK_SYMBOL); + break; + case 1: + lv_label_set_text(obj, APP_WIFI_FAIR_SYMBOL); + break; + case 2: + lv_label_set_text(obj, APP_WIFI_GOOD_SYMBOL); + break; + default: + ESP_LOGW(GUI_TAG, "Unknown wifi strength: %ld", v); + break; + } +} + +static void gui_set_wifi_connecting() { + lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); + + lv_anim_init(&wifi_animate); + lv_anim_set_exec_cb(&wifi_animate, change_wifi_icon); + lv_anim_set_time(&wifi_animate, 300); + lv_anim_set_repeat_delay(&wifi_animate, 300); + lv_anim_set_values(&wifi_animate, 0, 2); + lv_anim_set_var(&wifi_animate, wifi_label); + lv_anim_set_repeat_count(&wifi_animate, LV_ANIM_REPEAT_INFINITE); + lv_anim_start(&wifi_animate); +} + +static void gui_set_wifi_connected() { + lv_anim_del(wifi_label, NULL); + + lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); + lv_label_set_text(wifi_label, APP_WIFI_GOOD_SYMBOL); +} + +static void gui_set_wifi_disconnected() { + lv_anim_del(&wifi_label, NULL); + lv_obj_clear_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); + lv_label_set_text(wifi_label, APP_WIFI_WEAK_SYMBOL); +} + +static void gui_set_server_connecting() { + set_obj_blink_animate(desktop_label, &desktop_animate); +} + +static void gui_set_server_connected() { + lv_anim_del(&desktop_label, NULL); + lv_obj_clear_flag(desktop_label, LV_OBJ_FLAG_HIDDEN); + lv_label_set_text(desktop_label, APP_CONNECTED_SYMBOL); +} + +static void gui_set_server_disconnected() { + lv_anim_del(&desktop_label, NULL); + lv_obj_clear_flag(desktop_label, LV_OBJ_FLAG_HIDDEN); + lv_label_set_text(desktop_label, APP_DISCONNECTED_SYMBOL); +} + void lv_example_bar_6(lv_obj_t *src) { static lv_style_t style_bar; lv_style_init(&style_bar); @@ -104,6 +205,38 @@ void lv_example_bar_6(lv_obj_t *src) { lv_anim_start(&a); } +void gui_status_bar_create(lv_obj_t *scr) { + // wifi icon + wifi_label = lv_label_create(scr); + lv_label_set_long_mode(wifi_label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_label_set_text(wifi_label, APP_WIFI_GOOD_SYMBOL); + lv_obj_set_width(wifi_label, 10); + lv_obj_align(wifi_label, LV_ALIGN_OUT_TOP_LEFT, 0, 0); + lv_obj_set_style_text_color(wifi_label, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_text_font(wifi_label, &app_icon_8, LV_PART_MAIN); + lv_obj_add_flag(wifi_label, LV_OBJ_FLAG_HIDDEN); + + // timer icon + timer_label = lv_label_create(scr); + lv_label_set_long_mode(timer_label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_label_set_text(timer_label, APP_TIMER_SYMBOL); + lv_obj_set_width(timer_label, 10); + lv_obj_align(timer_label, LV_ALIGN_OUT_TOP_LEFT, 12, 0); + lv_obj_set_style_text_color(timer_label, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_text_font(timer_label, &app_icon_8, LV_PART_MAIN); + lv_obj_add_flag(timer_label, LV_OBJ_FLAG_HIDDEN); + + // desktop icon + desktop_label = lv_label_create(scr); + lv_label_set_long_mode(desktop_label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_label_set_text(desktop_label, APP_CONNECTED_SYMBOL); + lv_obj_set_width(desktop_label, 10); + lv_obj_align(desktop_label, LV_ALIGN_OUT_TOP_LEFT, 24, 0); + lv_obj_set_style_text_color(desktop_label, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_text_font(desktop_label, &app_icon_8, LV_PART_MAIN); + lv_obj_add_flag(desktop_label, LV_OBJ_FLAG_HIDDEN); +} + void example_lvgl_demo_ui(lv_disp_t *disp) { lv_obj_t *scr = lv_disp_get_scr_act(disp); @@ -113,9 +246,11 @@ void example_lvgl_demo_ui(lv_disp_t *disp) { */ lv_label_set_text(label, "Hello Espressif, Hello LVGL."); lv_obj_set_width(label, 120); - lv_obj_center(label); + lv_obj_align(label, LV_ALIGN_BOTTOM_RIGHT, 0, 0); lv_example_bar_6(scr); + + gui_status_bar_create(scr); } static void gui_tick(void *pvParameters) { @@ -128,6 +263,7 @@ static void gui_tick(void *pvParameters) { lv_timer_handler(); } } + void gui_main(void) { static lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s) diff --git a/main/idf_component.yml b/main/idf_component.yml index 64f0cb2..8e84cca 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -1,6 +1,6 @@ ## IDF Component Manager Manifest File dependencies: - lvgl/lvgl: "~8.2.0" + lvgl/lvgl: "^8.3.6~1" espressif/mdns: "^1.0.9" ## Required IDF version idf: diff --git a/main/main.c b/main/main.c index d12c9dd..b45a2ed 100644 --- a/main/main.c +++ b/main/main.c @@ -23,15 +23,19 @@ void app_main(void) { app_nvs_init(); light_init_strip(); - gpio_install_isr_service(0); + // gpio_install_isr_service(0); init_i2c(); i2c_check_slaves(); ch1116_main(); gui_main(); + + gui_set_wifi_connecting(); + gui_set_server_connecting(); + // display_print8_str(0, 0, "Ambient Light"); - ci_03t_init(); + // ci_03t_init(); // apds_9960_init(); // apds_9960_auto_fetch(); // auto_fetch_temperature(); @@ -39,14 +43,17 @@ void app_main(void) { // ui_input_init(); // xTaskCreate(mqtt_publish_ui_input, "mqtt_publish_ui_input", 2048, NULL, 10, // NULL); - vTaskDelay(pdMS_TO_TICKS(10)); + // vTaskDelay(pdMS_TO_TICKS(10)); light_play(light_mode_connection_wifi); if (connect_wifi()) { + gui_set_wifi_connected(); light_play(light_mode_idle); + } else { + gui_set_wifi_disconnected(); } udp_server_init(); - service_discovery_init(); - vTaskDelay(pdMS_TO_TICKS(1000)); + // service_discovery_init(); + // vTaskDelay(pdMS_TO_TICKS(1000)); // mqtt_app_start(); // if (waiting_for_mqtt_connected()) { // light_play(light_mode_mqtt_connected); diff --git a/main/wifi.c b/main/wifi.c index eae3a83..94f1a80 100644 --- a/main/wifi.c +++ b/main/wifi.c @@ -151,14 +151,7 @@ bool wifi_init_sta(void) { } bool connect_wifi(void) { - // Initialize NVS - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || - ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); + //! Should init NVS before wifi init ESP_LOGI(WIFI_TAG, "ESP_WIFI_MODE_STA"); return wifi_init_sta();