ESP32播放MP3音乐-无需SD卡-WM8978-ESP32解码MP3

2 篇文章 0 订阅

ESP32播放MP3音乐(无需SD卡和外置RAM)

无需SD卡,FLASH大小4MB,非常适合用于智能家居的语音提示或者在线播放音乐。

一般来说,一个语音提示文件的MP3格式的大小约5KB,而未压缩的wav格式的大小则为60KB左右。如果拿2MB的FLASH空间来存储MP3格式的语音提示文件,则其数量要远大于WAV格式。
wav格式或pcm格式是未压缩格式,ESP32可以直接播放的,无需解码

所需硬件:ESP32开发板(带32Mbit FLASH)、WM8978模块。

ESP32也可以使用内置的DAC来播放音乐,但据他人所言会影响其他资源的使用,故此处使用WM8978,同时也省去了一片功放芯片。

所用硬件
模块是某宝上买的,附送有资料,但除了I2C之外,其他的并不适用于ESP32。

1. 烧录我上传的固件文件(见文末)

烧录
完成烧录
完成烧录

2. 硬件连接

(WM8978) LRCK >>> (ESP32)GPIO 25
(WM8978) SCLK >>> (ESP32)GPIO 26
(WM8978) SDIN >>> (ESP32)GPIO 22
(WM8978) MCLK >>> (ESP32)GPIO 0
(WM8978) SCL >>> (ESP32)GPIO 15
(WM8978) MCLK >>> (ESP32)GPIO 14
模块3.3V供电,插入耳机。

3. 复位ESP32

复位后会循环播放固件里的MP3音乐,立体音。

串口

打开串口可以查看播放进度

划重点-代码实现流程:

1. 使用I2C协议来配置WM8978模块
2. 初始化ESP32的I2S通信接口
3. 建立数据缓冲,大于4096字节
4. 从FLASH读取一个扇区(4096字节)
5. 转为解码所需的stream比特流形式(本例子用的是开源的mad MP3解码库)
6. 开始MP3解码
7. 解码4096字节完成后,把PCM数据通过I2S送入WM8978模块
8. 重复第四步,直至结束

坑:注意MP3数据不要一帧一帧(一帧大小有几百字节)地解码-播放,这会导致奇怪的声音出现(解码出错)。

测试固件下载链接:https://download.csdn.net/download/DTXK1024/11972783

固件的下载积分我调整不了,如果你是需要某宝花钱买才可以下载CSDN的资源,那么可以私聊我或者评论里留下你的邮箱,我有时间会把资源发到你邮箱。

代码我整理后再放出

END

  • 22
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 43
    评论
ESP32-CAM是一款基于ESP32芯片的Wi-Fi和蓝牙开发板,搭载了摄像头模块,可以进行视频流传输和图像采集。ESP32-CAM支持使用MicroSD卡进行存储,以便于存储视频和照片等数据。 ESP32-CAM的MicroSD卡插槽位于开发板的底部,使用时需要插入MicroSD卡。在程序中,需要使用SD库进行SD卡读写操作。需要注意的是,在使用SD卡之前需要对ESP32-CAM进行初始化,以便于正确识别SD卡。 以下是使用ESP32-CAM读写SD卡的示例代码: ```cpp #include "esp_camera.h" #include "SD.h" // 定义SD卡引脚 #define SD_CS_PIN 5 void setup() { // 初始化SD卡 if(!SD.begin(SD_CS_PIN)){ Serial.println("SD Card Mount Failed"); return; } // 初始化摄像头 camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = 5; config.pin_d1 = 18; config.pin_d2 = 19; config.pin_d3 = 21; config.pin_d4 = 36; config.pin_d5 = 39; config.pin_d6 = 34; config.pin_d7 = 35; config.pin_xclk = 0; config.pin_pclk = 22; config.pin_vsync = 25; config.pin_href = 23; config.pin_sscb_sda = 26; config.pin_sscb_scl = 27; config.pin_pwdn = 32; config.pin_reset = -1; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; if(psramFound()){ config.frame_size = FRAMESIZE_UXGA; config.jpeg_quality = 10; config.fb_count = 2; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; config.fb_count = 1; } esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } } void loop() { // 拍摄照片 camera_fb_t * fb = esp_camera_fb_get(); if(!fb) { Serial.println("Camera capture failed"); return; } // 创建文件并写入照片数据 String filename = "/photo" + String(millis()) + ".jpg"; File file = SD.open(filename.c_str(), FILE_WRITE); if(!file){ Serial.println("Failed to open file for writing"); return; } file.write(fb->buf, fb->len); file.close(); esp_camera_fb_return(fb); Serial.printf("Saved file to %s\n", filename.c_str()); delay(5000); } ``` 在上述代码中,首先需要定义SD卡的引脚,然后在`setup()`函数中初始化SD卡和摄像头。在`loop()`函数中,首先拍摄照片,然后创建一个以时间戳命名的文件,并将照片数据写入文件中。最后输出保存的文件名,并延时5秒钟。需要注意的是,每次保存照片时需要更改文件名,以免覆盖之前保存的照片。
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值