这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【合宙ESP32C3开发板+Arduino】简易的MP3播放器

共1条 1/1 1 跳转至

【合宙ESP32C3开发板+Arduino】简易的MP3播放器

专家
2026-06-17 15:58:44     打赏

在成功实现播放MP3音乐文件的基础上,加入扫描SD卡的处理,实现自动连续播放的处理效果。实验依旧使用之前的线路。

图片1.png

预先在SD卡中准备多个mp3音乐。

程序代码如下:

#include <SPI.h>
#include <SD.h>
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
#include <vector>

// SD卡模块的SPI引脚
#define SCK_PIN  4
#define MISO_PIN 7
#define MOSI_PIN 6
#define CS_PIN   10

// 连接到MAX98357的I2S引脚
#define BCK_PIN  5   // 位时钟 (MAX98357的BCK)
#define WS_PIN   3   // 字时钟/左右声道选择 (MAX98357的LRC)
#define DATA_PIN 2   // 数据输出 (MAX98357的DIN)

I2SStream i2s; // final output of decoded stream
EncodedAudioStream decoder(&i2s, new MP3DecoderHelix()); // Decoding stream
StreamCopy copier;
File audioFile;

// --- 播放列表(按顺序播放)---
// 创建字符串向量
std::vector<String> playlist;

int playlistSize = 0; // sizeof(playlist) / sizeof(playlist[0]);

int currentIndex = 0;  // 当前播放到第几首
bool isPlaying = false;

// ========== 列出SD卡中的MP3文件 ==========    
void lisMp3Files() {    
    Serial.println("\nSD卡中的MP3文件:");    
       
    File root = SD.open("/");    
    if (!root) {    
        Serial.println("无法打开根目录");    
        return;    
    }    
       
    File file = root.openNextFile();    
    int count = 0;    
       
    while (file) {    
        if (!file.isDirectory()) {    
            String name = file.name();    
            name.toLowerCase();
            if (name.endsWith(".mp3")) {    
                Serial.printf("  - %s (%llu bytes)\n", name.c_str(), file.size());
                playlist.push_back(String("/") + name);    
                count++;    
            }    
        }    
        file = root.openNextFile();    
    }    
       
    if (count == 0) {    
        Serial.println("  没有找到MP3文件");    
        playlistSize = 0;
    } else {
        playlistSize = playlist.size();
    }
       
    root.close();    
} 

void setup(){
  Serial.begin(115200);
  AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);  

  SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, CS_PIN);

  // 初始化 SD 卡
  if (!SD.begin(CS_PIN)) {
    Serial.println("SD 卡初始化失败,请检查接线!");
    return;
  }
  Serial.println("SD 卡初始化成功");
  lisMp3Files();

  // setup i2s
  auto config = i2s.defaultConfig(TX_MODE);
  config.pin_bck = BCK_PIN;   // MAX98357 的 BCLK
  config.pin_ws = WS_PIN;    // MAX98357 的 LRC
  config.pin_data = DATA_PIN;  // MAX98357 的 DIN
  i2s.begin(config);


  // setup I2S based on sampling rate provided by decoder
  decoder.begin();

  // 开始播放第一首
  playNext();
 
}

void loop() {
  if (playlistSize == 0) {
    return;
  }

  if (!isPlaying) return;

  // 持续复制音频数据
  if (!copier.copy()) {
    // 当前文件播放结束,切换到下一首
    Serial.println("当前曲目播放结束");
    audioFile.close();
    currentIndex++;
   
    if (currentIndex < playlistSize) {
      playNext();  // 播放下一首
    } else {
      Serial.println("所有曲目播放完毕");
      isPlaying = false;
    }
  }
}

// 播放下一首(或指定索引)
void playNext() {
  if (currentIndex >= playlistSize) {
    Serial.println("播放列表已到头");
    return;
  }

  String fileName = playlist[currentIndex];
  Serial.print("正在播放: ");
  Serial.println(fileName);

  audioFile = SD.open(fileName);
  if (!audioFile) {
    Serial.println("文件打开失败,跳过");
    currentIndex++;
    playNext();  // 递归尝试下一首
    return;
  }

  // 重新配置解码器(重要:每次换文件都要重新关联)
  decoder.begin();
 
  // 开始复制数据
  copier.begin(decoder, audioFile);
  isPlaying = true;
}

代码中使用了vector,方便动态追加文件。














关键词: 懒猫的学习笔记     ESP32C3     MP3    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]