ESP32-S3 蓝牙音箱桌面摆件 · 新手落地手册
本方案适用于你手上全部硬件:ESP32-S3 SuperMini(N8R8)+ ST7735 1.3" 240×240 IPS 屏 + PCM5102 I2S 解码 + PAM8403 功放 + 喇叭 + WS2812 灯 + MPU6050 陀螺仪 + TTP223 触摸键 + TP4056 锂电池供电。 蓝牙音箱、屏幕、摇晃切歌、触摸控制、律动灯、电池便携,一个都不少。
目录
- 硬件全家福与角色分工
- 新手十条铁律
- 物料清单(你已有 + 还需要)
- ESP32-S3 引脚图与功能分配
- 接线总表
- 七步闯关路线图
- 分步详解
- 附录:测试代码(8 段)
- 故障快速定位表
- 成品结构与布线工艺
硬件全家福
| 模块 | 角色 | 一句话说明 |
|---|---|---|
| ESP32-S3 SuperMini (N8R8) | 大脑 | 8MB Flash + 8MB PSRAM,支持经典蓝牙 A2DP,蓝牙音箱的核心 |
| ST7735 1.3" 240×240 IPS | 眼睛 | 显示歌名、时钟、律动动画(标题写 ST7735,内核多为 ST7789V,两种驱动都备好) |
| PCM5102 I2S 解码板 | 翻译官 | 把蓝牙数字音频转成模拟信号(无 MCLK 版本最佳) |
| PAM8403 功放 | 扩音器 | 把模拟信号放大推给喇叭 |
| 喇叭 4Ω/8Ω 3W ×2 | 嘴 | 发声 |
| WS2812 灯珠 | 气氛组 | 音乐律动灯 |
| GY-521 MPU6050 | 体感 | 摇一摇切歌、姿态控制 |
| TTP223 触摸键 ×2 | 遥控 | 播放/暂停、切歌/模式 |
| TP4056 + 锂电池 | 心脏 | 离线供电,可拔线便携使用 |
为什么用 S3 而不是 C3? S3 自带经典蓝牙,手机直接连就能 A2DP 放歌(C3 只有 BLE 做不了),而且 8MB PSRAM 够跑歌词滚动和桌宠动画。
新手十条铁律
- 分步焊接,分步测试。 每步过关再焊下一步,出问题才能快速定位。
- 不要用纯充电线烧录。 充电线没有数据芯,电脑识别不到板子,一定用带数据功能的 USB-C 线。
- 所有 GND 全部共地。 主控、屏幕、功放、灯、传感器、触摸、电池板的地线拧成一股,这是底噪干净的命根子。
- 上电前先量电压。 万用表量 5V/3.3V/GND 有没有短路,再插电。电池接反一次就废。
- 漆包线必须刮漆再上锡。 刮 5~8mm 露出亮铜,先镀锡再焊,否则虚焊查到你崩溃。
- 模拟音频线 ≤2cm。 PCM5102 到 PAM8403 的 L/R/GND 越短越干净,长了就有滋滋声。
- 软件音量锁 70%。 PAM8403 拧满会破音失真,锁在 70% 以内。
- 烧录前检查 Arduino IDE 四项设置:开发板
ESP32S3 Dev Module、USB CDC On Boot: Enabled、Flash 8MB、PSRAM: OPI PSRAM。四项全对,否则要么串口空白、要么一跑就崩。 - 电池只接 5V 引脚。 TP4056 输出接 S3 的 5V(板载 LDO 稳压到 3.3V),不要同时接 3.3V。想让功率足,建议加 5V 升压模块(见步骤 0)。
- 锂电池远离功放。 PAM8403 发热,别贴电池,防鼓包。
物料清单
你已经有的 ✅
| 物料 | 数量 | 备注 |
|---|---|---|
| ESP32-S3 SuperMini(N8R8) | 1 | 8MB Flash + 8MB PSRAM |
| ST7735 1.3" 240×240 IPS 屏 | 1 | 也可能是 ST7789V 内核 |
| GY-521 MPU6050 | 1 | I2C 地址 0x68 |
| TTP223 触摸按钮 | 2~5 颗 | 用 2 颗即可 |
| TP4056 Type-C 充电+保护板 | 1 | 输出是电池电压 3.0~4.2V |
| 锂电池 3.7V | 1 | 建议 500~1500mAh |
还需要(音频链路)
| 物料 | 数量 | 说明 |
|---|---|---|
| PCM5102 I2S 解码板(无 MCLK) | 1 | 蓝牙数字→模拟 |
| PAM8403 双声道功放 | 1 | 必买 |
| 喇叭 4~8Ω 3W | 2 | 2 寸以内 |
| WS2812 灯珠/灯环 | 1~3 | 律动灯 |
| USB-C 数据线 + 5V≥2A 充电头 | 1 套 | 烧录 + 充电 |
强烈建议加购(小钱解决大坑)
| 物料 | 数量 | 说明 |
|---|---|---|
| 5V 升压小板(TP4056+升压一体板或 MT3608) | 1 | 让电池供电时也是稳定 5V,音量大不喘 |
| 100Ω 电阻 | 2 | WS2812 信号线抗干扰 |
| 4.7kΩ 电阻 | 2 | I2C 上拉备用 |
| 漆包线、助焊剂、热缩管 | 若干 | 耗材 |
S3 引脚分配
ESP32-S3 SuperMini 可用的 GPIO 很多,本方案只用了 13 个,全部避开板载 RGB LED(GPIO8)和下载按键(GPIO0)。
引脚分配表(唯一正确答案,照抄)
| 功能 | S3 引脚 | 备注 |
|---|---|---|
| I2S BCK(音频位时钟) | GPIO4 | → PCM5102 BCK |
| I2S LRCK(声道时钟) | GPIO5 | → PCM5102 LRCK |
| I2S DIN(音频数据) | GPIO6 | → PCM5102 DIN |
| SPI SCK(屏幕时钟) | GPIO10 | → 屏幕 SCK |
| SPI MOSI(屏幕数据) | GPIO11 | → 屏幕 MOSI |
| SPI CS(屏幕片选) | GPIO12 | → 屏幕 CS |
| SPI DC(数据/命令) | GPIO13 | → 屏幕 DC |
| SPI RST(屏幕复位) | GPIO14 | → 屏幕 RST |
| WS2812 数据 | GPIO16 | → 灯珠 DATA |
| 触摸键 1(播放/暂停) | GPIO17 | → TTP223#1 OUT |
| 触摸键 2(切歌/模式) | GPIO18 | → TTP223#2 OUT |
| I2C SDA(MPU6050) | GPIO2 | 软件 I2C,避开板载灯 |
| I2C SCL(MPU6050) | GPIO3 | 软件 I2C |
⚠️ 为什么 MPU6050 不用默认的 GPIO8/9? S3 SuperMini 板载 RGB LED 焊在 GPIO8 上,拿去做 I2C 会导致灯乱闪、传感器不稳定。用 GPIO2/3 做软件 I2C 最干净。代码里写
Wire.begin(2, 3)。
接线总表
① 电源系统(TP4056 + 电池 + 升压)
推荐接法(加 5V 升压):
| 连线 | 目标 |
|---|---|
| 锂电池 B+ / B− | TP4056 的 B+ / B−(正负千万别反) |
| TP4056 OUT+ / OUT− | 5V 升压板 IN+ / IN− |
| 升压板 OUT+ / OUT− | 系统 5V 总线 / GND 总线 |
| USB-C 数据线 | TP4056 充电口(充电时红灯亮) |
极简接法(不加升压,先跑通再说):
| 连线 | 目标 |
|---|---|
| TP4056 OUT+ | ESP32-S3 的 5V 引脚 |
| TP4056 OUT− | 系统 GND |
极简接法下电池电压 3.7~4.2V 也能让 S3 和 PAM8403 工作,只是大音量时功率打折。调试期建议直接插 USB 供电,电池最后再加。
② ESP32-S3 → PCM5102(I2S 数字音频)
| S3 | PCM5102 |
|---|---|
| GPIO4 | BCK |
| GPIO5 | LRCK |
| GPIO6 | DIN |
| 3.3V | VIN |
| GND | GND |
| — | SCK → GND(无 MCLK) |
| — | FMT → GND(I2S 格式) |
| — | FLT → GND(正常滤波) |
| — | XSMT → 3.3V(解除静音,这脚悬空会无声!) |
③ PCM5102 → PAM8403 → 喇叭(模拟音频)
| PCM5102 | PAM8403 |
|---|---|
| LOUT | L-IN |
| ROUT | R-IN |
| GND | GND(≤2cm 短接) |
| — | PAM8403 VCC → 5V |
| — | PAM8403 GND → GND |
| — | L-OUT/R-OUT → 左/右喇叭 |
④ ESP32-S3 → ST7735 屏幕
| S3 | 屏幕 |
|---|---|
| GPIO10 | SCK |
| GPIO11 | MOSI |
| GPIO12 | CS |
| GPIO13 | DC |
| GPIO14 | RST |
| 3.3V | VCC |
| GND | GND |
| (背光 BLK 若有) | 接 3.3V(常亮) |
⑤ ESP32-S3 → WS2812
| S3 | WS2812 |
|---|---|
| GPIO16 | DATA(串 100Ω 电阻抗干扰) |
| 5V | 5V |
| GND | GND |
⑥ ESP32-S3 → MPU6050
| S3 | MPU6050 |
|---|---|
| GPIO2 | SDA |
| GPIO3 | SCL |
| 3.3V | VCC |
| GND | GND |
⑦ ESP32-S3 → TTP223 触摸
| S3 | TTP223 |
|---|---|
| GPIO17 | OUT(键1:播放/暂停) |
| GPIO18 | OUT(键2:切歌/模式) |
| 3.3V | VCC |
| GND | GND |
TTP223 默认未触摸输出高电平、触摸输出低电平,代码按低电平有效写。
七步闯关路线图
步骤0 步骤1 步骤2 步骤3 步骤4 步骤5 步骤6
电池/供电 → 主控上电 → 屏幕点亮 → 蓝牙出声 → 功放喇叭 → 灯+传感器+触摸 → 整机联调
(TP4056) (能烧程序) (TFT_eSPI) (A2DP放歌) (底噪干净) (各自响应) (互不干扰)
| 步骤 | 焊什么 | ✅ 过关标准 |
|---|---|---|
| 0 | TP4056 + 电池 + 供电 | 插 USB 能充电,拔 USB 电池能开机 |
| 1 | 只焊 S3(其他不动) | 串口能打印、能复位 |
| 2 | + ST7735 屏幕 | 显示彩色图形,无花屏 |
| 3 | + PCM5102 + 蓝牙 | 手机连上蓝牙,喇叭/耳机能放出手机里的歌 |
| 4 | + PAM8403 + 喇叭 | 静态底噪干净,双声道正常 |
| 5 | + WS2812、MPU6050、TTP223 | 灯会亮、晃动有数据、触摸有响应 |
| 6 | 整机同时上电 | 屏幕/灯/传感器全开时底噪不明显变差 |
分步详解
步骤 0:电源系统(先搞定供电,后面才不焦虑)
焊接内容:锂电池 → TP4056 B+/B−(注意正负)→ 升压板 → 5V/GND 总线。
测试 0-1:量电压
- 未插 USB:电池两端 3.5~4.2V 正常;低于 3.0V 先充电。
- 插充电头:TP4056 输入脚约 5V,充电红灯亮。
测试 0-2:电池开机
- 拔掉 USB,只接电池,S3 电源灯应亮起。
- 不亮就检查:OUT+ 是不是接到了 S3 的 5V(不是 3.3V)。
⚠️ 锂电池安全:不接反、不短路、不放高温处。首次上电前先串一个 1A 保险丝或 0Ω 电阻当「开关」,方便随时断开排查。
步骤 1:只焊 S3 主控,其他一律不焊
烧录代码①。过关:串口持续打印,按 RST 能复位。
Arduino IDE 关键设置(90% 新手在这里翻车):
- 开发板管理器安装 esp32 by Espressif(2.0.14+)
- 开发板选
ESP32S3 Dev Module - USB CDC On Boot → Enabled(否则串口一片空白!)
- Flash Size → 8MB
- PSRAM → OPI PSRAM(不选会内存不足崩溃)
- 分区方案选 8MB with spiffs(跑完整固件够用)
- 烧录时波特率 921600 会更快,失败就降到 115200
步骤 2:焊接 ST7735 屏幕
焊接内容:GPIO10/11/12/13/14 → SCK/MOSI/CS/DC/RST,3.3V、GND。
测试:改 TFT_eSPI 的 User_Setup.h,烧录 graphictest 示例。
先试 ST7789 驱动(1.3" 240×240 IPS 多数是这个内核):
#define ST7789_DRIVER
#define TFT_WIDTH 240
#define TFT_HEIGHT 240
#define TFT_MOSI 11
#define TFT_SCLK 10
#define TFT_CS 12
#define TFT_DC 13
#define TFT_RST 14
#define SPI_FREQUENCY 40000000
颜色反了加 #define TFT_INVERSION_ON;点不亮就换成 ST7735 驱动:
#define ST7735_DRIVER
#define TFT_WIDTH 240
#define TFT_HEIGHT 240
#define INIT_SEQUENCE_3
过关:屏幕点亮、显示彩色图形、无花屏。
步骤 3:蓝牙 + PCM5102(本方案灵魂)
焊接内容:GPIO4/5/6 → PCM5102 BCK/LRCK/DIN,XSMT→3.3V,FMT/FLT/SCK→GND,PCM5102 输出接耳机先试听。
测试:
- 先烧代码②确认 I2S 通路(能听到 1kHz 蜂鸣)。
- 再烧代码⑦(ESP32-A2DP 库,Arduino 库管理器搜 ESP32-A2DP 安装)。
- 手机开蓝牙,搜索并连接名为 "S3-BT-Speaker" 的设备。
- 手机放歌,喇叭/耳机出声。
过关:手机能连、能放歌、无爆音。
蓝牙连不上?先确认板子型号是 S3(C3 没有经典蓝牙);再确认代码里库版本用的是 pschatzmann/ESP32-A2DP。
步骤 4:焊接 PAM8403 + 喇叭
焊接内容:PCM5102 LOUT/ROUT/GND → PAM8403 L-IN/R-IN/GND(≤2cm),PAM8403 5V/GND,喇叭接 L-OUT/R-OUT。
底噪测试:不播放时耳朵贴喇叭,几乎无沙沙声为过关。有嗡嗡声 → 查共地(见故障表)。
过关:播放音乐双声道干净,暂停时安静。
步骤 5:灯 + 传感器 + 触摸
过关:三项各自正常。
步骤 6:整机联调
全部模块同时上电:开屏幕、开灯、开传感器,听喇叭底噪是否变差。
- 底噪变差 → 优先强化共地,再给 WS2812 DATA 串 100Ω。
- 蓝牙偶尔断 → 检查电池供电是否够(大音量瞬间拉电流),建议上 5V 升压。
- 摇晃切歌 → 完整固件代码⑧里已含姿态逻辑。
过关:手机放歌、屏幕显示、触摸切歌、摇晃换曲、灯随音乐呼吸,电池模式下同样稳定。
附录:测试代码
代码①:S3 串口自检
void setup() {
Serial.begin(115200);
Serial.println("ESP32-S3 启动成功!");
}
void loop() {
Serial.println("Hello ESP32-S3!");
delay(1000);
}
代码②:I2S 正弦波测试音
#include <I2S.h>
const int PIN_BCK = 4; // -> PCM5102 BCK
const int PIN_LRCK = 5; // -> PCM5102 LRCK
const int PIN_DIN = 6; // -> PCM5102 DIN
const int RATE = 48000;
const int FREQ = 1000;
const float AMPLITUDE = 11000;
const int N = RATE / FREQ;
int16_t buf[N * 2];
void setup() {
Serial.begin(115200);
I2S.setPins(PIN_BCK, PIN_LRCK, PIN_DIN);
if (!I2S.begin(I2S_MODE_STD, RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO)) {
Serial.println("I2S 初始化失败!");
while (1) delay(1000);
}
for (int i = 0; i < N; i++) {
int16_t s = (int16_t)(AMPLITUDE * sinf(2.0f * PI * i / N));
buf[2 * i] = s;
buf[2 * i + 1] = s;
}
}
void loop() {
I2S.write((uint8_t *)buf, sizeof(buf));
}
代码③:屏幕配置(TFT_eSPI → User_Setup.h)
// 先试 ST7789 驱动:
#define ST7789_DRIVER
#define TFT_WIDTH 240
#define TFT_HEIGHT 240
#define TFT_MOSI 11
#define TFT_SCLK 10
#define TFT_CS 12
#define TFT_DC 13
#define TFT_RST 14
#define SPI_FREQUENCY 40000000
// 颜色反了加:#define TFT_INVERSION_ON
// 点不亮换成:#define ST7735_DRIVER + #define INIT_SEQUENCE_3
烧录示例:文件 → 示例 → TFT_eSPI → 通用 → graphictest。
代码④:WS2812 红绿蓝循环
#include <Adafruit_NeoPixel.h>
#define LED_PIN 16
#define LED_COUNT 3
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.setBrightness(120);
}
void loop() {
strip.setPixelColor(0, strip.Color(255, 0, 0));
strip.setPixelColor(1, strip.Color(0, 255, 0));
strip.setPixelColor(2, strip.Color(0, 0, 255));
strip.show(); delay(1000);
strip.clear(); strip.show(); delay(500);
}
代码⑤:MPU6050 姿态读取
#include <Wire.h>
const int MPU_ADDR = 0x68;
void setup() {
Serial.begin(115200);
Wire.begin(2, 3); // SDA=GPIO2, SCL=GPIO3(避开板载灯 GPIO8)
Wire.beginTransmission(MPU_ADDR);
if (Wire.endTransmission() != 0) {
Serial.println("MPU6050 未找到!");
while (1);
}
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B); // 退出睡眠
Wire.write(0);
Wire.endTransmission();
Serial.println("MPU6050 初始化成功");
}
void loop() {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 14);
if (Wire.available() >= 14) {
int16_t ax = (Wire.read() << 8) | Wire.read();
int16_t ay = (Wire.read() << 8) | Wire.read();
int16_t az = (Wire.read() << 8) | Wire.read();
int16_t t = (Wire.read() << 8) | Wire.read();
int16_t gx = (Wire.read() << 8) | Wire.read();
int16_t gy = (Wire.read() << 8) | Wire.read();
int16_t gz = (Wire.read() << 8) | Wire.read();
Serial.printf("accel:%6d %6d %6d | gyro:%6d %6d %6d\n", ax, ay, az, gx, gy, gz);
}
delay(200);
}
代码⑥:TTP223 触摸检测
const int BTN_1 = 17; // 播放/暂停
const int BTN_2 = 18; // 切歌/模式
void setup() {
Serial.begin(115200);
pinMode(BTN_1, INPUT);
pinMode(BTN_2, INPUT);
}
void loop() {
bool t1 = digitalRead(BTN_1) == LOW; // 触摸输出低电平
bool t2 = digitalRead(BTN_2) == LOW;
if (t1 || t2) {
Serial.printf("BTN1=%d BTN2=%d\n", t1, t2);
delay(200);
}
}
代码⑦:蓝牙 A2DP 播放(核心)
// 库:Arduino 库管理器搜索 "ESP32-A2DP"(作者 pschatzmann)并安装
#include "BluetoothA2DPSink.h"
BluetoothA2DPSink a2dp_sink;
// ESP32-S3 的 I2S 引脚
#define PIN_I2S_BCK 4
#define PIN_I2S_LRCK 5
#define PIN_I2S_DIN 6
void setup() {
Serial.begin(115200);
i2s_pin_config_t pin_config = {
.bck_io_num = PIN_I2S_BCK,
.ws_io_num = PIN_I2S_LRCK,
.data_out_num = PIN_I2S_DIN,
.data_in_num = I2S_PIN_NO_CHANGE
};
a2dp_sink.set_pin_config(pin_config);
a2dp_sink.start("S3-BT-Speaker"); // 蓝牙名称
Serial.println("蓝牙音箱已启动,用手机搜索连接");
}
void loop() {
delay(1000);
}
手机连上后放歌即出声。如果声音断续,把波特率/其他外设的串口打印关掉,给音频让路。
代码⑧:完整固件示例(蓝牙 + 屏幕 + 灯 + 触摸 + 摇晃)
这是一个「最小可用」骨架:蓝牙放歌 + 屏幕显示状态 + 触摸切歌/暂停 + 摇一摇切歌 + 灯呼吸。照抄即可跑,注释处按需扩展。
#include "BluetoothA2DPSink.h"
#include <TFT_eSPI.h>
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
// ===== 引脚 =====
#define PIN_I2S_BCK 4
#define PIN_I2S_LRCK 5
#define PIN_I2S_DIN 6
#define LED_PIN 16
#define LED_COUNT 3
#define BTN_PLAY 17
#define BTN_NEXT 18
#define MPU_SDA 2
#define MPU_SCL 3
#define MPU_ADDR 0x68
BluetoothA2DPSink a2dp_sink;
TFT_eSPI tft = TFT_eSPI();
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// MPU6050 读数
int16_t ax, ay, az, gx, gy, gz;
bool mpuOk = false;
void readMPU() {
if (!mpuOk) return;
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 14);
if (Wire.available() >= 14) {
ax = (Wire.read() << 8) | Wire.read();
ay = (Wire.read() << 8) | Wire.read();
az = (Wire.read() << 8) | Wire.read();
Wire.read(); Wire.read(); // 温度
gx = (Wire.read() << 8) | Wire.read();
gy = (Wire.read() << 8) | Wire.read();
gz = (Wire.read() << 8) | Wire.read();
}
}
void setup() {
Serial.begin(115200);
pinMode(BTN_PLAY, INPUT);
pinMode(BTN_NEXT, INPUT);
// 屏幕
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE);
tft.drawString("BT Speaker Ready", 20, 100, 2);
// 灯
strip.begin();
strip.setBrightness(60);
// MPU6050
Wire.begin(MPU_SDA, MPU_SCL);
Wire.beginTransmission(MPU_ADDR);
mpuOk = (Wire.endTransmission() == 0);
if (mpuOk) {
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B); Wire.write(0);
Wire.endTransmission();
}
// 蓝牙
i2s_pin_config_t pin_config = {
.bck_io_num = PIN_I2S_BCK,
.ws_io_num = PIN_I2S_LRCK,
.data_out_num = PIN_I2S_DIN,
.data_in_num = I2S_PIN_NO_CHANGE
};
a2dp_sink.set_pin_config(pin_config);
a2dp_sink.start("S3-BT-Speaker");
}
unsigned long lastShakeCheck = 0;
int hue = 0;
void loop() {
readMPU();
// 触摸 1:播放/暂停
if (digitalRead(BTN_PLAY) == LOW) {
a2dp_sink.toggle();
tft.fillScreen(TFT_BLACK);
tft.drawString(a2dp_sink.is_connected() ? "Playing" : "Paused", 20, 100, 2);
delay(300);
}
// 触摸 2:切歌
if (digitalRead(BTN_NEXT) == LOW) {
a2dp_sink.next();
delay(300);
}
// 摇一摇切歌(检测 X 轴加速度突变)
if (millis() - lastShakeCheck > 500) {
lastShakeCheck = millis();
if (mpuOk && abs(ax) > 12000) {
a2dp_sink.next();
tft.fillScreen(TFT_BLACK);
tft.drawString("Shake -> Next", 20, 100, 2);
}
}
// 灯呼吸
strip.fill(strip.ColorHSV(hue * 256, 255, 40));
strip.show();
hue = (hue + 1) % 360;
delay(10);
}
故障快速定位表
| 现象 | 优先排查点 |
|---|---|
| 电脑识别不到板子 | 换带数据功能的 USB-C 线;按住 BOOT 再按 RST 进下载模式 |
| 串口一片空白 | IDE 里 USB CDC On Boot: Enabled;波特率 115200 |
| 一编译就报内存不足 | 开发板没选对:必须是 ESP32S3 Dev Module + OPI PSRAM |
| 屏幕花屏/不亮 | SPI 四线虚焊;先试 ST7789_DRIVER 再试 ST7735_DRIVER;颜色反加 TFT_INVERSION_ON |
| 蓝牙搜不到 | 确认板子是 S3(C3 没有经典蓝牙);拔掉后重新上电;删除手机里旧配对 |
| 蓝牙能连但没声 | PCM5102 的 XSMT 必须接 3.3V(悬空=静音);I2S 三线是否接对 |
| 喇叭嗡嗡/滋滋 | GND 没全通共地;模拟音频线 >2cm;PAM8403 音量锁 70% |
| 声音断续卡顿 | 关掉无关串口打印;电池供电不足 → 加 5V 升压;降低 WiFi 占用 |
| MPU6050 找不到 | SDA/SCL 是否接对(GPIO2/3);GY-521 上拉是否脱落;地址 0x68 |
| 触摸无反应 | TTP223 默认输出高电平、触摸低电平;VCC 是否接上;跳线极性 |
| 充电灯不亮 | 充电头是否 5V;TP4056 输入虚焊;电池接反 |
| 电池供电不开机 | OUT+ 要接 S3 的 5V(不是 3.3V);电池过放先充电 |
成品结构与布线工艺
- 电源布局:TP4056 靠 USB-C 口,电池放底座下层,远离 PAM8403。
- 公共地线:一根粗铜线做地总线,S3、PAM8403、屏幕、灯、传感器、触摸、电池板全部 GND 焊上去——这是底噪干净的命根子。
- 模拟音频线:PCM5102 → PAM8403 的 L/R/GND ≤2cm,热缩管包住。
- 数字线:I2S/SPI/I2C/灯珠线用漆包线,刮漆拉直,焊点热缩管。
- 垫高走线:M2 铜柱垫高主板,底座内走线,外壳只露 USB-C 和喇叭孔。
- 散热:PAM8403 别贴电池和塑料外壳。
- 总开关:电池正极串一个拨动开关,彻底断电省电。
固件功能规划(最终形态)
- 蓝牙:手机 A2DP 连接 → PCM5102 → PAM8403 → 喇叭,S3 全程解码
- 屏幕:歌名 + 时钟 + 律动动画(PSRAM 够用,可以上 LVGL 或 TFT_eSPI)
- 触摸键:短按播放/暂停,长按切模式(蓝牙/时钟/灯效)
- 摇晃:摇一摇切歌、旋转自适应屏幕方向
- 灯:随音乐律动呼吸,充电时橙色,低电量红色闪烁
- 电池:TP4056 充电管理,满电绿灯、充电红灯
评论0
暂时没有评论