Initial CYD TF card info display with LVGL.
Mount microSD on VSPI and show type, format, and capacity on the CYD screen. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
.pio/
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
*.pyc
|
||||
__pycache__/
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
assets/
|
||||
*.bin
|
||||
*.elf
|
||||
43
README.md
Normal file
43
README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# CYD TF 卡信息显示(LVGL)
|
||||
|
||||
在 **ESP32-2432S028(CYD)** 上挂载 TF/microSD,用 LVGL 显示卡类型、文件系统、容量、已用/可用空间等。
|
||||
|
||||
## 硬件
|
||||
|
||||
| 功能 | GPIO |
|
||||
|------|------|
|
||||
| TFT MOSI / MISO / SCLK | 13 / 12 / 14 |
|
||||
| TFT CS / DC / BL | 15 / 2 / 21 |
|
||||
| **SD MOSI / MISO / SCK / CS** | **23 / 19 / 18 / 5** |
|
||||
|
||||
TF 卡使用独立 VSPI;显示使用 TFT_eSPI(HSPI)。本工程未启用触摸,避免与 SD 争用总线。
|
||||
|
||||
## 屏幕显示内容
|
||||
|
||||
- Status:是否挂载成功
|
||||
- Type:MMC / SDSC / SDHC
|
||||
- Format:FAT16 / FAT32 等(按分区容量推断)
|
||||
- Capacity:卡物理容量
|
||||
- Partition / Used / Free:分区总容量、已用、剩余
|
||||
- Root files:根目录条目数
|
||||
- 进度条:已用百分比
|
||||
|
||||
每 3 秒自动刷新;串口 115200 同步打印同样信息。
|
||||
|
||||
## 编译烧录
|
||||
|
||||
1. VS Code / Cursor 安装 **PlatformIO** 扩展
|
||||
2. 打开本目录,连接 CYD(通常 USB 转串口 CH340)
|
||||
3. 执行:
|
||||
|
||||
```bash
|
||||
pio run -t upload
|
||||
pio device monitor
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- TF 卡需为 **FAT/FAT32**(Arduino `SD` 库);exFAT 通常无法挂载。
|
||||
- 首次使用建议先在电脑上格式化为 FAT32。
|
||||
- 若花屏,可在 `platformio.ini` 把 `ILI9341_2_DRIVER` 换成 `ILI9341_DRIVER` 再试。
|
||||
- 若只要竖屏,在 `main.cpp` 去掉或改 `lv_display_set_rotation`。
|
||||
13
copy_lv_conf.py
Normal file
13
copy_lv_conf.py
Normal file
@@ -0,0 +1,13 @@
|
||||
Import("env") # noqa: F821
|
||||
from pathlib import Path
|
||||
|
||||
src = Path(env["PROJECT_DIR"]) / "include" / "lv_conf.h" # noqa: F821
|
||||
dst_dir = Path(env["PROJECT_LIBDEPS_DIR"]) / env["PIOENV"] # noqa: F821
|
||||
dst_dir.mkdir(parents=True, exist_ok=True)
|
||||
dst = dst_dir / "lv_conf.h"
|
||||
if src.exists():
|
||||
dst.write_text(src.read_text(encoding="utf-8"), encoding="utf-8")
|
||||
lvgl = dst_dir / "lvgl" / "lv_conf.h"
|
||||
if (dst_dir / "lvgl").exists():
|
||||
lvgl.write_text(src.read_text(encoding="utf-8"), encoding="utf-8")
|
||||
print(f"copy_lv_conf: synced -> {dst}")
|
||||
1127
include/lv_conf.h
Normal file
1127
include/lv_conf.h
Normal file
File diff suppressed because it is too large
Load Diff
15
include/pins.h
Normal file
15
include/pins.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
// CYD ESP32-2432S028R 引脚
|
||||
|
||||
// TFT (HSPI / TFT_eSPI 已在 platformio.ini 配置)
|
||||
#define TFT_BL_PIN 21
|
||||
|
||||
// TF / microSD (独立 VSPI)
|
||||
#define SD_MISO 19
|
||||
#define SD_MOSI 23
|
||||
#define SD_SCK 18
|
||||
#define SD_CS 5
|
||||
|
||||
#define SCREEN_WIDTH 240
|
||||
#define SCREEN_HEIGHT 320
|
||||
21
include/sd_info.h
Normal file
21
include/sd_info.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
struct SdCardInfo {
|
||||
bool mounted;
|
||||
bool present;
|
||||
const char *type; // MMC / SDSC / SDHC / UNKNOWN / NONE
|
||||
const char *filesystem; // FAT12 / FAT16 / FAT32 / exFAT / FAT / —
|
||||
uint64_t card_bytes; // 卡物理容量
|
||||
uint64_t total_bytes; // 分区总容量
|
||||
uint64_t used_bytes;
|
||||
uint64_t free_bytes;
|
||||
uint32_t root_files; // 根目录条目数
|
||||
String error; // 失败原因
|
||||
};
|
||||
|
||||
bool sd_init();
|
||||
void sd_deinit();
|
||||
SdCardInfo sd_read_info();
|
||||
String format_bytes(uint64_t bytes);
|
||||
6
include/ui.h
Normal file
6
include/ui.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "sd_info.h"
|
||||
|
||||
void ui_create();
|
||||
void ui_update(const SdCardInfo &info);
|
||||
50
platformio.ini
Normal file
50
platformio.ini
Normal file
@@ -0,0 +1,50 @@
|
||||
; CYD ESP32-2432S028 — TF 卡信息 + LVGL 显示
|
||||
[env:cyd]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
board_build.partitions = default.csv
|
||||
|
||||
lib_deps =
|
||||
bodmer/TFT_eSPI@^2.5.43
|
||||
lvgl/lvgl@9.2.2
|
||||
|
||||
build_flags =
|
||||
-DCORE_DEBUG_LEVEL=0
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DILI9341_2_DRIVER=1
|
||||
-DTFT_WIDTH=240
|
||||
-DTFT_HEIGHT=320
|
||||
-DTFT_MISO=12
|
||||
-DTFT_MOSI=13
|
||||
-DTFT_SCLK=14
|
||||
-DTFT_CS=15
|
||||
-DTFT_DC=2
|
||||
-DTFT_RST=-1
|
||||
-DTFT_BL=21
|
||||
-DTFT_BACKLIGHT_ON=HIGH
|
||||
-DTOUCH_CS=-1
|
||||
-DLOAD_GLCD=1
|
||||
-DLOAD_FONT2=1
|
||||
-DLOAD_FONT4=1
|
||||
-DLOAD_FONT6=1
|
||||
-DLOAD_FONT7=1
|
||||
-DLOAD_FONT8=1
|
||||
-DLOAD_GFXFF=1
|
||||
-DSMOOTH_FONT=1
|
||||
-DSPI_FREQUENCY=40000000
|
||||
-DSPI_READ_FREQUENCY=20000000
|
||||
; lv_conf.h 放在 .pio/libdeps/cyd/lv_conf.h(见 extra_script)
|
||||
-DLV_CONF_SKIP
|
||||
-DLV_COLOR_DEPTH=16
|
||||
-DLV_MEM_SIZE=49152
|
||||
-DLV_FONT_MONTSERRAT_14=1
|
||||
-DLV_FONT_MONTSERRAT_16=1
|
||||
-DLV_FONT_MONTSERRAT_18=1
|
||||
-DLV_FONT_MONTSERRAT_20=1
|
||||
-DLV_USE_TFT_ESPI=1
|
||||
-DLV_USE_FLEX=1
|
||||
-I${PROJECT_DIR}/include
|
||||
|
||||
extra_scripts = pre:copy_lv_conf.py
|
||||
74
src/main.cpp
Normal file
74
src/main.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <Arduino.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include <lvgl.h>
|
||||
|
||||
#include "pins.h"
|
||||
#include "sd_info.h"
|
||||
#include "ui.h"
|
||||
|
||||
static constexpr uint32_t DRAW_BUF_SIZE =
|
||||
(SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8));
|
||||
static uint32_t draw_buf[DRAW_BUF_SIZE / 4];
|
||||
|
||||
static uint32_t last_refresh_ms = 0;
|
||||
static constexpr uint32_t REFRESH_MS = 3000;
|
||||
|
||||
static void refresh_sd_ui() {
|
||||
SdCardInfo info = sd_read_info();
|
||||
|
||||
Serial.println("---- TF Card ----");
|
||||
if (!info.mounted) {
|
||||
Serial.printf("Error: %s\n", info.error.c_str());
|
||||
} else {
|
||||
Serial.printf("Type: %s\n", info.type);
|
||||
Serial.printf("FS: %s\n", info.filesystem);
|
||||
Serial.printf("Card: %s\n", format_bytes(info.card_bytes).c_str());
|
||||
Serial.printf("Part: %s\n", format_bytes(info.total_bytes).c_str());
|
||||
Serial.printf("Used: %s\n", format_bytes(info.used_bytes).c_str());
|
||||
Serial.printf("Free: %s\n", format_bytes(info.free_bytes).c_str());
|
||||
Serial.printf("Root entries: %lu\n",
|
||||
static_cast<unsigned long>(info.root_files));
|
||||
}
|
||||
|
||||
ui_update(info);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(200);
|
||||
Serial.println();
|
||||
Serial.printf("LVGL %d.%d.%d | CYD TF info\n", lv_version_major(),
|
||||
lv_version_minor(), lv_version_patch());
|
||||
|
||||
pinMode(TFT_BL_PIN, OUTPUT);
|
||||
digitalWrite(TFT_BL_PIN, HIGH);
|
||||
|
||||
lv_init();
|
||||
|
||||
lv_display_t *disp =
|
||||
lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
|
||||
// 横屏:320x240
|
||||
lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
|
||||
|
||||
ui_create();
|
||||
|
||||
if (!sd_init()) {
|
||||
Serial.println("SD mount failed at boot");
|
||||
}
|
||||
|
||||
refresh_sd_ui();
|
||||
last_refresh_ms = millis();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
lv_timer_handler();
|
||||
lv_tick_inc(5);
|
||||
|
||||
uint32_t now = millis();
|
||||
if (now - last_refresh_ms >= REFRESH_MS) {
|
||||
last_refresh_ms = now;
|
||||
refresh_sd_ui();
|
||||
}
|
||||
|
||||
delay(5);
|
||||
}
|
||||
139
src/sd_info.cpp
Normal file
139
src/sd_info.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "sd_info.h"
|
||||
#include "pins.h"
|
||||
|
||||
#include <FS.h>
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
static SPIClass sd_spi(VSPI);
|
||||
static bool sd_ready = false;
|
||||
|
||||
static const char *card_type_name(uint8_t t) {
|
||||
switch (t) {
|
||||
case CARD_MMC: return "MMC";
|
||||
case CARD_SD: return "SDSC";
|
||||
case CARD_SDHC: return "SDHC";
|
||||
case CARD_NONE: return "NONE";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
// 读引导扇区,尽量识别 FAT 类型(Arduino SD 挂载的是 FatFs)
|
||||
static const char *detect_filesystem() {
|
||||
File root = SD.open("/");
|
||||
if (!root) {
|
||||
return "—";
|
||||
}
|
||||
root.close();
|
||||
|
||||
// 通过容量启发式:Arduino SD 库挂载成功即为 FAT 系
|
||||
// 再尝试从卷信息推断常见类型
|
||||
uint64_t total = SD.totalBytes();
|
||||
if (total == 0) {
|
||||
return "FAT";
|
||||
}
|
||||
// FatFs 对 >32MB 常用 FAT32;小卡可能是 FAT16
|
||||
if (total > 32ULL * 1024ULL * 1024ULL) {
|
||||
return "FAT32";
|
||||
}
|
||||
if (total > 2ULL * 1024ULL * 1024ULL) {
|
||||
return "FAT16";
|
||||
}
|
||||
return "FAT12/16";
|
||||
}
|
||||
|
||||
static uint32_t count_root_entries() {
|
||||
File root = SD.open("/");
|
||||
if (!root || !root.isDirectory()) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t n = 0;
|
||||
File f = root.openNextFile();
|
||||
while (f) {
|
||||
n++;
|
||||
f = root.openNextFile();
|
||||
}
|
||||
root.close();
|
||||
return n;
|
||||
}
|
||||
|
||||
bool sd_init() {
|
||||
if (sd_ready) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pinMode(SD_CS, OUTPUT);
|
||||
digitalWrite(SD_CS, HIGH);
|
||||
|
||||
sd_spi.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
|
||||
|
||||
// CYD 上 SD 与触摸争用 VSPI;本工程不用硬件触摸,频率适中更稳
|
||||
if (!SD.begin(SD_CS, sd_spi, 25000000)) {
|
||||
sd_ready = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
sd_ready = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void sd_deinit() {
|
||||
if (sd_ready) {
|
||||
SD.end();
|
||||
sd_ready = false;
|
||||
}
|
||||
}
|
||||
|
||||
SdCardInfo sd_read_info() {
|
||||
SdCardInfo info{};
|
||||
info.mounted = false;
|
||||
info.present = false;
|
||||
info.type = "NONE";
|
||||
info.filesystem = "—";
|
||||
info.card_bytes = 0;
|
||||
info.total_bytes = 0;
|
||||
info.used_bytes = 0;
|
||||
info.free_bytes = 0;
|
||||
info.root_files = 0;
|
||||
|
||||
if (!sd_ready && !sd_init()) {
|
||||
info.error = "Mount failed";
|
||||
return info;
|
||||
}
|
||||
|
||||
uint8_t type = SD.cardType();
|
||||
info.type = card_type_name(type);
|
||||
|
||||
if (type == CARD_NONE) {
|
||||
info.error = "No card";
|
||||
info.present = false;
|
||||
return info;
|
||||
}
|
||||
|
||||
info.present = true;
|
||||
info.mounted = true;
|
||||
info.card_bytes = SD.cardSize();
|
||||
info.total_bytes = SD.totalBytes();
|
||||
info.used_bytes = SD.usedBytes();
|
||||
info.free_bytes =
|
||||
(info.total_bytes > info.used_bytes) ? (info.total_bytes - info.used_bytes) : 0;
|
||||
info.filesystem = detect_filesystem();
|
||||
info.root_files = count_root_entries();
|
||||
info.error = "";
|
||||
return info;
|
||||
}
|
||||
|
||||
String format_bytes(uint64_t bytes) {
|
||||
const double b = static_cast<double>(bytes);
|
||||
char buf[48];
|
||||
if (bytes >= (1ULL << 30)) {
|
||||
snprintf(buf, sizeof(buf), "%.2f GB", b / (1024.0 * 1024.0 * 1024.0));
|
||||
} else if (bytes >= (1ULL << 20)) {
|
||||
snprintf(buf, sizeof(buf), "%.2f MB", b / (1024.0 * 1024.0));
|
||||
} else if (bytes >= (1ULL << 10)) {
|
||||
snprintf(buf, sizeof(buf), "%.2f KB", b / 1024.0);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%llu B", static_cast<unsigned long long>(bytes));
|
||||
}
|
||||
return String(buf);
|
||||
}
|
||||
150
src/ui.cpp
Normal file
150
src/ui.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include "ui.h"
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
static lv_obj_t *lbl_status;
|
||||
static lv_obj_t *lbl_type;
|
||||
static lv_obj_t *lbl_fs;
|
||||
static lv_obj_t *lbl_capacity;
|
||||
static lv_obj_t *lbl_total;
|
||||
static lv_obj_t *lbl_used;
|
||||
static lv_obj_t *lbl_free;
|
||||
static lv_obj_t *lbl_files;
|
||||
static lv_obj_t *bar_usage;
|
||||
static lv_obj_t *lbl_hint;
|
||||
|
||||
static lv_obj_t *make_row(lv_obj_t *parent, const char *title, lv_obj_t **value_out) {
|
||||
lv_obj_t *row = lv_obj_create(parent);
|
||||
lv_obj_set_width(row, LV_PCT(100));
|
||||
lv_obj_set_height(row, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_bg_opa(row, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(row, 0, 0);
|
||||
lv_obj_set_style_pad_all(row, 2, 0);
|
||||
lv_obj_set_flex_flow(row, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(row, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_clear_flag(row, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
lv_obj_t *t = lv_label_create(row);
|
||||
lv_label_set_text(t, title);
|
||||
lv_obj_set_style_text_color(t, lv_color_hex(0x90A4AE), 0);
|
||||
lv_obj_set_style_text_font(t, &lv_font_montserrat_14, 0);
|
||||
|
||||
lv_obj_t *v = lv_label_create(row);
|
||||
lv_label_set_text(v, "—");
|
||||
lv_obj_set_style_text_color(v, lv_color_hex(0xECEFF1), 0);
|
||||
lv_obj_set_style_text_font(v, &lv_font_montserrat_16, 0);
|
||||
*value_out = v;
|
||||
return row;
|
||||
}
|
||||
|
||||
void ui_create() {
|
||||
lv_obj_t *scr = lv_screen_active();
|
||||
lv_obj_set_style_bg_color(scr, lv_color_hex(0x0D1B2A), 0);
|
||||
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||
|
||||
lv_obj_t *col = lv_obj_create(scr);
|
||||
lv_obj_set_size(col, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_style_bg_opa(col, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(col, 0, 0);
|
||||
lv_obj_set_style_pad_left(col, 12, 0);
|
||||
lv_obj_set_style_pad_right(col, 12, 0);
|
||||
lv_obj_set_style_pad_top(col, 10, 0);
|
||||
lv_obj_set_style_pad_bottom(col, 8, 0);
|
||||
lv_obj_set_flex_flow(col, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(col, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER,
|
||||
LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_set_style_pad_row(col, 4, 0);
|
||||
lv_obj_clear_flag(col, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
lv_obj_t *title = lv_label_create(col);
|
||||
lv_label_set_text(title, "TF Card");
|
||||
lv_obj_set_style_text_font(title, &lv_font_montserrat_20, 0);
|
||||
lv_obj_set_style_text_color(title, lv_color_hex(0x4FC3F7), 0);
|
||||
|
||||
lv_obj_t *subtitle = lv_label_create(col);
|
||||
lv_label_set_text(subtitle, "CYD ESP32 Storage Info");
|
||||
lv_obj_set_style_text_font(subtitle, &lv_font_montserrat_14, 0);
|
||||
lv_obj_set_style_text_color(subtitle, lv_color_hex(0x607D8B), 0);
|
||||
|
||||
lv_obj_t *sep = lv_obj_create(col);
|
||||
lv_obj_set_size(sep, LV_PCT(100), 1);
|
||||
lv_obj_set_style_bg_color(sep, lv_color_hex(0x37474F), 0);
|
||||
lv_obj_set_style_bg_opa(sep, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_border_width(sep, 0, 0);
|
||||
lv_obj_set_style_pad_all(sep, 0, 0);
|
||||
|
||||
make_row(col, "Status", &lbl_status);
|
||||
make_row(col, "Type", &lbl_type);
|
||||
make_row(col, "Format", &lbl_fs);
|
||||
make_row(col, "Capacity", &lbl_capacity);
|
||||
make_row(col, "Partition", &lbl_total);
|
||||
make_row(col, "Used", &lbl_used);
|
||||
make_row(col, "Free", &lbl_free);
|
||||
make_row(col, "Root files", &lbl_files);
|
||||
|
||||
bar_usage = lv_bar_create(col);
|
||||
lv_obj_set_width(bar_usage, LV_PCT(100));
|
||||
lv_obj_set_height(bar_usage, 14);
|
||||
lv_bar_set_range(bar_usage, 0, 100);
|
||||
lv_bar_set_value(bar_usage, 0, LV_ANIM_OFF);
|
||||
lv_obj_set_style_bg_color(bar_usage, lv_color_hex(0x263238), 0);
|
||||
lv_obj_set_style_bg_opa(bar_usage, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_bg_color(bar_usage, lv_color_hex(0x29B6F6), LV_PART_INDICATOR);
|
||||
lv_obj_set_style_radius(bar_usage, 4, 0);
|
||||
lv_obj_set_style_radius(bar_usage, 4, LV_PART_INDICATOR);
|
||||
|
||||
lbl_hint = lv_label_create(col);
|
||||
lv_label_set_text(lbl_hint, "Refreshing every 3s");
|
||||
lv_obj_set_style_text_font(lbl_hint, &lv_font_montserrat_14, 0);
|
||||
lv_obj_set_style_text_color(lbl_hint, lv_color_hex(0x546E7A), 0);
|
||||
}
|
||||
|
||||
void ui_update(const SdCardInfo &info) {
|
||||
if (!info.mounted || !info.present) {
|
||||
lv_label_set_text(lbl_status, info.error.length() ? info.error.c_str() : "Fail");
|
||||
lv_obj_set_style_text_color(lbl_status, lv_color_hex(0xEF5350), 0);
|
||||
lv_label_set_text(lbl_type, info.type);
|
||||
lv_label_set_text(lbl_fs, "—");
|
||||
lv_label_set_text(lbl_capacity, "—");
|
||||
lv_label_set_text(lbl_total, "—");
|
||||
lv_label_set_text(lbl_used, "—");
|
||||
lv_label_set_text(lbl_free, "—");
|
||||
lv_label_set_text(lbl_files, "—");
|
||||
lv_bar_set_value(bar_usage, 0, LV_ANIM_OFF);
|
||||
lv_label_set_text(lbl_hint, "Insert TF and wait...");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_label_set_text(lbl_status, "Mounted OK");
|
||||
lv_obj_set_style_text_color(lbl_status, lv_color_hex(0x66BB6A), 0);
|
||||
lv_label_set_text(lbl_type, info.type);
|
||||
lv_label_set_text(lbl_fs, info.filesystem);
|
||||
|
||||
String cap = format_bytes(info.card_bytes);
|
||||
String tot = format_bytes(info.total_bytes);
|
||||
String used = format_bytes(info.used_bytes);
|
||||
String freeb = format_bytes(info.free_bytes);
|
||||
|
||||
lv_label_set_text(lbl_capacity, cap.c_str());
|
||||
lv_label_set_text(lbl_total, tot.c_str());
|
||||
lv_label_set_text(lbl_used, used.c_str());
|
||||
lv_label_set_text(lbl_free, freeb.c_str());
|
||||
|
||||
char files_buf[16];
|
||||
snprintf(files_buf, sizeof(files_buf), "%lu", static_cast<unsigned long>(info.root_files));
|
||||
lv_label_set_text(lbl_files, files_buf);
|
||||
|
||||
int pct = 0;
|
||||
if (info.total_bytes > 0) {
|
||||
pct = static_cast<int>((info.used_bytes * 100ULL) / info.total_bytes);
|
||||
if (pct > 100) {
|
||||
pct = 100;
|
||||
}
|
||||
}
|
||||
lv_bar_set_value(bar_usage, pct, LV_ANIM_ON);
|
||||
|
||||
char hint[40];
|
||||
snprintf(hint, sizeof(hint), "Used %d%% | auto refresh", pct);
|
||||
lv_label_set_text(lbl_hint, hint);
|
||||
}
|
||||
Reference in New Issue
Block a user