ESP32 使用 MAX98357 播放MP3
阅前须知:
正文
首先使用ESP32板和MAX98357芯片进行了简单的接线,下载了ArduinoI2S的库,然后用Arduino IDE并编写了一些简单的代码来实现音乐播放。
当我们启动程序并播放这首歌时,我们听到了一个令人惊叹的立体声效果,仿佛我们身临其境,整个音乐环绕着我们。这归功于MAX98357芯片的高品质音频放大和ESP32的先进处理能力。
总之,使用ESP32和MAX98357芯片播放音乐的实验效果令人惊叹。这不仅是科技和音乐的完美结合,也是一个有趣而充满创意的实验。无论您是音乐爱好者还是科技迷,都一定要尝试一下!
元件说明
MAX98357是一款高品质、低功耗的立体声音频放大器芯片,由Maxim Integrated生产。该芯片具有内置的数字音频接口(I2S),可与各种数字音频设备配合使用。MAX98357能够提供高达3.2W的输出功率,并具有优秀的失真和噪声性能。此外,该芯片还支持多种电源电压,包括3.3V、5V和+/-5V等。该芯片适用于便携式音频设备、智能音箱、车载音频系统和其他需要高品质音频放大器的应用。其小尺寸和低功耗使其非常适合在空间受限或需要长时间使用的应用中。如果您正在寻找一款高性能、低功耗的立体声音频放大器芯片,那么MAX98357将是您的不二之选。
ESP32和MAX98357的应用
ESP32和MAX98357这两款芯片可以结合起来实现很多有趣的应用,下面是一些例子举例:
- 智能音箱:使用ESP32作为控制中心,接入互联网,可以与人工智能语音助手如Alexa、Google Home等配合使用,同时使用MAX98357作为音频输出设备,可以实现高品质的音频播放效果。
- 蓝牙音箱:ESP32可以配合蓝牙模块实现无线连接,将音频数据传输到MAX98357芯片进行音频放大和播放,实现一个便携式的蓝牙音箱。
- 录音回放设备:将麦克风接入ESP32,利用其内置的ADC模块将模拟信号转换为数字信号,并使用MAX98357芯片进行数字音频输出,可以实现录音回放功能。
- 游戏机:ESP32可以连接到游戏控制器,接收游戏数据并控制MAX98357芯片进行音频输出,实现一个简单的游戏机。
- IoT音乐应用:ESP32可以连接到各种传感器,收集环境数据,并控制MAX98357芯片进行音频输出,实现一个智能音乐应用。
这些只是ESP32和MAX98357可以实现的一些应用,您也可以发挥自己的创意和想象力,开发出更多有趣的应用。
MAX98357的特点
- 输出功率: 4欧时为3.2W,THD为10% 8欧时为 1.8W,THD为10%
- I2S采样率:8KHz-96kHZ
- D类放大器 增益可选:3dB/6dB/9dB/12d B/15dl
- 无需主控时钟 ( MCLK)
- 即插即用:只需单电源供电,即可自动配置35种不 同的时钟和128种数字音频格式。
- 适用于Raspberry Pi, Arduino以及ESP32等具 有I2S音频输出的微控制器或开发板系统
引脚说明
MAX98357A的引脚图:
MAX98357A模块引脚 | 引脚说明 |
---|---|
VIN | 电源正(2.5V-5.5V) |
GND | 电源地 |
SD | 关机和频道选择。SD MODE拉低以将器件处于关断状态,当处于不同电压范围时,则有配置不同的频道 |
GAIN | 增益和频道选择。在TDM模式下,增益固定为12dB |
DIN | 数字信号输入 |
BCLK | 位时钟输入 |
LRC | I2S与LJ模式的左/右时钟。同步时钟用于TDM模式 |
BOM表
名称 | 数量 |
---|---|
ESP32 开发板 | x1 |
MAX98357A I2S 音频放大器模块 | x1 |
喇叭 | x1 |
跳线(杜邦线) | 若干 |
接线图
ESP32与MAX98357的接线图:
库安装
1,首先到GITHUB下载「ESP32-audioI2S」
仓库地址:https://github.com/schreibfaul1/ESP32-audioI2S/
2,解压。
3,把解压的文件放进Arduino IDE的libraries文件夹
代码提点
1,加载库
#include "Arduino.h"
#include "WiFiMulti.h" // Wifi库
#include "Audio.h" // I2S的音乐库
2,定义MAX98375A的引脚
// Digital I/O used
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26
3,创建实例
Audio audio; // 创建 播放音乐的 Audio 实例
WiFiMulti wifiMulti; // ESP32 的 WIFI 实例
4,初始化音乐Audio实例
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT); // 初始化,配置所用引脚
audio.setVolume(12); // 设置音量大小 0...21
5,播放音乐
可以播放网络上的mp3文件
audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.mp3"); // 128k mp3
6, 持续运行
需要在loop()中放置audio.loop();
void loop() {
...
audio.loop();
...
}
7,从串口中获取mp3连接
if (Serial.available()){ // put streamURL in serial monitor
audio.stopSong();
String r=Serial.readString(); r.trim();
if (r.length()>5) audio.connecttohost(r.c_str());
log_i("free heap=%i", ESP.getFreeHeap());
}
完整代码
// Welcome to www.LingShunLAB.com
#include "Arduino.h"
#include "WiFiMulti.h"
#include "Audio.h"
// Digital I/O used
#define I2S_DOUT 25
#define I2S_BCLK 27
#define I2S_LRC 26
Audio audio;
WiFiMulti wifiMulti;
// config your wifi
String ssid = "xxxxx";
String password = "xxxxx";
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
wifiMulti.addAP(ssid.c_str(), password.c_str());
wifiMulti.run();
if(WiFi.status() != WL_CONNECTED){
WiFi.disconnect(true);
wifiMulti.run();
}
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(12); // 0...21
audio.connecttohost("http://mp3.ffh.de/radioffh/hqlivestream.mp3"); // 128k mp3
}
void loop()
{
audio.loop();
if(Serial.available()){ // put streamURL in serial monitor
audio.stopSong();
String r=Serial.readString(); r.trim();
if(r.length()>5) audio.connecttohost(r.c_str());
log_i("free heap=%i", ESP.getFreeHeap());
}
}
// optional
void audio_info(const char *info){
Serial.print("info "); Serial.println(info);
}
void audio_id3data(const char *info){ //id3 metadata
Serial.print("id3data ");Serial.println(info);
}
void audio_eof_mp3(const char *info){ //end of file
Serial.print("eof_mp3 ");Serial.println(info);
}
void audio_showstation(const char *info){
Serial.print("station ");Serial.println(info);
}
void audio_showstreamtitle(const char *info){
Serial.print("streamtitle ");Serial.println(info);
}
void audio_bitrate(const char *info){
Serial.print("bitrate ");Serial.println(info);
}
void audio_commercial(const char *info){ //duration in sec
Serial.print("commercial ");Serial.println(info);
}
void audio_icyurl(const char *info){ //homepage
Serial.print("icyurl ");Serial.println(info);
}
void audio_lasthost(const char *info){ //stream URL played
Serial.print("lasthost ");Serial.println(info);
}
上传代码后,程序会自动播放一首歌曲,然后可以在串口中发送MP3连接,即可在线播放。
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"
#include "SD.h"
#include "FS.h"
#define SD_CS 5
#define SPI_MOSI 23
#define SPI_MISO 19
#define SPI_SCK 18
#define I2S_DOUT 25
#define I2S_BCLK 26
#define I2S_LRC 27
Audio audio;
void setup() {
pinMode(SD_CS, OUTPUT);
digitalWrite(SD_CS, HIGH);
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
Serial.begin(115200);
SD.begin(SD_CS);
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(21); // 0...21
audio.connecttoFS(SD, "/320k_test.mp3");
}
void loop()
{
audio.loop();
}
作者:掘金莫狄
链接:https://juejin.cn/post/6844903990220554254
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码3——在线播放
#include "Arduino.h"
#include "WiFiMulti.h"
#include "Audio.h"
#include <Preferences.h>
#define I2S_DOUT 37
#define I2S_BCLK 36
#define I2S_LRC 35
Preferences preferences;
Audio audio;
WiFiMulti wifiMulti;
String ssid = "FAST_BA74";
String password = "12345678";
const uint16_t port = 8000;
static String music_id = "";
WiFiServer server(port);
TaskHandle_t Task;
void setup() {
Serial.begin(115200);
preferences.begin("my-app", false);
music_id = preferences.getString("music", "1873321491");
WiFi.mode(WIFI_STA);
wifiMulti.addAP(ssid.c_str(), password.c_str());
wifiMulti.run();
if (WiFi.status() != WL_CONNECTED) {
WiFi.disconnect(true);
wifiMulti.run();
}
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
audio.setVolume(10); // 0...21
char httpPath[60];
sprintf(httpPath, "%s%s%s", "http://music.163.com/song/media/outer/url?id=", music_id, ".mp3");
Serial.println(httpPath);
audio.connecttohost(httpPath); // 128k mp3
xTaskCreatePinnedToCore(
Taskcode, /* Task function. */
"Task", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
0, /* priority of the task */
&Task, /* Task handle to keep track of created task */
0); /* pin task to core 1 */
}
void loop() {
audio.loop();
}
//Taskcode
void Taskcode(void *pvParameters) {
Serial.println(WiFi.localIP());
server.begin();
for (;;) {
WiFiClient client = server.available(); //尝试建立客户对象
if (client) //如果当前客户可用
{
Serial.println("[Client connected]");
while (client.connected()) //如果客户端处于连接状态
{
if (client.available()) //如果有可读数据
{
audio.stopSong();//停止播放
String c = client.readStringUntil('\n');
Serial.print(c);
preferences.putString("music", c);
preferences.end();
client.stop();
esp_restart();
}
}
client.stop(); //结束当前连接:
Serial.println("[Client disconnected]");
}
}
vTaskDelay(1000);
}
作者:掘金莫狄
链接:https://juejin.cn/post/6844903990220554254
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。