# esp32-s3-2.16 **Repository Path**: LMLM8090/esp32-s3-2.16 ## Basic Information - **Project Name**: esp32-s3-2.16 - **Description**: 2.16版本测试,私有 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-10-12 - **Last Updated**: 2026-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ESP32-S3 Touch AMOLED 2.16 — PC Monitor + Audio Spectrum + 1024 Game + Calendar 基于 **ESP32-S3-Touch-AMOLED-2.16** 开发板的桌面小工具,通过 BLE 接收 Mac/PC 系统数据并在 480x480 AMOLED 圆形触摸屏上实时显示。 ## 功能特性 - **代码雨页面**:Matrix 风格数字/字母代码雨动画(40×30 网格,头部白绿→尾部暗绿渐变),Arduino_GFX 全帧离屏 canvas + PSRAM 缓冲 + 增量绘制(整帧一次性推屏,约 60fps) - **PC 监控页面**:CPU / 内存 / 磁盘 / 温度 / 网络速度,LVGL 进度条 + 电池图标(百分比 + 充电扫描动画) - **音频频谱页面**:60 频段圆形 FFT 频谱可视化,圆心位于屏幕正中心,整体顺时针旋转 180°,无频率刻度文字,实时柱状图动画(含自适应增益 AGC) - **心率页面**:通过 BLE 连接小米手环 9 Pro,实时显示 BPM 大字、心率区间彩条、MIN/MAX/AVG 统计 - **1024 游戏页面**:经典 1024 数字合并游戏,IMU 倾斜-释放手势控制(板子向哪边翻转,方块往哪边滑),120ms 滑动/合并动画,标准配色 - **日历页面**:时钟 / 日期 / 日历网格(今日高亮)+ 手动设时弹窗,顶部显示 WiFi 状态与时间来源 - **WiFi 配网 + NTP 校时**:AP 热点 `ESP32-S3-Config` + Captive Portal 网页配网(192.168.4.1),连接成功后自动 NTP 同步时间 - **RTC 掉电保持**:PCF85063A 实时时钟(I2C 0x51),断网断电后仍能保持时间 - **触摸翻页**:左右滑动切换六个页面(代码雨 → 监控 → 频谱 → 游戏 → 心率 → 日历) - **IMU 控制**:QMI8658 加速度计倾斜检测控制游戏方块移动 - **电源管理**:AXP2101 PMU 电池电量/温度监控,短按电源键亮屏/熄屏,长按 3 秒关机 - **低功耗模式**:短按熄屏后自动进入 Light Sleep——挂起音频、停止 BLE/WiFi/心率扫描、关闭音频 IC 供电,200ms 定时唤醒轮询按键,任意按键唤醒恢复全部外设 - **BLE 无线传输**:电脑端 Python 脚本通过 BLE 推送系统数据;心率页另作 BLE Client 连接手环 - **上电防闪屏**:启动时先黑屏再亮,消除 AMOLED 上电闪一下的问题 ## 硬件需求 | 组件 | 说明 | |------|------| | ESP32-S3-Touch-AMOLED-2.16 | 主开发板(480x480 AMOLED + CST92xx 触摸 + AXP2101 PMU + QMI8658 IMU) | | ES7210 ADC | 板载 4 通道 24-bit 音频 ADC(I2C 地址 0x40) | | ES8311 DAC | 板载音频 DAC(I2C 地址 0x18) | | QMI8658 IMU | 板载 6 轴 IMU(I2C 地址 0x6B),用于 1024 游戏倾斜控制 | | PCF85063A RTC | 实时时钟(I2C 地址 0x51),掉电保持时间 | | 小米手环 9 Pro | 心率数据源(BLE Client 连接,广播名含 "BAND 9",心率服务 UUID 180d / 特征 2a37) | | 麦克风 | 连接 ES7210 的模拟输入 | ## 快速开始 ### 1. 烧录固件 使用 Arduino IDE 打开 `esp32-s3-2.16.ino`,选择开发板 **ESP32-S3**,烧录即可。 所需 Arduino 库: - [Arduino_GFX](https://github.com/moononournation/Arduino_GFX) — CO5300 AMOLED 驱动 - [LVGL](https://lvgl.io/) v8.4 — UI 框架 - [XPowersLib](https://github.com/lewisxhe/XPowersLib) — AXP2101 电源管理 - [SensorLib](https://github.com/lewisxhe/SensorLib) — QMI8658 IMU 驱动 - ESP32 BLE Arduino — 内置 BLE 库 ### 2. 运行 Mac 监控脚本 ```bash # 一键启动(自动创建虚拟环境、安装依赖) chmod +x run_monitor.sh ./run_monitor.sh # 或手动运行 python3 -m venv ~/bleak-env source ~/bleak-env/bin/activate pip install psutil bleak python3 mac_monitor.py ``` 脚本会自动扫描 BLE 设备 `ESP32-S3-PC`,连接后每秒推送一次系统数据。 Intel Mac 用户可直接使用 `packaging/` 打包的一键安装包(`PC Monitor.dmg`),无需安装 Python 环境。 ### 3. 使用 - 开机后自动进入 **代码雨页面** - 手机/电脑端 BLE 连接后监控页数据开始刷新 - **左右滑动** 切换页面:代码雨 → 监控 → 频谱 → 1024 游戏 → 心率 → 日历 - **心率页面**:切到该页后设备停止 PC 广播、开始扫描并连接小米手环,稳定显示实时心率;离开心率页时释放连接、恢复 PC 广播(广播与扫描按页面互斥,避免 BLE 崩溃) - **1024 游戏**:倾斜设备后回正(倾斜-释放手势)控制方块移动,板子向哪边翻转方块往哪边滑,合并相同数字,目标达到 1024;方块滑动与合并带 120ms 动画 - **WiFi 配网**:手机连接热点 `ESP32-S3-Config`(密码 `12345678`)→ 浏览器打开 `192.168.4.1` → 选择自家 WiFi 并输入密码 → 设备自动连接并 NTP 校时,凭据保存在 NVS 重启不丢 - **日历页面**:显示时钟 / 日期 / 日历与 WiFi 状态;点 **Set Time** 弹窗手动设时(时间自动写入 RTC,断电保持);时间源优先级:NTP > BLE > RTC > 默认 2026-01-01 - **短按电源键** 熄屏并进入低功耗模式(任意按键唤醒) - **长按电源键 3 秒** 关机(熄屏状态下任意按键唤醒) ## 文件结构 ``` esp32-s3-2.16/ ├── esp32-s3-2.16.ino # 主入口(setup + loop,六页面分发) ├── config.h # 引脚定义、常量配置、游戏/IMU参数 ├── ble_manager.h/.cpp # BLE 服务(Server)、连接管理、PC 数据接收、广播互斥 ├── hr_client.h/.cpp # 心率 BLE Client(连小米手环)、扫描/连接/重连、统计 ├── ui_heartrate.h/.cpp # 心率页面 LVGL UI(BPM 大字、区间条、统计) ├── pmu_manager.h/.cpp # AXP2101 电源管理、电池监控、屏幕开关 ├── audio_codec.h/.cpp # ES7210 + ES8311 寄存器初始化(带错误检测) ├── audio_processor.h/.cpp # I2S、FFT、频谱处理、音频任务 ├── display_driver.h/.cpp # GFX/LVGL 初始化、触摸驱动、频谱绘制 ├── ui_monitor.h/.cpp # PC 监控页面 LVGL UI ├── imu_manager.h/.cpp # QMI8658 IMU 初始化、倾斜方向检测 ├── game_1024.h/.cpp # 1024 游戏逻辑(4×4网格、合并、分数) ├── ui_game.h/.cpp # 1024 游戏 LVGL UI(方块渲染、胜负覆盖层) ├── code_rain.h/.cpp # Matrix 代码雨页面(Arduino_GFX 直接绘制) ├── wifi_manager.h/.cpp # WiFi AP+STA 配网、Captive Portal、NTP 校时、BLE 功率自适应 ├── rtc_manager.h/.cpp # PCF85063A 实时时钟(读写、掉电保持) ├── ui_calendar.h/.cpp # 日历页面 LVGL UI(时钟/日历/手动设时) ├── lv_conf.h # LVGL 配置文件 ├── mac_monitor.py # macOS BLE 监控脚本 ├── run_monitor.sh # 一键启动脚本 ├── packaging/ # macOS 一键安装包(Intel Mac dmg,构建脚本见 packaging/README.md) ├── README.md # 项目说明文档 └── AGENTS.md # 技术架构文档 ``` ## BLE 数据协议 ESP32 作为 BLE GATT Server,Mac 端作为 Client 通过 Write 发送 JSON: ```json {"cpu":12.3,"mem":45.6,"disk":67.8,"net_down":1.234,"net_up":0.567,"temp":52.1} ``` | 字段 | 类型 | 单位 | 说明 | |------|------|------|------| | cpu | float | % | CPU 使用率 | | mem | float | % | 内存使用率 | | disk | float | % | 磁盘使用率 | | net_down | float | MB/s | 网络下载速度 | | net_up | float | MB/s | 网络上传速度 | | temp | float | °C | CPU 表面温度(通过 AppleSMC 读取) | ## 技术细节 - **双核架构**:Core 0 运行音频采集 + FFT,Core 1 运行 LVGL + 显示渲染 - **音频采样率**:24kHz,FFT 窗口 512 点,60 频段对数映射 - **显示**:480x480 RGB565 AMOLED,QSPI 接口;代码雨使用 PSRAM 全帧离屏 canvas + 增量绘制(整帧一次性推屏,约 60fps),圆形频谱使用 Arduino_GFX 直接绘制 - **触摸**:CST92xx 电容触摸,I2C 通信,支持滑动手势翻页(300ms/30px 阈值) - **1024 控制**:QMI8658 IMU 倾斜-释放手势,触发阈值约 0.7g(≈45°),回正后稳定 80ms 才派发一次移动,避免临界抖动误触 - **1024 动画**:方块移动/合并使用 LVGL `lv_anim` 做 120ms 位置 + 透明度插值;每轮动画前先把 16 个 tile 对象吸附回各自格子坐标,避免合并后位置漂移导致方块消失/错位 - **LVGL 时间源**:`esp_timer` 1ms 周期定时器驱动 `lv_tick_inc`,与 `loop()` 解耦,动画更平滑 - **LVGL 内存(PSRAM)**:LVGL 对象堆与渲染缓冲全部走 PSRAM——`LV_MEM_SIZE=128KB` 经 `LV_MEM_POOL_ALLOC` → `lvgl_pool_alloc()`(`heap_caps_malloc(SPIRAM)`)分配,渲染缓冲优先 PSRAM(失败回退 DMA)。曾把 `LV_MEM_SIZE` 降到 16KB 省内存,但 6 页 ~75+ 控件(含日历 42 天格子)创建时触发 `LV_ASSERT_MALLOC` 的 `while(1)` 死锁,表现为启动后黑屏、日志停在 `[Rain] PSRAM canvas OK` - **WiFi + NTP**:AP+STA 双模(AP 先启动),Captive Portal 在 192.168.4.1 配网;`configTime(UTC+8)` 从 `pool.ntp.org` / `ntp.aliyun.com` 校时;WiFi TX 全功率(78 = 19.5dBm),WiFi 连接时 BLE 功率自动降 P3、断开恢复 P9 以抑制 2.4GHz 干扰 - **日历与时间**:日历页时钟 / 日历 / 手动设时,时间自动写入 PCF85063A RTC;时间源优先级 NTP > BLE > RTC > 默认 2026-01-01 - **平滑动画**:频谱柱状图使用上升 0.06 / 下降 0.90 的指数平滑 - **频谱布局**:圆心 (240,240) 精确位于 480×480 屏幕正中心,整体顺时针旋转 180°(`displayInit()` 中柱角度 `+M_PI`);频率数字标签已移除,频谱页只显示圆形频谱 - **频谱 AGC**:归一化基准 `global_peak` 采用慢攻击/慢释放峰值表,稳定反映当前环境音量,不会因历史峰值偏高而越显越小(下限 8.0f 防静音噪点) - **BLE 双角色(Server + Client)**:ESP32 同时作 Server(被 PC 连)和 Client(连手环)。广播与扫描/连接不能稳定并存,故按页面互斥——监控/频谱/游戏页开 PC 广播,心率页关广播开心率扫描;切页带 600ms 防抖,连接前显式停广播,断开时真正 `disconnect()` 释放 client 再重连,规避 `xQueueGenericSend` 断言崩溃 - **上电防闪屏**:`displayInit()` 先 `setBrightness(0)` → 黑屏 → 再 `setBrightness(128)`,消除 AMOLED 上电闪屏 - **BLE 连接**:断开后自动重新广播(仅非心率页),最大功率发射,数据范围验证 - **电源管理**:电池电压/百分比/温度监控,充电状态检测,每 10 秒更新 - **电源控制**:短按 PWR 熄屏 + 进入低功耗模式,长按 3 秒关机,低功耗状态任意按键唤醒恢复,串口记录操作日志 - **低功耗模式**:短按熄屏后自动进入 Light Sleep——`vTaskSuspend` 挂起 Core 0 音频任务,`bleServerStop/wifiStop/setHRPageActive(false)` 停止射频外设,`enterLowPower()` 关闭 ALDO1-4 切断音频 IC 供电 + PA 拉低,`esp_light_sleep_start(200ms)` 定时唤醒轮询 PMU 按键;唤醒时 `exitLowPower()` 恢复 ALDO/PA/亮度 + 全部外设;松键 IRQ 通过 `clearIrqStatus()` + 100ms 去抖抑制;外设轮询已移到 `!screen_on` 检查之后,低功耗期间只运行 `pmuPoll()` - **电池图标**:30x14 紧凑轮廓 + 百分比文字同一行显示,充电时填充条做 ping-pong 扫描动画(2px→24px→2px,每程 1.2 秒),非充电时填充条宽度 = 实际电量对应宽度;仅在监控页面显示 - **错误处理**:所有初始化函数返回成功/失败状态,系统健康检查 - **系统监控**:每 30 秒检查 BLE 连接、电池状态、音频队列 ## License MIT