# ble_tool **Repository Path**: panzi/ble_tool ## Basic Information - **Project Name**: ble_tool - **Description**: esp32实现工具 - **Primary Language**: C - **License**: LGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-03 - **Last Updated**: 2026-05-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ESP32-C3 Desktop Ornament This project turns the ESP32-C3 + ST7735 LCD board into a small desktop information ornament. It shows time, date, weather, fuel price, exchange rate, and device status on a 160x80 display with joystick navigation. The original BLE HID code is still present, but desktop mode is now the default. BLE HID is disabled by default to leave more RAM for Wi-Fi, HTTP, SNTP, and LVGL. ## Features - Fixed one-screen dashboard: - Top row: city, weather, temperature, humidity, Wi-Fi status - Middle row: large clock - Bottom row: date, fuel price, exchange rate - Joystick menu for user-selectable configuration: - City preset - Fuel type - FX pair - Manual refresh - BLE HID on/off - NVS persistence for menu choices. - Optional Wi-Fi and HTTP data fetch. - Offline/demo-safe behavior when Wi-Fi or API URLs are not configured. ## Hardware Assumptions The current pinout is defined in `main/driver/lcd/st7735.h` and `main/driver/input/joystick.h`. LCD: | Signal | GPIO | | --- | --- | | MOSI | GPIO3 | | SCK | GPIO2 | | CS | GPIO7 | | DC | GPIO6 | | RST | GPIO10 | | BL | GPIO11 | Joystick: | Direction | GPIO | | --- | --- | | UP | GPIO8 | | DOWN | GPIO13 | | LEFT | GPIO5 | | RIGHT | GPIO9 | | CENTER | GPIO4 | The LCD SPI clock is intentionally set to 10 MHz for cold-start stability. ## Controls Desktop mode: | Action | Behavior | | --- | --- | | UP | No action | | DOWN | No action | | RIGHT | Open menu | | CENTER | Open menu | Menu mode: | Action | Behavior | | --- | --- | | UP | Previous item | | DOWN | Next item | | RIGHT | Enter/run selected item | | LEFT | Back to root when inside submenu | The menu currently uses immediate commands. For example, selecting `City` cycles through the city presets and saves the choice to NVS. Wi-Fi setup: | Stage | Controls | | --- | --- | | Menu | Select `WiFi`, then press RIGHT | | SSID scan | UP/DOWN selects a scanned SSID, CENTER confirms, RIGHT rescans, LEFT exits | | Password | RIGHT switches between letter/number/symbol columns | | Password | UP/DOWN rotates the active column, CENTER picks the shown character | | Password | Select `OK` in the symbol column to save, or `DEL` to delete one character | Saved Wi-Fi credentials are stored in NVS and override the compile-time defaults on the next boot. ## Build Use the ESP-IDF environment already configured for this workspace: ```sh export IDF_PYTHON_ENV_PATH=/Users/pan/.espressif/python_env/idf5.5_py3.13_env source /Users/pan/.espressif/v5.5.3/esp-idf/export.sh idf.py build ``` Current verified build result: - App binary size: about `0x1c9060` - App partition size: `0x300000` - Free app partition space: about 40% Flash: ```sh idf.py -p /dev/cu.usbmodemXXXX flash monitor ``` ## Wi-Fi Configuration Wi-Fi is configured at compile time in `main/app/app_config.h`. ```c #define DESK_WIFI_SSID "YourSSID" #define DESK_WIFI_PASSWORD "YourPassword" ``` If `DESK_WIFI_SSID` is empty, Wi-Fi is disabled and the ornament runs in offline mode. Reason for compile-time Wi-Fi in the first version: entering SSID/password with a 5-way joystick on a 160x80 screen is cumbersome and error-prone. A future version can add BLE provisioning, SmartConfig, serial provisioning, or a temporary AP portal. ## Time Configuration Time is synchronized using SNTP. ```c #define DESK_TIMEZONE "CST-8" #define DESK_NTP_SERVER "pool.ntp.org" ``` `CST-8` is POSIX timezone syntax for UTC+8. ## HTTP API Configuration External data APIs are optional and configurable in `main/app/app_config.h`. Weather uses a built-in city coordinate table in `main/service/desk/desk_config.c`. The menu stores the selected city index in NVS, and the firmware generates the Open-Meteo URL from latitude/longitude at runtime. The default city is Shenzhen. Fuel URL: ```c #define DESK_FUEL_URL "" ``` FX URLs: ```c #define DESK_FX_URL_USD_CNY "" #define DESK_FX_URL_HKD_CNY "" #define DESK_FX_URL_JPY_CNY "" #define DESK_FX_URL_EUR_CNY "" ``` The parser is intentionally small and expects simple JSON fields. Weather supports Open-Meteo `current=temperature_2m,relative_humidity_2m,weather_code` responses. It also supports compact normalized fields: ```json { "city": "Shanghai", "text": "Cloudy", "temp": 22, "humidity": 65 } ``` Fuel response fields: ```json { "p92": 7.82, "p95": 8.33, "p98": 9.13, "diesel": 7.48 } ``` FX response fields: ```json { "rate": 7.23 } ``` Using a small normalization endpoint is recommended. For example, a tiny cloud function can call any provider you like and return the compact JSON above. This keeps the ESP32 firmware independent of provider-specific schemas and reduces RAM usage. ## Resource Notes Flash is sufficient. The bigger constraint is RAM once Wi-Fi, TLS, HTTP, LVGL, and BLE are all enabled. Current design choices to stay within resource limits: - BLE HID defaults to off. - HTTP requests are sequential, never concurrent. - Response buffer is fixed at 1024 bytes. - No full JSON library is used. - UI uses simple labels and no large images. - Network refresh interval defaults to 30 minutes. If HTTPS endpoints cause memory pressure, prefer a trusted local HTTP gateway or a compact proxy service on the LAN/cloud. ## Important Files | File | Purpose | | --- | --- | | `main/app/main.c` | Main app flow, UI scheduling, joystick routing | | `main/app/app_config.h` | Wi-Fi, timezone, and API URL configuration | | `main/service/desk/desk_config.*` | Persistent user configuration | | `main/service/desk/desk_data.*` | Display data model | | `main/service/desk/desk_fetch.*` | HTTP fetch and compact JSON extraction | | `main/service/net/wifi_manager.*` | Wi-Fi STA connection, scanning, and saved credentials | | `main/service/net/time_service.*` | SNTP setup | | `main/ui/display/ui_display.*` | LVGL menu and fixed desktop dashboard | | `main/ui/menu/menu.*` | Joystick menu model | | `main/driver/lcd/*` | ST7735 and LVGL display driver | ## Next Improvements - Add dynamic menu labels with current values. - Add brightness control with PWM instead of binary backlight. - Add provider-specific adapters for chosen weather, fuel, and FX APIs. - Add NVS cache for the last successful network payload. - Add a local web configuration page.