├── .gitignore ├── .vscode └── extensions.json ├── README.MD ├── include └── README ├── lib └── README ├── main.cpp ├── pio.zip ├── platformio.ini ├── src ├── UIManager.cpp ├── UIManager.h ├── WIFIManager.cpp ├── WIFIManager.h ├── iconfont_symbol.c ├── main.cpp └── setup.cpp └── test └── README /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/* 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # ESP32C3+0.96寸tft屏幕电脑状态监控项目 2 | 3 | 使用VScode+platformIO+lvgl+arduino开发,使用c++编写 4 | 5 | 上位机使用Python程序和[LibreHardwareMonitor](https://github.com/LibreHardwareMonitor/LibreHardwareMonitor)编写 6 | 7 | 通过WIFI传输数据 8 | 9 | 上位机程序在这个库 [esp32c3_observer](https://github.com/imshixin/esp32c3_observer) 10 | 11 | **注意:上位机程序需要使用管理员权限执行,否则获取不到cpu数据** 12 | 13 | 使用时自行更改`main.cpp`中的`ssid`和`passwd`以及`main.py`的`ip` 14 | 15 | # 配置文件 16 | 如果你不会自己配置lvgl和tft_eSpi,可以使用上传的配置文件 17 | 18 | 将`pio.zip`中的`.pio\libdeps\esp32-c3-devkitm-1\lvgl\lv_conf.h`和`.pio\libdeps\esp32-c3-devkitm-1\TFT_eSPI\User_Setup_Select.h` `.pio\libdeps\esp32-c3-devkitm-1\TFT_eSPI\User_Setup.h`复制到自己项目的对应目录下 19 | 20 | > 如果你的屏幕不是合宙的9.9包邮0.96寸小屏幕,你可能需要对tft_eSPI做一点配置,具体建议百度 21 | -------------------------------------------------------------------------------- /include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define LED_PIN1 12 9 | #define LED_PIN2 13 10 | 11 | typedef struct Data{ 12 | float cpu_load; 13 | float cpu_temp; 14 | float gpu_load; 15 | float gpu_temp; 16 | } Data; 17 | 18 | /*Change to your screen resolution*/ 19 | static const uint16_t screenWidth = 80; 20 | static const uint16_t screenHeight = 160; 21 | 22 | static lv_disp_draw_buf_t draw_buf; 23 | static lv_color_t buf[screenWidth * 10]; 24 | 25 | TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */ 26 | // WiFiServer server(port); 27 | 28 | const char* ssid="nova 5 pro"; 29 | const char* passwd="81297311"; 30 | const int port = 34567; 31 | bool wifi_conn=false; 32 | 33 | /* Display flushing */ 34 | void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) 35 | { 36 | uint32_t w = (area->x2 - area->x1 + 1); 37 | uint32_t h = (area->y2 - area->y1 + 1); 38 | 39 | tft.startWrite(); 40 | tft.setAddrWindow(area->x1, area->y1, w, h); 41 | tft.pushColors((uint16_t *)&color_p->full, w * h, true); 42 | tft.endWrite(); 43 | 44 | lv_disp_flush_ready(disp); 45 | } 46 | 47 | void inline lvgl_init(){ 48 | String LVGL_Arduino = "Hello Arduino! "; 49 | LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch(); 50 | 51 | Serial.println(LVGL_Arduino); 52 | 53 | lv_init(); 54 | lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * 10); 55 | 56 | /*Initialize the display*/ 57 | static lv_disp_drv_t disp_drv; 58 | lv_disp_drv_init(&disp_drv); 59 | /*Change the following line to your display resolution*/ 60 | disp_drv.hor_res = screenWidth; 61 | disp_drv.ver_res = screenHeight; 62 | disp_drv.flush_cb = my_disp_flush; 63 | disp_drv.draw_buf = &draw_buf; 64 | lv_disp_drv_register(&disp_drv); 65 | } 66 | 67 | /* 初始化用户界面 */ 68 | void ui_show_setup(){ 69 | 70 | 71 | } 72 | 73 | void change_led_timer(lv_timer_t* timer){ 74 | lv_obj_t* led = (lv_obj_t*)(timer->user_data); 75 | Serial.printf("wifi_conn::%b\n",wifi_conn); 76 | if(wifi_conn){ 77 | lv_led_on(led); 78 | }else{ 79 | lv_led_toggle(led); 80 | } 81 | } 82 | void ui_network_setup(){ 83 | Serial.println("init ui_network"); 84 | lv_obj_t* txt = lv_label_create(lv_scr_act()); 85 | lv_label_set_text(txt,"connecting wifi"); 86 | lv_obj_align(txt,LV_ALIGN_CENTER,0,0); 87 | lv_obj_t* led = lv_led_create(lv_scr_act()); 88 | lv_obj_align_to(led,txt,LV_ALIGN_BOTTOM_MID,0,0); 89 | // lv_timer_create(change_led_timer,300,led); 90 | } 91 | 92 | 93 | void connect_wifi(){ 94 | ui_network_setup(); 95 | Serial.println("start connect wifi"); 96 | WiFi.disconnect(); 97 | delay(500); 98 | WiFi.begin(ssid,passwd); 99 | for(int i=0;WiFi.status()!=WL_CONNECTED;i++){ 100 | Serial.print('.'); 101 | delay(500); 102 | WiFi.begin(ssid,passwd); 103 | } 104 | wifi_conn=true; 105 | } 106 | void setup() 107 | { 108 | Serial.begin(115200); /* prepare for possible serial debug */ 109 | pinMode(LED_PIN1, OUTPUT); 110 | pinMode(LED_PIN2, OUTPUT); 111 | digitalWrite(LED_PIN1, HIGH); 112 | digitalWrite(LED_PIN2, HIGH); 113 | 114 | 115 | 116 | lvgl_init(); 117 | tft.init(); /* TFT init */ 118 | tft.setRotation(1); /* Landscape orientation, flipped */ 119 | tft.fillScreen(TFT_BLACK); 120 | Serial.println("init tft success"); 121 | /*-------------------------- main code----------------- */ 122 | connect_wifi(); 123 | 124 | ui_show_setup(); 125 | 126 | Serial.println("Setup done"); 127 | } 128 | 129 | void loop() 130 | { 131 | lv_timer_handler(); /* let the GUI do its work */ 132 | delay(5); 133 | } 134 | -------------------------------------------------------------------------------- /pio.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imshixin/esp32c3_lvgl_observer/564775470eeb99c281a8837845ca4d1fed841dca/pio.zip -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32-c3-devkitm-1] 12 | platform = espressif32 13 | board = esp32-c3-devkitm-1 14 | framework = arduino 15 | monitor_speed = 115200 16 | board_build.flash_mode = dio 17 | lib_deps = 18 | bodmer/TFT_eSPI@^2.4.71 19 | lvgl/lvgl@^8.2.0 20 | -------------------------------------------------------------------------------- /src/UIManager.cpp: -------------------------------------------------------------------------------- 1 | #include "UIManager.h" 2 | #include "WIFIManager.h" 3 | #include 4 | #include 5 | 6 | #define MAIN_DATA_OFFSET_X 12 7 | #define MAIN_DATA_OFFSET_Y 18 8 | #define MY_SYMBOL_TEMP "\xEE\x9B\xAE" 9 | #define MY_SYMBOL_LOAD "\xEE\x9C\xBB" 10 | #define TEMP_COLOR lv_color_hex(0xa30cf9) 11 | #define LOAD_COLOR lv_color_hex(0x21a3ef) 12 | LV_FONT_DECLARE(iconfont_symbol); 13 | 14 | extern WIFIManager wm; 15 | extern int port; 16 | // extern data_t datas; 17 | 18 | UIManager::UIManager(){ 19 | Serial.println("start init screen"); 20 | init_data_show(); 21 | init_ip_show(); 22 | init_waiting_for_connect(); 23 | Serial.println("screen init success"); 24 | } 25 | 26 | void UIManager::load_scr(screen_type st){ 27 | switch (st) 28 | { 29 | case UM_SCR_IP_SHOW: 30 | // if(!wm.checkConn()){ 31 | // load_scr(UM_SCR_WAIT_FOR_CONNECT); 32 | // break; 33 | // } 34 | lv_label_set_text(label_ip_show,("Connect It:\n" + WiFi.localIP().toString() + ":"+String(port)).c_str()); 35 | lv_scr_load(scr_ip_show); 36 | break; 37 | case UM_SCR_DATA_SHOW: 38 | lv_scr_load(scr_data_show); 39 | break; 40 | case UM_SCR_WAIT_FOR_CONNECT: 41 | default: 42 | lv_scr_load(scr_wait_for_connect); 43 | break; 44 | } 45 | } 46 | 47 | void UIManager::init_ip_show() 48 | { 49 | scr_ip_show = lv_obj_create(NULL); 50 | label_ip_show = lv_label_create(scr_ip_show); 51 | // lv_label_set_text(label_ip_show, ("Connect It:\n" + WiFi.localIP().toString() + ":34567").c_str()); 52 | lv_obj_center(label_ip_show); 53 | } 54 | 55 | void UIManager::init_data_show(){ 56 | static lv_style_t style; 57 | lv_style_init(&style); 58 | scr_data_show = lv_obj_create(NULL); 59 | lv_obj_t *left_con = lv_obj_create(scr_data_show); 60 | lv_obj_t *right_con = lv_obj_create(scr_data_show); 61 | lv_obj_set_pos(left_con, 0, 0); 62 | lv_obj_set_pos(right_con, lv_pct(50), 0); 63 | lv_obj_set_size(left_con, lv_pct(50), lv_pct(100)); 64 | lv_obj_set_size(right_con, lv_pct(50), lv_pct(100)); 65 | lv_style_set_border_width(&style, 1); 66 | lv_style_set_radius(&style, 0); 67 | lv_style_set_pad_all(&style, 0 68 | ); 69 | lv_obj_set_scrollbar_mode(left_con, LV_SCROLLBAR_MODE_OFF); 70 | lv_obj_add_style(left_con, &style, LV_PART_MAIN); 71 | lv_obj_add_style(right_con, &style, LV_PART_MAIN); 72 | 73 | lv_obj_t *left_load_arc = lv_arc_create(left_con); 74 | lv_obj_t *left_temp_arc = lv_arc_create(left_con); 75 | lv_obj_t *right_load_arc = lv_arc_create(right_con); 76 | lv_obj_t *right_temp_arc = lv_arc_create(right_con); 77 | lv_obj_set_style_arc_color(left_load_arc,LOAD_COLOR,LV_PART_INDICATOR); 78 | lv_obj_set_style_arc_color(right_load_arc,LOAD_COLOR,LV_PART_INDICATOR); 79 | lv_obj_set_style_arc_color(left_temp_arc,TEMP_COLOR,LV_PART_INDICATOR); 80 | lv_obj_set_style_arc_color(right_temp_arc,TEMP_COLOR,LV_PART_INDICATOR); 81 | lv_arc_set_style(left_load_arc, 5, 90, 0, 180, 1, 0, 0, LV_ARC_MODE_NORMAL); 82 | lv_arc_set_style(left_temp_arc, 8, 90, 0, 180, 0.8, 0, 0, LV_ARC_MODE_NORMAL); 83 | lv_arc_set_style(right_load_arc, 5, 270, 0, 180, 1, 0, 0, LV_ARC_MODE_REVERSE); 84 | lv_arc_set_style(right_temp_arc, 8, 270, 0, 180, 0.8, 0, 0, LV_ARC_MODE_REVERSE); 85 | arcs.llarc = left_load_arc; 86 | arcs.ltarc = left_temp_arc; 87 | arcs.rlarc = right_load_arc; 88 | arcs.rtarc = right_temp_arc; 89 | 90 | lv_obj_t* cpu_label = lv_label_create(left_con); 91 | lv_obj_t* gpu_label = lv_label_create(right_con); 92 | lv_label_set_text(cpu_label,"CPU"); 93 | lv_label_set_text(gpu_label,"GPU"); 94 | lv_obj_set_style_text_font(cpu_label,&lv_font_montserrat_16,LV_PART_MAIN); 95 | lv_obj_set_style_text_font(gpu_label,&lv_font_montserrat_16,LV_PART_MAIN); 96 | lv_obj_align(cpu_label,LV_ALIGN_RIGHT_MID,0,-14); 97 | lv_obj_align(gpu_label,LV_ALIGN_LEFT_MID,0,-14); 98 | 99 | lv_obj_t* cpu_load_label = lv_label_create(left_con); 100 | lv_obj_t* cpu_temp_label = lv_label_create(left_con); 101 | lv_obj_t* gpu_load_label = lv_label_create(right_con); 102 | lv_obj_t* gpu_temp_label = lv_label_create(right_con); 103 | lv_obj_set_style_text_font(cpu_load_label,&iconfont_symbol,LV_PART_MAIN); 104 | lv_obj_set_style_text_font(cpu_temp_label,&iconfont_symbol,LV_PART_MAIN); 105 | lv_obj_set_style_text_font(gpu_load_label,&iconfont_symbol,LV_PART_MAIN); 106 | lv_obj_set_style_text_font(gpu_temp_label,&iconfont_symbol,LV_PART_MAIN); 107 | lv_obj_set_style_text_color(cpu_load_label,LOAD_COLOR,LV_PART_MAIN); 108 | lv_obj_set_style_text_color(cpu_temp_label,TEMP_COLOR,LV_PART_MAIN); 109 | lv_obj_set_style_text_color(gpu_temp_label,TEMP_COLOR,LV_PART_MAIN); 110 | lv_obj_set_style_text_color(gpu_load_label,LOAD_COLOR,LV_PART_MAIN); 111 | lv_obj_align(cpu_load_label,LV_ALIGN_BOTTOM_RIGHT,0,0); 112 | lv_obj_align(cpu_temp_label,LV_ALIGN_BOTTOM_RIGHT,-MAIN_DATA_OFFSET_X,-MAIN_DATA_OFFSET_Y); 113 | lv_obj_align(gpu_load_label,LV_ALIGN_BOTTOM_LEFT,0,0); 114 | lv_obj_align(gpu_temp_label,LV_ALIGN_BOTTOM_LEFT,MAIN_DATA_OFFSET_X,-MAIN_DATA_OFFSET_Y); 115 | labels.llarc = cpu_load_label; 116 | labels.ltarc = cpu_temp_label; 117 | labels.rlarc = gpu_load_label; 118 | labels.rtarc = gpu_temp_label; 119 | } 120 | 121 | // void set_text(lv_timer_t* timer){ 122 | // lv_obj_t* text=(lv_obj_t*)timer->user_data; 123 | // lv_label_set_text(text, "Connecting WIFI..."); 124 | // } 125 | 126 | void inline UIManager::init_waiting_for_connect(){ 127 | scr_wait_for_connect = lv_obj_create(NULL); 128 | lv_obj_set_size(scr_wait_for_connect, 160, 80); 129 | lv_obj_set_pos(scr_wait_for_connect, 0, 0); 130 | lv_obj_t *txt = lv_label_create(scr_wait_for_connect); 131 | lv_label_set_text(txt, "Connecting WIFI.."); 132 | lv_obj_align(txt, LV_ALIGN_TOP_MID, 0, 0); 133 | // txt->user_data=0; 134 | // lv_obj_t *led = lv_led_create(scr_wait_for_connect); 135 | // lv_obj_align(led, LV_ALIGN_BOTTOM_MID, 0, 0); 136 | // lv_timer_create(set_text, 500, txt); 137 | } 138 | 139 | void UIManager::update_ui(data_t datas) 140 | { 141 | // data_objs_t *arcs = (data_objs_t *)arg; 142 | anim_set_value_start(arcs.llarc, datas.cpu_load); 143 | anim_set_value_start(arcs.ltarc, datas.cpu_temp); 144 | anim_set_value_start(arcs.rlarc, 100 - datas.gpu_load); 145 | anim_set_value_start(arcs.rtarc, 100 - datas.gpu_temp); 146 | lv_label_set_text_fmt(labels.llarc,"%d" MY_SYMBOL_LOAD,datas.cpu_load); 147 | lv_label_set_text_fmt(labels.ltarc,"%d" MY_SYMBOL_TEMP,datas.cpu_temp); 148 | lv_label_set_text_fmt(labels.rlarc,"%d" MY_SYMBOL_LOAD,datas.gpu_load); 149 | lv_label_set_text_fmt(labels.rtarc,"%d" MY_SYMBOL_TEMP,datas.gpu_temp); 150 | } 151 | 152 | void UIManager::anim_set_value_start(lv_obj_t *arc, int16_t value) 153 | { 154 | lv_anim_t anim; 155 | lv_anim_init(&anim); 156 | lv_anim_set_var(&anim, arc); 157 | lv_anim_set_time(&anim, 300); 158 | lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)lv_arc_set_value); 159 | lv_anim_set_values(&anim, lv_arc_get_value(arc), value); 160 | lv_anim_start(&anim); 161 | } 162 | 163 | 164 | void UIManager::lv_arc_set_style(lv_obj_t *arc, lv_coord_t w, uint16_t rotation, uint16_t bg_start, uint16_t bg_end, float zoom, lv_coord_t x, lv_coord_t y, lv_arc_mode_t mode) 165 | { 166 | lv_obj_set_pos(arc, x, y); 167 | lv_obj_set_style_arc_width(arc, w, LV_PART_MAIN); 168 | lv_obj_set_style_arc_width(arc, w, LV_PART_INDICATOR); 169 | lv_obj_set_style_bg_opa(arc, LV_OPA_10, LV_PART_MAIN); 170 | lv_obj_set_style_bg_opa(arc, LV_OPA_10, LV_PART_INDICATOR); 171 | lv_obj_remove_style(arc, NULL, LV_PART_KNOB); 172 | lv_obj_center(arc); 173 | lv_arc_set_rotation(arc, rotation); 174 | lv_arc_set_bg_angles(arc, bg_start, bg_end); 175 | lv_obj_set_size(arc, (lv_pct((int16_t)(100.0 * zoom))), (lv_pct((int16_t)(100.0 * zoom)))); 176 | lv_arc_set_mode(arc, mode); 177 | } 178 | -------------------------------------------------------------------------------- /src/UIManager.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum screen_type 4 | { 5 | UM_SCR_WAIT_FOR_CONNECT, 6 | UM_SCR_IP_SHOW, 7 | UM_SCR_DATA_SHOW 8 | }; 9 | struct data_t 10 | { 11 | uint8_t cpu_load; 12 | uint8_t cpu_temp; 13 | uint8_t gpu_load; 14 | uint8_t gpu_temp; 15 | }; 16 | class UIManager 17 | { 18 | public: 19 | //切换界面 20 | void load_scr(screen_type st); 21 | UIManager(); 22 | //更新界面 23 | void update_ui(data_t datas); 24 | 25 | private: 26 | //界面初始化函数 27 | void init_waiting_for_connect(); 28 | void init_ip_show(); 29 | void init_data_show(); 30 | //动画函数 31 | void anim_set_value_start(lv_obj_t *arc, int16_t value); 32 | //圆弧样式设置 33 | void lv_arc_set_style(lv_obj_t *arc, lv_coord_t w, uint16_t rotation, uint16_t bg_start, uint16_t bg_end, float zoom, lv_coord_t x, lv_coord_t y, lv_arc_mode_t mode); 34 | lv_obj_t *scr_wait_for_connect; 35 | lv_obj_t *scr_ip_show; 36 | lv_obj_t *scr_data_show; 37 | lv_obj_t* label_ip_show; 38 | struct data_objs_t 39 | { 40 | lv_obj_t *llarc; 41 | lv_obj_t *ltarc; 42 | lv_obj_t *rlarc; 43 | lv_obj_t *rtarc; 44 | } arcs, labels; 45 | }; 46 | -------------------------------------------------------------------------------- /src/WIFIManager.cpp: -------------------------------------------------------------------------------- 1 | #include "WIFIManager.h" 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | WIFIManager::WIFIManager(string ssid, string pwd) : ssid(ssid), pwd(pwd) 7 | { 8 | } 9 | void WIFIManager::connect(bool disconn = true) 10 | { 11 | if (disconn) 12 | WiFi.disconnect(); 13 | WiFi.begin(this->ssid.c_str(), this->pwd.c_str()); 14 | } 15 | bool WIFIManager::checkConn() 16 | { 17 | if (WiFi.status() == WL_CONNECTED) 18 | { 19 | return true; 20 | } 21 | return false; 22 | } 23 | -------------------------------------------------------------------------------- /src/WIFIManager.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class WIFIManager{ 6 | public: 7 | WIFIManager(string ssid,string pwd); 8 | /* 连接WIFI 9 | disconn:是否要先断开再连接 10 | */ 11 | void connect(bool disconn); 12 | /* 检查wifi连接 */ 13 | bool checkConn(); 14 | private: 15 | string ssid,pwd; 16 | }; 17 | -------------------------------------------------------------------------------- /src/iconfont_symbol.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Size: 14 px 3 | * Bpp: 4 4 | * Opts: 5 | ******************************************************************************/ 6 | 7 | #include "lvgl.h" 8 | 9 | #ifndef ICONFONT_SYMBOL 10 | #define ICONFONT_SYMBOL 1 11 | #endif 12 | 13 | #if ICONFONT_SYMBOL 14 | 15 | /*----------------- 16 | * BITMAPS 17 | *----------------*/ 18 | 19 | /*Store the image of the glyphs*/ 20 | static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 21 | /* U+0030 "0" */ 22 | 0x0, 0x8e, 0xfb, 0x20, 0x8, 0xd3, 0x19, 0xd0, 23 | 0xf, 0x40, 0x0, 0xe5, 0x2f, 0x0, 0x0, 0x99, 24 | 0x4e, 0x0, 0x0, 0x8a, 0x4e, 0x0, 0x0, 0x8a, 25 | 0x2f, 0x0, 0x0, 0x99, 0xf, 0x40, 0x0, 0xd5, 26 | 0x8, 0xd2, 0x18, 0xe0, 0x0, 0x8e, 0xfc, 0x20, 27 | 28 | /* U+0031 "1" */ 29 | 0x0, 0x5e, 0x20, 0x0, 0xbc, 0xf2, 0x0, 0x6, 30 | 0xf, 0x20, 0x0, 0x0, 0xf2, 0x0, 0x0, 0xf, 31 | 0x20, 0x0, 0x0, 0xf2, 0x0, 0x0, 0xf, 0x20, 32 | 0x0, 0x0, 0xf2, 0x0, 0x0, 0xf, 0x20, 0x2, 33 | 0xff, 0xff, 0xf5, 34 | 35 | /* U+0032 "2" */ 36 | 0x3, 0xbf, 0xfb, 0x20, 0xd, 0x61, 0x18, 0xe0, 37 | 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x3, 0xf0, 38 | 0x0, 0x0, 0xb, 0x90, 0x0, 0x0, 0x8d, 0x0, 39 | 0x0, 0x7, 0xe1, 0x0, 0x0, 0x5e, 0x20, 0x0, 40 | 0x4, 0xe3, 0x0, 0x0, 0xd, 0xff, 0xff, 0xf9, 41 | 42 | /* U+0033 "3" */ 43 | 0x3, 0xbe, 0xfc, 0x30, 0xc, 0x62, 0x7, 0xe0, 44 | 0x0, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x7, 0xd0, 45 | 0x0, 0x2e, 0xfe, 0x20, 0x0, 0x1, 0x28, 0xe0, 46 | 0x0, 0x0, 0x0, 0xd5, 0x0, 0x0, 0x0, 0xd4, 47 | 0x1e, 0x61, 0x6, 0xe1, 0x4, 0xbf, 0xfb, 0x30, 48 | 49 | /* U+0034 "4" */ 50 | 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x8f, 0x60, 51 | 0x0, 0x3, 0xec, 0x60, 0x0, 0xd, 0x4b, 0x60, 52 | 0x0, 0x89, 0xb, 0x60, 0x3, 0xd0, 0xb, 0x60, 53 | 0xd, 0x30, 0xb, 0x60, 0x4f, 0xff, 0xff, 0xfe, 54 | 0x0, 0x0, 0xb, 0x60, 0x0, 0x0, 0xb, 0x60, 55 | 56 | /* U+0035 "5" */ 57 | 0xaf, 0xff, 0xff, 0x5a, 0x80, 0x0, 0x0, 0xa8, 58 | 0x0, 0x0, 0xa, 0xab, 0xed, 0x40, 0xad, 0x30, 59 | 0x5f, 0x33, 0x10, 0x0, 0x99, 0x0, 0x0, 0x7, 60 | 0xb1, 0x0, 0x0, 0x99, 0xc9, 0x20, 0x5f, 0x22, 61 | 0xae, 0xfc, 0x30, 62 | 63 | /* U+0036 "6" */ 64 | 0x0, 0x4d, 0xfe, 0x91, 0x4, 0xe5, 0x12, 0x76, 65 | 0xc, 0x60, 0x0, 0x0, 0x1f, 0x3c, 0xfc, 0x40, 66 | 0x3f, 0xc4, 0x5, 0xf2, 0x3f, 0x70, 0x0, 0x99, 67 | 0x2f, 0x40, 0x0, 0x7b, 0xe, 0x70, 0x0, 0x98, 68 | 0x6, 0xe4, 0x5, 0xf2, 0x0, 0x6d, 0xfc, 0x30, 69 | 70 | /* U+0037 "7" */ 71 | 0x1f, 0xff, 0xff, 0xf7, 0x0, 0x0, 0x1, 0xf3, 72 | 0x0, 0x0, 0x8, 0xa0, 0x0, 0x0, 0x1f, 0x20, 73 | 0x0, 0x0, 0x9a, 0x0, 0x0, 0x1, 0xf2, 0x0, 74 | 0x0, 0x9, 0x90, 0x0, 0x0, 0x2f, 0x10, 0x0, 75 | 0x0, 0xa9, 0x0, 0x0, 0x2, 0xf1, 0x0, 0x0, 76 | 77 | /* U+0038 "8" */ 78 | 0x1, 0xae, 0xfc, 0x40, 0xd, 0xa1, 0x5, 0xf3, 79 | 0x1f, 0x10, 0x0, 0xa7, 0xe, 0x30, 0x0, 0xc5, 80 | 0x3, 0xb6, 0x4a, 0x70, 0x7, 0xb4, 0x38, 0xc1, 81 | 0x3e, 0x0, 0x0, 0x89, 0x5d, 0x0, 0x0, 0x6b, 82 | 0x1e, 0x71, 0x3, 0xd6, 0x2, 0xbe, 0xfd, 0x60, 83 | 84 | /* U+0039 "9" */ 85 | 0x1, 0xae, 0xea, 0x10, 0xd, 0x91, 0x19, 0xc0, 86 | 0x3e, 0x0, 0x0, 0xe4, 0x3e, 0x0, 0x0, 0xe8, 87 | 0xd, 0x80, 0x19, 0xea, 0x2, 0xbe, 0xe7, 0x99, 88 | 0x0, 0x0, 0x0, 0xb7, 0x0, 0x0, 0x1, 0xf3, 89 | 0x2d, 0x40, 0x1b, 0xb0, 0x5, 0xcf, 0xe9, 0x0, 90 | 91 | /* U+E6EE "" */ 92 | 0x1, 0x20, 0x0, 0x13, 0x0, 0x2c, 0x97, 0x4, 93 | 0xc8, 0xb4, 0x65, 0xb, 0xc, 0x0, 0x9, 0x1c, 94 | 0xb6, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x0, 95 | 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 96 | 0xb, 0x0, 0x3, 0x0, 0x0, 0xa, 0x50, 0x59, 97 | 0x0, 0x0, 0x0, 0x8b, 0x70, 98 | 99 | /* U+E73B "" */ 100 | 0x0, 0x77, 0x0, 0x0, 0x50, 0x9, 0x22, 0x90, 101 | 0x7, 0x30, 0x9, 0x0, 0x90, 0x47, 0x0, 0xa, 102 | 0x0, 0xa1, 0x90, 0x0, 0x3, 0xaa, 0x39, 0x10, 103 | 0x0, 0x0, 0x0, 0x74, 0x7a, 0x90, 0x0, 0x3, 104 | 0x84, 0x60, 0x27, 0x0, 0xa, 0x6, 0x30, 0x9, 105 | 0x0, 0x92, 0x2, 0x80, 0x55, 0x1, 0x40, 0x0, 106 | 0x49, 0x60 107 | }; 108 | 109 | 110 | /*--------------------- 111 | * GLYPH DESCRIPTION 112 | *--------------------*/ 113 | 114 | static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { 115 | {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, 116 | {.bitmap_index = 0, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 117 | {.bitmap_index = 40, .adv_w = 147, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 2}, 118 | {.bitmap_index = 75, .adv_w = 136, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 119 | {.bitmap_index = 115, .adv_w = 130, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 120 | {.bitmap_index = 155, .adv_w = 138, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 121 | {.bitmap_index = 195, .adv_w = 141, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 2}, 122 | {.bitmap_index = 230, .adv_w = 136, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 123 | {.bitmap_index = 270, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 124 | {.bitmap_index = 310, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 125 | {.bitmap_index = 350, .adv_w = 133, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 2}, 126 | {.bitmap_index = 390, .adv_w = 224, .box_w = 10, .box_h = 9, .ofs_x = 2, .ofs_y = 1}, 127 | {.bitmap_index = 435, .adv_w = 224, .box_w = 10, .box_h = 10, .ofs_x = 2, .ofs_y = 0} 128 | }; 129 | 130 | /*--------------------- 131 | * CHARACTER MAPPING 132 | *--------------------*/ 133 | 134 | static const uint16_t unicode_list_1[] = { 135 | 0x0, 0x4d 136 | }; 137 | 138 | /*Collect the unicode lists and glyph_id offsets*/ 139 | static const lv_font_fmt_txt_cmap_t cmaps[] = 140 | { 141 | { 142 | .range_start = 48, .range_length = 10, .glyph_id_start = 1, 143 | .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY 144 | }, 145 | { 146 | .range_start = 59118, .range_length = 78, .glyph_id_start = 11, 147 | .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 2, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY 148 | } 149 | }; 150 | 151 | 152 | 153 | /*-------------------- 154 | * ALL CUSTOM DATA 155 | *--------------------*/ 156 | 157 | #if LV_VERSION_CHECK(8, 0, 0) 158 | /*Store all the custom data of the font*/ 159 | static lv_font_fmt_txt_glyph_cache_t cache; 160 | static const lv_font_fmt_txt_dsc_t font_dsc = { 161 | #else 162 | static lv_font_fmt_txt_dsc_t font_dsc = { 163 | #endif 164 | .glyph_bitmap = glyph_bitmap, 165 | .glyph_dsc = glyph_dsc, 166 | .cmaps = cmaps, 167 | .kern_dsc = NULL, 168 | .kern_scale = 0, 169 | .cmap_num = 2, 170 | .bpp = 4, 171 | .kern_classes = 0, 172 | .bitmap_format = 0, 173 | #if LV_VERSION_CHECK(8, 0, 0) 174 | .cache = &cache 175 | #endif 176 | }; 177 | 178 | 179 | /*----------------- 180 | * PUBLIC FONT 181 | *----------------*/ 182 | 183 | /*Initialize a public general font descriptor*/ 184 | #if LV_VERSION_CHECK(8, 0, 0) 185 | const lv_font_t iconfont_symbol = { 186 | #else 187 | lv_font_t iconfont_symbol = { 188 | #endif 189 | .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ 190 | .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ 191 | .line_height = 12, /*The maximum line height required by the font*/ 192 | .base_line = 0, /*Baseline measured from the bottom of the line*/ 193 | #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) 194 | .subpx = LV_FONT_SUBPX_NONE, 195 | #endif 196 | #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 197 | .underline_position = 0, 198 | .underline_thickness = 0, 199 | #endif 200 | .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ 201 | }; 202 | 203 | 204 | 205 | #endif /*#if ICONFONT_SYMBOL*/ 206 | 207 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "WIFIManager.h" 6 | #include "UIManager.h" 7 | 8 | #define WAINTING_PERIOD 1000 9 | #define MAIN_DATA_OFFSET_X 12 10 | #define MAIN_DATA_OFFSET_Y 18 11 | #define MY_SYMBOL_TEMP "\xEE\x9B\xAE" 12 | #define MY_SYMBOL_LOAD "\xEE\x9C\xBB" 13 | #define TEMP_COLOR lv_color_hex(0xa30cf9) 14 | #define LOAD_COLOR lv_color_hex(0x21a3ef) 15 | LV_FONT_DECLARE(iconfont_symbol); 16 | 17 | static const uint16_t screenWidth = 160; 18 | static const uint16_t screenHeight = 80; 19 | int port = 34567; //端口 20 | 21 | data_t data; 22 | 23 | //显示缓存 24 | static lv_disp_draw_buf_t draw_buf; 25 | static lv_color_t buf[screenWidth * 10]; 26 | 27 | TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */ 28 | WiFiServer server(port); 29 | 30 | WiFiClient client;//与上位机通讯的客户端 31 | lv_timer_t *server_timer = NULL; 32 | WIFIManager wm("nova 5 Pro", "81297311");//wifi管理器 33 | UIManager *um;//显示界面管理器 34 | 35 | void wifi_server_listen_timer(lv_timer_t *); 36 | void wifi_client_get_data_timer(lv_timer_t *); 37 | 38 | void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) 39 | { 40 | uint32_t w = (area->x2 - area->x1 + 1); 41 | uint32_t h = (area->y2 - area->y1 + 1); 42 | 43 | tft.startWrite(); 44 | tft.setAddrWindow(area->x1, area->y1, w, h); 45 | tft.pushColors((uint16_t *)&color_p->full, w * h, true); 46 | tft.endWrite(); 47 | 48 | lv_disp_flush_ready(disp); 49 | } 50 | 51 | void check_wifi_conn_timer(lv_timer_t *timer) 52 | { 53 | if (wm.checkConn()) 54 | { 55 | Serial.println("wifi connected"); 56 | server.begin(); 57 | //wifi已连接,切换显示ip 58 | um->load_scr(UM_SCR_IP_SHOW); 59 | lv_timer_del(timer); 60 | lv_timer_create(wifi_server_listen_timer,1000,NULL); 61 | } 62 | } 63 | 64 | void inline display_init() 65 | { 66 | lv_init(); 67 | 68 | tft.begin(); /* TFT init */ 69 | tft.setRotation(1); /* Landscape orientation, flipped */ 70 | 71 | lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * 10); 72 | 73 | /*Initialize the display*/ 74 | static lv_disp_drv_t disp_drv; 75 | lv_disp_drv_init(&disp_drv); 76 | /*Change the following line to your display resolution*/ 77 | disp_drv.hor_res = screenWidth; 78 | disp_drv.ver_res = screenHeight; 79 | disp_drv.flush_cb = my_disp_flush; 80 | disp_drv.draw_buf = &draw_buf; 81 | lv_disp_drv_register(&disp_drv); 82 | } 83 | 84 | /* 上位机连接监听 */ 85 | void wifi_server_listen_timer(lv_timer_t *timer) 86 | { 87 | Serial.println("等待WIFI上位机连接"); 88 | client = server.available(); 89 | if (!client) 90 | return; 91 | Serial.println("WiFiClient established"); 92 | Serial.printf("Client IP :%s\n", client.remoteIP().toString().c_str()); 93 | um->load_scr(UM_SCR_DATA_SHOW);//加载显示数据界面 94 | client.setTimeout(3); 95 | //接收处理数据函数的定时器 96 | //仅执行一次是为了让当前轮函数运行后在执行下一轮函数,以防两轮的函数同时执行 97 | lv_timer_t *t = lv_timer_create(wifi_client_get_data_timer, 1000, NULL); 98 | lv_timer_set_repeat_count(t, 1); 99 | lv_timer_del(timer); 100 | } 101 | 102 | void wifi_client_get_data_timer(lv_timer_t *timer) 103 | { 104 | 105 | if (!client) 106 | { 107 | client.stop(); 108 | //当前连接已断开,启动监听上位机连接的函数 109 | lv_timer_create(wifi_server_listen_timer, 1000, NULL); 110 | um->load_scr(UM_SCR_IP_SHOW);//加载显示ip的界面 111 | Serial.println("stop WiFiClient"); 112 | return; 113 | } 114 | if (!client.available()) 115 | { 116 | // delay(WAINTING_PERIOD); 117 | //开启下一次数据处理函数 118 | lv_timer_t *t = lv_timer_create(wifi_client_get_data_timer, 1000, timer->user_data); 119 | lv_timer_set_repeat_count(t, 1); 120 | return; 121 | } 122 | // delay(WAINTING_PERIOD); 123 | data.cpu_load = client.parseInt(); 124 | data.cpu_temp = client.parseInt(); 125 | data.gpu_load = client.parseInt(); 126 | data.gpu_temp = client.parseInt(); 127 | um->update_ui(data);//刷新界面 128 | Serial.printf("get new data::{%d,%d,%d,%d}\n", data.cpu_load, data.cpu_temp, data.gpu_load, data.gpu_temp); 129 | //开启下一次数据处理函数 130 | lv_timer_t *t = lv_timer_create(wifi_client_get_data_timer, 1000, timer->user_data); 131 | lv_timer_set_repeat_count(t, 1); 132 | Serial.println("set new async call"); 133 | } 134 | 135 | void main_init() 136 | { 137 | //UI管理器 138 | um = new UIManager(); 139 | Serial.println("show screen wait for connect"); 140 | um->load_scr(UM_SCR_WAIT_FOR_CONNECT);//加载等待wifi连接的界面 141 | Serial.println("start connect wifi"); 142 | wm.connect(true);//连接wifi 143 | lv_timer_create(check_wifi_conn_timer, 1000, NULL);//定时检查wifi连接 144 | } 145 | /* 生成随机数据 */ 146 | void update_random_data(lv_timer_t *t) 147 | { 148 | uint8_t dat = rand() % 101; 149 | data.cpu_load = dat; 150 | data.cpu_temp = dat; 151 | data.gpu_load = dat; 152 | data.gpu_temp = dat; 153 | um->update_ui(data); 154 | } 155 | 156 | void setup() 157 | { 158 | Serial.begin(115200); /* prepare for possible serial debug */ 159 | display_init();//显示驱动和lvgl初始化 160 | main_init(); 161 | Serial.println("Setup done"); 162 | } 163 | void loop() 164 | { 165 | //lvgl的定时处理器 166 | lv_timer_handler(); /* let the GUI do its work */ 167 | delay(5); 168 | } 169 | -------------------------------------------------------------------------------- /src/setup.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imshixin/esp32c3_lvgl_observer/564775470eeb99c281a8837845ca4d1fed841dca/src/setup.cpp -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | --------------------------------------------------------------------------------