En este post, aprenderás cómo usar el módulo amplificador MAX98357A con el ESP32 para reproducir audio.
El MAX98357A es un conversor digital a analógico (DAC) compacto con amplificador integrado. Recibe datos de audio digital mediante el protocolo I2S y entrega audio amplificado directamente a un altavoz. Esta combinación simplifica tu montaje de hardware y mejora la calidad del sonido.
A lo largo de este tutorial, aprenderás a generar señales de audio, convertir texto a voz, escuchar radio por internet, reproducir archivos MP3 desde una tarjeta SD y usar audio por Bluetooth.
Componentes necesarios
Necesitarás al menos un módulo MAX98357A. Si quieres reproducir en estéreo, necesitarás dos módulos MAX98357A. Igualmente, necesitarás dos altavoces de 4-8 Ω y al menos 3 vatios.
Para reproducir archivos MP3 desde una tarjeta SD, además necesitarás una tarjeta SD de al menos 1GB y un módulo lector de tarjetas SD.
Por último, necesitas un ESP32, una placa de pruebas (breadboard) y algunos cables. Yo usé un ESP32 lite, pero la mayoría de las otras placas ESP32 también deberían funcionar. Preferiblemente consigue un ESP32-S3 con PSRAM si planeas almacenar y reproducir música desde la memoria.

2 x Amplificador MAX98357A

2x Altavoz 4Ω 5W

Lector de tarjetas Micro SD

Tarjeta Micro SD 8GB

ESP32 lite

Cable de datos USB

Set de cables Dupont

Breadboard
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
El protocolo de audio I2S
Empecemos con una breve introducción al protocolo I2S, que se utiliza para transferir datos de audio digitalmente desde un ESP32 a un módulo amplificador como el MAX98357.
I2S, o Inter-IC Sound, es un estándar de interfaz de bus serie usado para conectar dispositivos de audio digital. Fue introducido por Philips en los años 80 para simplificar la transmisión de datos de audio entre circuitos integrados. A diferencia de protocolos como SPI o I2C, I2S está diseñado específicamente para aplicaciones de audio, asegurando una temporización y sincronización precisa de las señales de audio.
En esencia, I2S transfiere datos de audio en Modulación por Impulsos Codificados (PCM) de manera síncrona. El protocolo utiliza tres señales principales: el reloj serie (SCK), la selección de palabra (WS) y los datos serie (SD). El reloj serie pulsa a la velocidad de bits, indicando cuándo se envían los bits. La señal de selección de palabra alterna para indicar si los datos actuales corresponden al canal de audio izquierdo o derecho. Finalmente, la línea de datos serie transporta los bits de audio reales, transmitiendo primero el bit más significativo (MSB).

Normalmente, los datos de audio se envían en palabras de 16 o 24 bits, pero el protocolo puede soportar otras profundidades de bits dependiendo del hardware.
El periférico I2S del ESP32 soporta comunicación full-duplex, permitiendo entrada y salida de audio simultáneamente. Puede configurarse para operar en modo maestro o esclavo. Cuando actúa como maestro, el ESP32 genera las señales de reloj y selección de palabra. Esta es la configuración habitual al conectar con el amplificador MAX98357A, que actúa como dispositivo esclavo I2S. En la siguiente sección veremos más de cerca el MAX98357A.
Características técnicas del módulo MAX98357A
El módulo MAX98357A es un amplificador digital que acepta entrada I2S directamente. Convierte la señal de audio digital entrante en una señal analógica y la amplifica para alimentar altavoces. Integra un amplificador Clase D de 3,2W con un conversor digital a analógico (DAC) incorporado. La interfaz de audio digital reconoce hasta 35 esquemas de reloj PCM y TDM diferentes, lo que elimina la necesidad de programación por I2C.

El MAX98357A soporta muestras de audio de 16, 24 y 32 bits a tasas de muestreo desde 8 kHz hasta 96 kHz. Esta flexibilidad permite una reproducción de audio de alta calidad, adecuada para voz, música y otras aplicaciones de sonido.
El módulo funciona con una sola fuente de alimentación de 3,3V o 5V, lo que lo hace compatible con la mayoría de microcontroladores, incluido el ESP32. Cuenta con un regulador de baja caída integrado y protección contra sobrecalentamiento. La imagen de abajo muestra el frente y reverso de un módulo MAX98357A típico:

En la entrada, el MAX98357A espera tres señales principales: bit clock (BCLK), word select (LRC) y datos serie (SD). El bit clock sincroniza los bits de datos, mientras que la selección de palabra indica si los datos actuales corresponden al canal izquierdo o derecho. La línea de datos serie transporta las muestras de audio en un flujo continuo.

Internamente, el módulo convierte los datos de audio digital entrantes en una señal analógica usando su DAC integrado. Esta señal analógica es amplificada por la etapa de amplificador Clase D, que puede alimentar un altavoz de 4 u 8 Ω con 3 vatios.
El MAX98357A incluye control de ganancia y puede configurarse para producir salida de canal izquierdo, derecho o una mezcla de ambos canales estéreo a través del pin SD. En la siguiente sección hablaremos de estos pines en más detalle.
Pinout del módulo MAX98357A
Un módulo MAX98357A típico tiene pines para la alimentación (Vin, GND), para la interfaz I2S (LRC, BCLK, DIN), para el control de ganancia (GAIN) y para la selección de canal y apagado (SD). La imagen de abajo muestra el pinout:

Alimentación
El pin VIN acepta de 3,3V a 5V. El pin GND es la referencia de tierra y debe conectarse a la tierra del ESP32.
El consumo de corriente del MAX98357A para reproducción de audio a volumen moderado suele estar entre 200mA y 400mA. El regulador de voltaje de una placa ESP32 típica es de unos 800mA, pero el ESP32 lite usa un ME6211 de solo 500mA.
Esto significa que puedes alimentar un MAX98357A desde el pin de salida de 3,3V del ESP32, pero es arriesgado, ya que a volumen alto y ganancia máxima la corriente puede llegar hasta 1,5A (a 5V). Por eso, es mejor alimentar el MAX98357A desde una fuente de alimentación externa.
Ten en cuenta que el MAX98357A incluye un limitador de corriente de salida al altavoz de 2,8A. Si la corriente de salida supera este valor, el chip se apagará temporalmente y se reiniciará para protegerse.
Interfaz I2S
El pin LRC significa Left-Right Clock o Word Select. Indica si los datos de audio actuales pertenecen al canal izquierdo o derecho. El ESP32 genera esta señal como parte del protocolo I2S.
El pin BCLK es el Bit Clock. Sincroniza los bits de datos enviados por la línea DIN. El ESP32 también proporciona esta señal de reloj.
El pin DIN es la línea de entrada de datos. Este pin recibe los datos de audio reales desde el ESP32.
Control de ganancia
Puedes controlar la ganancia del MAX98357A conectando el pin de ganancia a VCC o GND directamente o mediante una resistencia de 100K. La siguiente tabla muestra qué conexión resulta en qué ganancia.
| Ganancia | Conexión |
|---|---|
| 15dB | GAIN — 100K — GND |
| 12dB | GAIN — GND |
| 9dB | Ninguna |
| 6dB | GAIN — VCC |
| 3dB | GAIN — 100K — VCC |
La ganancia de 9dB es la configuración por defecto y no se requiere ninguna conexión.
Control de canal
El pin SD (Shutdown) del MAX98357A te permite apagar el amplificador o seleccionar la salida derecha, izquierda o mixta desde la entrada estéreo. La imagen de abajo muestra el esquema del módulo MAX98357A con el pin SD Mode y la información sobre cómo seleccionar un canal:

Si el pin SD no está conectado (por defecto), el amplificador genera una salida mixta de los canales izquierdo y derecho ((L+R)/2). Si el pin SD está conectado a tierra, el amplificador se apaga. De lo contrario, el voltaje en SD determina si se amplifica el canal izquierdo o derecho. La siguiente tabla muestra los voltajes requeridos en el pin SD para activar las diferentes funciones:
| Voltaje @ SD | Función |
|---|---|
| < 0.16V | Amplificador apagado |
| 0.16 … 0.77V | Canal izquierdo y derecho mezclados ((L+R)/2) |
| 0.77 … 1.4V | Canal derecho (370KΩ @ 5V, 210KΩ @ 3V3) |
| > 1.4V | Solo canal izquierdo (100kΩ) |
Para lograr el voltaje requerido en el pin SD y seleccionar el canal derecho, necesitas conectar el pin SD a VCC mediante una resistencia adecuada. El esquema muestra la siguiente fórmula:
R = (94 * VDD – 100) KΩ
Esto significa que, a 5V necesitas una resistencia de 370KΩ entre SD y 5V, y a 3,3V necesitas una de 210KΩ.
Para seleccionar el canal izquierdo puedes usar una resistencia de 100kΩ a 5V o 3,3V. Y si quieres salida de canal mixto (mono sumado), simplemente deja el pin SD sin conectar.
Datasheet
El siguiente botón enlaza al datasheet del MAX98357A, donde puedes encontrar detalles técnicos adicionales:
Conectar MAX98357A al ESP32
En esta sección aprenderás las diferentes formas de conectar el MAX98357A y los altavoces a un ESP32.
Mono sumado
Empezamos con la configuración más sencilla. Usamos un solo MAX98357A y un solo altavoz para reproducir una señal estéreo mezclada (50% canal izquierdo, 50% canal derecho).
Comienza conectando Vin del MAX98357A a 3,3V del ESP32 y GND a G. Luego conecta los pines I2S como se muestra en la siguiente tabla:
| MAX98357A | ESP32 |
|---|---|
| Vin | 3V3 |
| GND | G |
| LRC | 32 |
| BCLK | 25 |
| DIN | 33 |
Deja los pines GAIN y SD del MAX98357A sin conectar. Esto generará una mezcla de canal izquierdo y derecho con una ganancia de 9dB.
Al conectar el altavoz, asegúrate de respetar la polaridad correcta y usa un altavoz de 4Ω u 8Ω de al menos 3W. Puedes usar altavoces de mayor potencia, pero no de menor.
La siguiente imagen muestra el cableado completo de un MAX98357A con un ESP32 lite para sonido mono sumado (mezcla) con alimentación a través del pin de 3,3V:

Como se mencionó antes, el MAX98357A puede consumir hasta 1,5A de corriente al reproducir sonido fuerte con ganancia máxima. El pin de 3,3V del ESP32 no puede suministrar tanta corriente y necesitas usar una fuente de alimentación externa. La imagen de abajo muestra cómo conectar una alimentación externa de 5V al circuito:

Estéreo
Si quieres reproducir sonido estéreo necesitas dos altavoces, y dos MAX98357A (uno por canal) y resistencias para seleccionar el canal izquierdo o derecho. La imagen de abajo muestra el cableado completo:

Ambos MAX98357A están conectados en paralelo, usando la misma alimentación y pines I2S que antes. La única diferencia es que el MAX98357A para el canal izquierdo tiene una resistencia de 100KΩ entre SD y 3,3V y el MAX98357A para el canal derecho tiene una de 210KΩ.
Ten en cuenta que el ESP32 debe producir una señal estéreo y el MAX98357A simplemente selecciona el canal izquierdo o derecho de la entrada estéreo dependiendo del voltaje en el pin SD.
Como antes, en vez de alimentar el MAX98357A desde el pin de 3,3V del ESP32, la opción más segura es usar alimentación externa. El diagrama de conexiones muestra cómo usar una fuente de alimentación externa de 5V:

Ten en cuenta que el pin SD del MAX98357A sigue conectado a 3,3V mediante una resistencia de 100KΩ o 210KΩ. También puedes conectar las resistencias a la fuente externa de 5V, pero entonces deberías usar una resistencia de 370KΩ para el canal derecho en vez de la de 210KΩ. La resistencia de 100KΩ para el canal izquierdo puede quedarse igual.
Tarjeta SD
Si quieres reproducir archivos de audio necesitas conectar un lector de tarjetas SD que almacene los archivos de audio en una tarjeta SD. El diagrama de conexiones de abajo muestra cómo conectar un lector de tarjetas SD y el MAX98357A a un ESP32:

El lector de tarjetas SD se comunica por SPI y los pines SPI por defecto del ESP32 son CS=5, MOSI=23, CLK=18 y MISO=19. La tabla de abajo resume las conexiones que debes hacer entre el lector de tarjetas SD y el ESP32:
| Lector de tarjetas SD | ESP32 |
|---|---|
| 3V3 | 3V |
| GND | G |
| CS/SS | 5 |
| MOSI | 23 |
| CLK/SCK | 18 |
| MISO | 19 |
Si no estás seguro de cuáles son los pines SPI por defecto de tu ESP32, consulta el Find I2C and SPI default pins tutorial.
Si quieres reproducir sonido estéreo necesitas conectar dos módulos MAX98357A. El siguiente diagrama muestra cómo hacerlo:

Si necesitas más ayuda para conectar el lector de tarjetas SD, consulta nuestro SD Card Module with ESP32 tutorial.
Instalación de librerías
Hay varias librerías de Arduino que puedes usar para generar audio para un dispositivo I2S como el MAX98357A. A continuación, comento brevemente las tres más usadas.
Primero, está la librería ESP8266Audio de Earle F. Philhower, que soporta placas ESP8266, ESP32, Raspberry Pi Pico RP2040 y Pico 2 RP2350.
Luego está la librería ESP32-audioI2S de schreibfaul1. Ten en cuenta que esta librería solo funciona en chips multinúcleo como ESP32, ESP32-S3, ESP32-P4 y tu placa debe tener PSRAM. No funciona en placas ESP32-S2, ESP32-C3.
Por último, está la librería arduino-audio-tools de Phil Schatzmann, que es la más potente y con muchísimas funciones. Es la librería que vamos a usar en este tutorial, pero las otras también valen la pena probarlas.
Instalar core ESP32
A enero de 2026, no pude hacer funcionar la librería arduino-audio-tools con el core ESP32 actual (Versión 3.3.6). Para los ejemplos de este tutorial necesitas bajar el core ESP32 a la Versión 2.0.17.
Suponiendo que ya tienes instalado el core ESP32, bajarlo de versión es fácil. Abre el BOARDS MANAGER, escribe “esp32” en la barra de búsqueda y luego selecciona la versión 2.0.17 para el core “esp32 by Espressif” y haz clic en “UPDATE” como se muestra abajo:

Si necesitas más ayuda para bajar de versión o instalar el core ESP, consulta el Install ESP32 core in Arduino IDE tutorial.
Instalar la librería arduino-audio-tools
Para instalar la librería arduino-audio-tools ve al arduino-audio-tools repo, haz clic en el botón verde «<> Code» y luego en «Download ZIP» para descargar la librería como archivo ZIP, como se muestra abajo:

Luego abre un Sketch, ve a Sketch -> Include Library -> Add .ZIP Library … para instalar la librería ZIP descargada (arduino-audio-tools-main.zip):

Para algunos ejemplos de código necesitamos dos librerías más de Phil Schatzmann: la arduino-libhelix y la ESP32-A2DP. Puedes instalarlas igual. Haz clic en el enlace para ir al repo de github, haz clic en el botón verde «<> Code» para descargar las librerías (arduino-libhelix-main.zip, ESP32-A2DP-main.zip) y luego instálalas.
Reproducir sonido de prueba
Antes de probar algo complejo, primero vamos a reproducir un sonido de prueba. Esto nos permitirá verificar el cableado del MAX98357A con el ESP32 y que los canales izquierdo y derecho están correctamente seleccionados al reproducir sonido estéreo. Además, este código no depende de ninguna librería y funciona tanto con el core ESP32 actual (3.x) como con el antiguo (2.x).
#include <driver/i2s.h>
#include <math.h>
#define I2S_PORT I2S_NUM_0
// MAX98357
#define MAX_DIN 33
#define MAX_LRC 32
#define MAX_BCLK 25
// Audio parameters
#define SAMPLE_RATE 44100
#define TONE_FREQ 500
#define AMPLITUDE 1000 // Max 32767
// Channels
#define LEFT false
#define RIGHT true
// Buffer size (frames, not samples)
#define BUFFER_LEN 256
// Stereo buffer: Left, Right
int16_t samples[BUFFER_LEN * 2];
void setup() {
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = BUFFER_LEN,
.use_apll = false,
.tx_desc_auto_clear = true,
.fixed_mclk = 0
};
i2s_pin_config_t pin_config = {
.bck_io_num = MAX_BCLK,
.ws_io_num = MAX_LRC,
.data_out_num = MAX_DIN,
.data_in_num = I2S_PIN_NO_CHANGE
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
i2s_set_pin(I2S_PORT, &pin_config);
}
void loop() {
static float phase = 0.0;
const float phaseIncrement = 2.0 * PI * TONE_FREQ / SAMPLE_RATE;
for (int i = 0; i < BUFFER_LEN; i++) {
int16_t sound = (int16_t)(AMPLITUDE * sin(phase));
int16_t silence = 0;
samples[2 * i] = (LEFT) ? sound : silence; // Left channel
samples[2 * i + 1] = (RIGHT) ? sound : silence; // Right channel
phase += phaseIncrement;
if (phase >= 2.0 * PI) phase -= 2.0 * PI;
}
size_t bytes_written;
i2s_write(I2S_PORT, samples, sizeof(samples), &bytes_written, portMAX_DELAY);
}
El código configura el ESP32 como transmisor maestro I2S, genera en tiempo real una señal de audio de onda senoidal y la envía al amplificador para producir sonido en el canal izquierdo, derecho o ambos.
Imports
El código incluye la librería driver/i2s.h, que proporciona las funciones del driver I2S del ESP32 para comunicación de audio. También incluye la librería estándar de matemáticas math.h para usar funciones matemáticas como sin() para generar la forma de onda de audio.
#include <driver/i2s.h>; #include <math.h>;
Constantes
Se definen varias constantes para configurar la interfaz I2S y los parámetros de audio. I2S_PORT selecciona el número de periférico I2S 0 en el ESP32. Los pines MAX_DIN, MAX_LRC y MAX_BCLK corresponden a las líneas de datos, selección de palabra (left-right clock) y bit clock conectadas al amplificador MAX98357.
Los parámetros de audio incluyen una tasa de muestreo de 44.100 Hz, una frecuencia de tono de 500 Hz y una amplitud de 1000 (dentro del rango de un entero con signo de 16 bits). Lo más importante es que el código también define banderas booleanas LEFT y RIGHT para controlar qué canales de audio emiten sonido.
Por último, BUFFER_LEN define el número de frames de audio por buffer, y un array estéreo samples almacena las muestras de audio intercaladas de los canales izquierdo y derecho.
#define I2S_PORT I2S_NUM_0 // MAX98357 #define MAX_DIN 33 #define MAX_LRC 32 #define MAX_BCLK 25 // Audio parameters #define SAMPLE_RATE 44100 #define TONE_FREQ 500 #define AMPLITUDE 1000 // Max 32767 // Channels #define LEFT false #define RIGHT true // Buffer size (frames, not samples) #define BUFFER_LEN 256 // Stereo buffer: Left, Right int16_t samples[BUFFER_LEN * 2];
Función setup
La función setup() inicializa el driver I2S y configura los pines para la comunicación con el amplificador MAX98357.
Se crea una estructura i2s_config_t para especificar el modo I2S como transmisor maestro, muestras de 16 bits, formato de canal estéreo (derecho e izquierdo) y una tasa de muestreo de 44,1 kHz. También se configuran los parámetros del buffer DMA para una transferencia eficiente de datos.
A continuación, una estructura i2s_pin_config_t asigna los pines GPIO para bit clock (bck_io_num), selección de palabra (ws_io_num) y salida de datos (data_out_num). El pin de entrada de datos no se usa y se pone en I2S_PIN_NO_CHANGE.
Por último, se instala el driver I2S con i2s_driver_install() y se aplica la configuración de pines con i2s_set_pin().
void setup() {
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = BUFFER_LEN,
.use_apll = false,
.tx_desc_auto_clear = true,
.fixed_mclk = 0
};
i2s_pin_config_t pin_config = {
.bck_io_num = MAX_BCLK,
.ws_io_num = MAX_LRC,
.data_out_num = MAX_DIN,
.data_in_num = I2S_PIN_NO_CHANGE
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
i2s_set_pin(I2S_PORT, &pin_config);
}
Función loop
La función loop() genera continuamente muestras de audio y las envía al periférico I2S para su reproducción.
Una variable estática phase lleva el seguimiento de la posición actual dentro del ciclo de la onda senoidal. El phaseIncrement se calcula en base a la frecuencia de tono deseada y la tasa de muestreo, determinando cuánto avanza la fase por muestra.
Dentro del bucle, el código llena el buffer samples con datos de audio estéreo intercalados. Para cada frame, calcula el seno de la fase actual, lo escala por la amplitud y lo convierte a entero de 16 bits. Dependiendo de las banderas LEFT y RIGHT, el sonido se asigna a los canales izquierdo y/o derecho, mientras que el otro canal se pone en silencio (cero).
La fase se incrementa y se ajusta para mantenerse dentro del rango de 0 a 2π radianes, asegurando una forma de onda continua.
Después de llenar el buffer, la función i2s_write() envía los datos de audio al driver I2S, que los transmite al amplificador. La función bloquea hasta que se escriben todos los bytes, manteniendo una reproducción de audio fluida.
void loop() {
static float phase = 0.0;
const float phaseIncrement = 2.0 * PI * TONE_FREQ / SAMPLE_RATE;
for (int i = 0; i < BUFFER_LEN; i++) {
int16_t sound = (int16_t)(AMPLITUDE * sin(phase));
int16_t silence = 0;
samples[2 * i] = (LEFT) ? sound : silence; // Left channel
samples[2 * i + 1] = (RIGHT) ? sound : silence; // Right channel
phase += phaseIncrement;
if (phase >= 2.0 * PI) phase -= 2.0 * PI;
}
size_t bytes_written;
i2s_write(I2S_PORT, samples, sizeof(samples), &bytes_written, portMAX_DELAY);
}
Puedes usar este código para verificar que el sonido estéreo se reproduce correctamente al usar dos módulos MAX98357 y dos altavoces. Si pones la constante LEFT en true y RIGHT en false, solo el altavoz izquierdo debería sonar. De igual forma, puedes comprobar que el canal derecho suena correctamente. Si no es así, revisa el voltaje y las resistencias en el pin SD del MAX98357, que controla el canal.
Para los siguientes ejemplos usaremos la librería arduino-audio-tools, que ocultará todos los detalles de la comunicación I2S y simplificará el código.
Texto a voz
Este siguiente ejemplo muestra cómo convertir texto a voz usando la interfaz I2S con un amplificador MAX98357. Se conecta a WiFi, envía texto a la API de texto a voz (TTS) de OpenAI, recibe un flujo de audio MP3, lo decodifica y lo reproduce a través del amplificador. El código usa la librería arduino-audio-tools para gestionar el streaming y la decodificación de audio.
/*
www.makerguides.com
Libraries:
- ESP32 Core 2.0.17
- [arduino-audio-tools](https://github.com/pschatzmann/arduino-audio-tools)
Version: 1.2.2
- [arduino-libhelix](https://github.com/pschatzmann/arduino-libhelix)
Version: 0.9.2
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
// MAX98357 I2S pins
#define MAX_DIN 33
#define MAX_LRC 32
#define MAX_BCLK 25
// Text to Speech
#define TTS_MODEL "gpt-4o-mini-tts"
#define TTS_VOICE "marin"
#define TTS_VOLUME 0.6
// WiFi credentials
const char* ssid = "ssid";
const char* password = "pwd";
// OpenAI configuration
const char* openaiHost = "api.openai.com";
const int openaiPort = 443;
const char* openaiApiKey = "apikey";
WiFiClientSecure client;
I2SStream i2s;
VolumeStream volume(i2s);
EncodedAudioStream mp3decode(&volume, new MP3DecoderHelix());
StreamCopy copier(mp3decode, client);
void text2speech(const char* text) {
client.setInsecure();
if (!client.connect("api.openai.com", 443)) {
Serial.println("Connection failed");
return;
}
String body = String("{") +
"\"model\":\"" + TTS_MODEL + "\"," +
"\"voice\":\"" + TTS_VOICE + "\"," +
"\"format\":\"mp3\"," +
"\"input\":\"" + text + "\"" +
"}";
client.println("POST /v1/audio/speech HTTP/1.1");
client.println("Host: api.openai.com");
client.println("Authorization: Bearer " + String(openaiApiKey));
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(body.length());
client.println();
client.print(body);
// ---- Skip HTTP headers ----
while (client.connected()) {
String line = client.readStringUntil('\n');
if (line == "\r") break;
}
}
void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
auto config = i2s.defaultConfig(TX_MODE);
config.pin_bck = MAX_BCLK;
config.pin_ws = MAX_LRC;
config.pin_data = MAX_DIN;
i2s.begin(config);
mp3decode.begin();
volume.begin(config);
volume.setVolume(TTS_VOLUME);
text2speech("Hello, this a test for text to speech.");
}
void loop() {
copier.copy();
}
Imports
El código comienza incluyendo varias librerías. Arduino.h es la librería principal de Arduino. WiFi.h y WiFiClientSecure.h proporcionan conectividad WiFi y cliente HTTPS seguro. La librería AudioTools y su códec MP3 CodecMP3Helix se usan para streaming y decodificación de audio.
#include <Arduino.h> #include <WiFi.h> #include <WiFiClientSecure.h> #include "AudioTools.h" #include "AudioTools/AudioCodecs/CodecMP3Helix.h"
Constantes y definición de pines
A continuación, se definen los pines usados para la interfaz I2S hacia el amplificador MAX98357. Estos pines corresponden a la entrada de datos (MAX_DIN), selección de palabra o left-right clock (MAX_LRC) y bit clock (MAX_BCLK).
// MAX98357 I2S pins #define MAX_DIN 33 #define MAX_LRC 32 #define MAX_BCLK 25
Además, se establecen constantes para el modelo TTS, la voz y el nivel de volumen.
// Text to Speech #define TTS_MODEL "gpt-4o-mini-tts" #define TTS_VOICE "marin" #define TTS_VOLUME 0.6
Puedes probar otros modelos TTS, como «tts-1» y otras voces como «alloy», «ash», «coral», «echo», «fable», «onyx», «nova», ‘sage», «shimmer», «marin», «cedar». Para más detalles consulta platform.openai.com/docs/guides/text-to-speech.
Las credenciales WiFi y los detalles de la API de OpenAI también se guardan como cadenas constantes. Tendrás que reemplazar «ssid» y «pwd» por las credenciales de tu WiFi.
// WiFi credentials const char* ssid = "ssid"; const char* password = "pwd";
También necesitarás obtener una «apikey» de OpenAI. Ve a https://platform.openai.com y regístrate con un correo electrónico o una cuenta de Google o Microsoft existente.
// OpenAI configuration const char* openaiHost = "api.openai.com"; const int openaiPort = 443; const char* openaiApiKey = "apikey";
Después de verificar tu correo y completar la configuración inicial, inicia sesión en el panel de OpenAI, platform.openai.com/api-keys y busca o crea tu API Key (=SECRET KEY) como se muestra abajo:

La API Key es una cadena única y larga, que empieza por «sk-proj-«, necesaria para autenticar tus peticiones a la API (ver abajo).
sk-proj-xcA.......................OtDu0U
Eso es todo lo que necesitas para obtener una API key, pero te recomiendo que pongas un límite de uso en tu cuenta también. Para más detalles consulta el Vision Chatbot with DFRobot ESP32-S3 AI Camera and OpenAI tutorial.
Objetos de audio y red
Se instancian varios objetos para gestionar el streaming de audio y la comunicación de red. WiFiClientSecure gestiona la conexión HTTPS con la API de OpenAI. I2SStream gestiona la salida de audio I2S. VolumeStream envuelve el stream I2S para controlar el volumen de audio. EncodedAudioStream decodifica los datos de audio MP3 usando el decodificador Helix MP3. Finalmente, StreamCopy copia el stream de audio decodificado desde el cliente de red a la salida de audio.
WiFiClientSecure client; I2SStream i2s; VolumeStream volume(i2s); EncodedAudioStream mp3decode(&volume, new MP3DecoderHelix()); StreamCopy copier(mp3decode, client);
Función de texto a voz
La función text2speech() envía una cadena de texto a la API TTS de OpenAI y prepara el stream de audio para su reproducción. Primero configura el cliente para aceptar certificados inseguros (útil para desarrollo). Luego intenta conectar con el servidor de OpenAI en el puerto 443. Si la conexión falla, imprime un mensaje de error y retorna.
La función construye un cuerpo JSON especificando el modelo TTS, la voz, el formato de salida (MP3) y el texto de entrada. Envía una petición HTTP POST con los encabezados apropiados, incluyendo la autorización usando la API key. Tras enviar el cuerpo de la petición, lee y salta los encabezados de respuesta HTTP para posicionar el stream del cliente al inicio de los datos de audio MP3.
void text2speech(const char* text) {
client.setInsecure();
if (!client.connect("api.openai.com", 443)) {
Serial.println("Connection failed");
return;
}
String body = String("{") +
"\"model\":\"" + TTS_MODEL + "\"," +
"\"voice\":\"" + TTS_VOICE + "\"," +
"\"format\":\"mp3\"," +
"\"input\":\"" + text + "\"" +
"}";
client.println("POST /v1/audio/speech HTTP/1.1");
client.println("Host: api.openai.com");
client.println("Authorization: Bearer " + String(openaiApiKey));
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(body.length());
client.println();
client.print(body);
// ---- Skip HTTP headers ----
while (client.connected()) {
String line = client.readStringUntil('\n');
if (line == "\r") break;
}
}
Función setup
La función setup() inicializa la comunicación serie para depuración y configura el logger de audio para mostrar advertencias. Luego conecta a la red WiFi especificada, esperando hasta que la conexión se establezca.
Una vez conectado el WiFi, se configura la interfaz I2S en modo transmisión con los pines definidos antes. Se inicializan el stream I2S, el decodificador MP3 y el control de volumen. El volumen se ajusta al nivel predefinido.
Por último, se llama a la función text2speech() con una cadena de texto de ejemplo para empezar a transmitir y reproducir la voz sintetizada.
void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
auto config = i2s.defaultConfig(TX_MODE);
config.pin_bck = MAX_BCLK;
config.pin_ws = MAX_LRC;
config.pin_data = MAX_DIN;
i2s.begin(config);
mp3decode.begin();
volume.begin(config);
volume.setVolume(TTS_VOLUME);
text2speech("Hello, this a test for text to speech.");
}
Función loop
La función loop() copia continuamente datos del stream del decodificador MP3 a la salida de audio I2S. Esto mantiene la reproducción de audio mientras haya datos disponibles del cliente de red.
void loop() {
copier.copy();
}
Radio por internet
Este ejemplo muestra cómo implementar una radio web sencilla. Se conecta a una red WiFi, transmite radio por internet en formato MP3, decodifica el audio, ajusta el volumen y saca el sonido por el amplificador digital MAX98357.
/*
www.makerguides.com
Libraries:
- ESP32 Core 2.0.17
- [arduino-audio-tools](https://github.com/pschatzmann/arduino-audio-tools)
Version: 1.2.2
- [arduino-libhelix](https://github.com/pschatzmann/arduino-libhelix)
Version: 0.9.2
*/
#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include "AudioTools.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
#include "AudioTools/Communication/HTTP/ICYStream.h"
// MAX98357
#define MAX_DIN 33 // serial data
#define MAX_LRC 32 // word select
#define MAX_BCLK 25 // serial clock
#define MAX_VOL 0.5 // Volume
const char* ssid = "ssid";
const char* password = "pwd";
const char* url = "https://jazz.stream.laut.fm/jazz";
ICYStream icystream;
I2SStream i2s;
VolumeStream volume(i2s);
EncodedAudioStream mp3decode(&volume, new MP3DecoderHelix());
StreamCopy copier(mp3decode, icystream);
void callbackMetadata(MetaDataType type, const char* str, int len) {
Serial.printf("%s: %s\n", toStr(type), str);
}
void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
auto config = i2s.defaultConfig(TX_MODE);
config.pin_bck = MAX_BCLK;
config.pin_ws = MAX_LRC;
config.pin_data = MAX_DIN;
i2s.begin(config);
volume.begin(config);
volume.setVolume(MAX_VOL);
mp3decode.begin();
icystream.begin(url);
icystream.setMetadataCallback(callbackMetadata);
}
void loop() {
copier.copy();
}
Imports
El código comienza incluyendo las librerías necesarias para conectividad WiFi, comunicación I2C y procesamiento de audio. Las librerías Arduino.h y WiFi.h proporcionan funciones básicas de Arduino y WiFi. La librería Wire.h se incluye para comunicación I2C, que a menudo se usa para controlar periféricos. La librería AudioTools y sus componentes relacionados gestionan el streaming, la decodificación y la reproducción de audio.
#include <Arduino.h> #include <WiFi.h> #include <Wire.h> #include "AudioTools.h" #include "AudioTools/AudioCodecs/CodecMP3Helix.h" #include "AudioTools/Communication/HTTP/ICYStream.h"
Constantes
A continuación, se definen los pines para el amplificador MAX98357. Estos pines corresponden a las señales I2S: MAX_DIN para la entrada de datos serie, MAX_LRC para la selección de palabra (left-right clock) y MAX_BCLK para el reloj serie. El volumen se establece como un valor flotante entre 0 y 1, donde MAX_VOL es 0.5, representando el 50% de volumen.
#define MAX_DIN 33 // serial data #define MAX_LRC 32 // word select #define MAX_BCLK 25 // serial clock #define MAX_VOL 0.5 // Volume
Credenciales WiFi y URL del stream
Las credenciales de la red WiFi se guardan en las constantes ssid y password. La constante url contiene la dirección del stream de radio por internet a reproducir, en este caso un stream de jazz.
const char* ssid = "ssid"; const char* password = "pwd"; const char* url = "https://jazz.stream.laut.fm/jazz";
Aquí tienes algunas URLs más de streams de radio por internet que puedes probar:
"https://jazz.stream.laut.fm/jazz" "http://vis.media-ice.musicradio.com/CapitalMP3"; "http://stream.srg-ssr.ch/m/rsj/mp3_128" "http://stream.live.vc.bbcmedia.co.uk/bbc_world_service" "http://icecast.omroep.nl/radio1-bb-mp3" "http://stream-02-eu.relaxingjazz.com/stream/1/"
Objetos de audio
Se instancian varios objetos para gestionar la cadena de audio. El objeto ICYStream gestiona el streaming HTTP de la radio por internet y la interfaz de salida de audio I2S. El objeto VolumeStream envuelve el stream I2S para controlar el volumen de audio. Y el objeto EncodedAudioStream decodifica los datos MP3 usando el códec MP3DecoderHelix. Por último, el objeto StreamCopy copia los datos de audio decodificados del decodificador MP3 al stream ICY.
ICYStream icystream; I2SStream i2s; VolumeStream volume(i2s); EncodedAudioStream mp3decode(&volume, new MP3DecoderHelix()); StreamCopy copier(mp3decode, icystream);
Función de callback de metadatos
La función callbackMetadata() se define para manejar los metadatos recibidos del stream de radio por internet, como títulos de canciones o información del artista. Imprime el tipo de metadato y el contenido en el monitor serie para depuración o información.
void callbackMetadata(MetaDataType type, const char* str, int len) {
Serial.printf("%s: %s\n", toStr(type), str);
}
Función setup
En la función setup() se inicializa la comunicación serie a 115200 baudios para permitir el registro y la depuración. El logger de audio se configura para mostrar advertencias y mensajes superiores en el monitor serie.
El ESP32 intenta conectarse a la red WiFi especificada, comprobando el estado de la conexión cada 500 milisegundos hasta que se conecta.
Después de conectar, la configuración I2S se obtiene usando el modo de transmisión por defecto. Los pines I2S se asignan a las constantes definidas previamente para bit clock, selección de palabra y entrada de datos. La interfaz I2S y el control de volumen se inicializan con esta configuración, y el volumen se ajusta al 50%.
Se inicia el decodificador MP3 y el stream de radio por internet se inicializa con la URL proporcionada. Se registra la función de callback de metadatos para manejar los metadatos entrantes durante la reproducción.
void setup() {
Serial.begin(115200);
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
auto config = i2s.defaultConfig(TX_MODE);
config.pin_bck = MAX_BCLK;
config.pin_ws = MAX_LRC;
config.pin_data = MAX_DIN;
i2s.begin(config);
volume.begin(config);
volume.setVolume(MAX_VOL);
mp3decode.begin();
icystream.begin(url);
icystream.setMetadataCallback(callbackMetadata);
}
Función loop
La función loop() copia continuamente los datos de audio del stream de radio por internet a través del decodificador MP3 y el controlador de volumen hasta la salida I2S. Este proceso mantiene la reproducción de audio funcionando indefinidamente.
void loop() {
copier.copy();
}
Si quieres añadir más funciones como un controlador de volumen, consulta nuestro Playing Audio with ESP32 and PCM5102A tutorial. Y si quieres añadir una pantalla, consulta el tutorial Internet Radio with ESP32 and MAX 98357A.
Reproducir MP3 desde tarjeta SD
Este ejemplo muestra cómo reproducir archivos de audio MP3 almacenados en una tarjeta SD usando un ESP32, el amplificador I2S MAX98357 y la librería AudioTools. El código inicializa el hardware de audio, configura el decodificador MP3 y transmite continuamente los datos de audio al amplificador.
/*
www.makerguides.com
Libraries:
- ESP32 Core 2.0.17
- [arduino-audio-tools](https://github.com/pschatzmann/arduino-audio-tools)
Version: 1.2.2
- [arduino-libhelix](https://github.com/pschatzmann/arduino-libhelix)
Version: 0.9.2
*/
#include "AudioTools.h"
#include "AudioTools/Disk/AudioSourceSD.h"
#include "AudioTools/AudioCodecs/CodecMP3Helix.h"
// MAX98357
#define MAX_DIN 33
#define MAX_LRC 32
#define MAX_BCLK 25
#define PATH "/"
#define EXT "mp3"
AudioSourceSD source(PATH, EXT);
I2SStream i2s;
MP3DecoderHelix decoder;
AudioPlayer player(source, i2s, decoder);
void printMetaData(MetaDataType type, const char* str, int len){
Serial.printf("%s: %s\n", toStr(type), str);
}
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
auto cfg = i2s.defaultConfig(TX_MODE);
cfg.pin_bck = MAX_BCLK;
cfg.pin_ws = MAX_LRC;
cfg.pin_data = MAX_DIN;
i2s.begin(cfg);
//source.setFileFilter("*Bob Dylan*");
player.setMetadataCallback(printMetaData);
player.setVolume(0.4);
player.begin();
}
void loop() {
player.copy();
}
Imports
El código comienza incluyendo los archivos de cabecera de la librería AudioTools. Estos proporcionan las clases y funciones necesarias para gestionar fuentes de audio, decodificar archivos MP3 y transmitir audio por I2S.
#include "AudioTools.h" #include "AudioTools/Disk/AudioSourceSD.h" #include "AudioTools/AudioCodecs/CodecMP3Helix.h"
Constantes
A continuación, se definen los pines conectados al amplificador MAX98357. Estos especifican la entrada de datos I2S (MAX_DIN), selección de palabra o left-right clock (MAX_LRC) y bit clock (MAX_BCLK) en el ESP32.
#define MAX_DIN 33 #define MAX_LRC 32 #define MAX_BCLK 25
Además, se establecen constantes para la ruta de la fuente de audio y la extensión de archivo. Aquí, PATH es el directorio raíz de la tarjeta SD y EXT especifica que solo se tendrán en cuenta archivos MP3.
#define PATH "/" #define EXT "mp3"
Objetos
Se instancian varios objetos para gestionar la cadena de reproducción de audio. AudioSourceSD representa la fuente de audio de la tarjeta SD, filtrando archivos por la ruta y extensión especificadas. I2SStream gestiona el stream de salida de audio I2S. MP3DecoderHelix es el decodificador MP3 basado en el códec Helix. Por último, AudioPlayer une estos componentes para gestionar la reproducción.
AudioSourceSD source(PATH, EXT); I2SStream i2s; MP3DecoderHelix decoder; AudioPlayer player(source, i2s, decoder);
Función de callback de metadatos
La función printMetaData() se define para manejar información de metadatos como artista o título de la pista. Recibe el tipo de metadato y la cadena, y la imprime en la consola serie para depuración o información.
void printMetaData(MetaDataType type, const char* str, int len){
Serial.printf("%s: %s\n", toStr(type), str);
}
Función setup
En la función setup() se inicializa la comunicación serie a 115200 baudios para el registro. También se inicia el logger de AudioTools con nivel de advertencia para capturar mensajes importantes.
La configuración I2S se obtiene de los ajustes por defecto para el modo transmisión. Los pines para bit clock, selección de palabra y datos se asignan a las constantes definidas previamente correspondientes a las conexiones del MAX98357. El stream I2S se inicializa con esta configuración.
Opcionalmente, se puede establecer un filtro de archivos en la fuente de audio para reproducir solo archivos que coincidan con un patrón (comentado en este ejemplo). El callback de metadatos se asigna a la función printMetaData() para recibir metadatos durante la reproducción. El volumen se ajusta al 40% para controlar la salida. Por último, se inicia el reproductor de audio.
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
auto cfg = i2s.defaultConfig(TX_MODE);
cfg.pin_bck = MAX_BCLK;
cfg.pin_ws = MAX_LRC;
cfg.pin_data = MAX_DIN;
i2s.begin(cfg);
//source.setFileFilter("*Bob Dylan*");
player.setMetadataCallback(printMetaData);
player.setVolume(0.4);
player.begin();
}
Función loop
La función loop() llama continuamente a player.copy(), que gestiona el streaming de audio desde la tarjeta SD a través del decodificador y por I2S al amplificador. Esto mantiene la reproducción de audio funcionando sin bloquear otros procesos.
void loop() {
player.copy();
}
Si quieres añadir más funciones como un controlador de volumen y botones para saltar pistas, consulta el Playing Audio with ESP32 and PCM5102A tutorial.
Reproducir audio por Bluetooth
Este ejemplo muestra cómo transmitir audio por Bluetooth. El código configura la interfaz I2S con pines específicos e inicializa un receptor Bluetooth A2DP, permitiendo que el ESP32 reciba y reproduzca audio desde dispositivos Bluetooth.
/*
www.makerguides.com
Libraries:
- ESP32 Core 2.0.17
- [arduino-audio-tools](https://github.com/pschatzmann/arduino-audio-tools)
Version: 1.2.2
- [arduino-libhelix](https://github.com/pschatzmann/arduino-libhelix)
Version: 0.9.2
- [ESP32-A2DP](https://github.com/pschatzmann/ESP32-A2DP)
Version: 1.8.8
*/
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
#define MAX_DIN 33 // serial data
#define MAX_LRC 32 // word select
#define MAX_BCLK 25 // serial clock
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
void setup() {
auto cfg = i2s.defaultConfig();
cfg.pin_bck = MAX_BCLK;
cfg.pin_ws = MAX_LRC;
cfg.pin_data = MAX_DIN;
i2s.begin(cfg);
a2dp_sink.start("MyMusic");
}
void loop() { }
Imports
El código comienza incluyendo dos librerías importantes. La librería AudioTools.h proporciona herramientas para gestionar streams de audio y configurar la interfaz I2S. La librería BluetoothA2DPSink.h permite que el ESP32 actúe como receptor Bluetooth A2DP, es decir, puede recibir streams de audio desde fuentes Bluetooth como smartphones.
#include "AudioTools.h" #include "BluetoothA2DPSink.h"
Constantes
A continuación, se definen tres constantes para especificar los pines GPIO usados para la interfaz I2S. Estos pines conectan el ESP32 al amplificador MAX98357. MAX_DIN es el pin de entrada de datos serie, MAX_LRC es el pin de selección de palabra o left-right clock, y MAX_BCLK es el pin de reloj serie.
#define MAX_DIN 33 // serial data #define MAX_LRC 32 // word select #define MAX_BCLK 25 // serial clock
Objetos
Se crea un objeto I2SStream llamado i2s para gestionar el stream de audio I2S. Luego, se instancia un objeto BluetoothA2DPSink llamado a2dp_sink, pasándole el objeto i2s. Esta configuración enlaza la entrada de audio Bluetooth directamente a la salida I2S, permitiendo la reproducción de audio sin interrupciones a través del amplificador.
I2SStream i2s; BluetoothA2DPSink a2dp_sink(i2s);
Función setup
Dentro de la función setup(), se configura e inicia la interfaz I2S. Primero, se obtiene la configuración I2S por defecto llamando a i2s.defaultConfig(). Luego, se asignan los pines para bit clock (pin_bck), selección de palabra (pin_ws) y entrada de datos (pin_data) a las constantes definidas previamente. Finalmente, la interfaz I2S se inicializa con esta configuración llamando a i2s.begin(cfg).
Después de configurar I2S, se inicia el receptor Bluetooth A2DP con el nombre de dispositivo "MyMusic". Este nombre aparecerá cuando otros dispositivos Bluetooth busquen receptores de audio disponibles.
void setup() {
auto cfg = i2s.defaultConfig();
cfg.pin_bck = MAX_BCLK;
cfg.pin_ws = MAX_LRC;
cfg.pin_data = MAX_DIN;
i2s.begin(cfg);
a2dp_sink.start("MyMusic");
}
Para probarlo, abre tu móvil, busca «dispositivos conectados» o «dispositivos Bluetooth», busca el dispositivo «MyMusic», conéctate a él y luego reproduce música. Deberías escucharla a través de tu ESP32 y MAX98357.
Función loop
La función loop() está vacía porque todo el streaming y la reproducción de audio se gestionan de forma asíncrona por el receptor Bluetooth A2DP y la interfaz I2S. Una vez iniciado, el ESP32 escucha continuamente streams de audio Bluetooth y los saca por I2S al amplificador sin requerir más código en el bucle principal.
void loop() { }
Conclusiones
En este proyecto, aprendiste cómo reproducir audio usando el ESP32 y el amplificador MAX98357. Vimos los detalles técnicos del módulo MAX98357A y cómo conectarlo al ESP32 para sonido mono o estéreo. También aprendiste a convertir texto a voz, escuchar radio por internet, reproducir archivos MP3 desde una tarjeta SD y reproducir audio por Bluetooth.
Si quieres añadir más funciones como un controlador de volumen y botones para saltar pistas, consulta nuestro Playing Audio with ESP32 and PCM5102A tutorial. Igualmente, si necesitas más información sobre el módulo lector de tarjetas SD usado aquí, échale un vistazo al SD Card Module with ESP32 tutorial.
Para un sonido mejor y más potente puedes usar el DAC PCM5102A y añadir un amplificador. Consulta los siguientes tutoriales para más información:
- TDA7379 Class AB Audio Amplifier with ESP32
- High-Power ESP32 Audio with TPA3116D2 and PCM5102
- Audio with PAM8403, PCM5102 and ESP32
- Stereo Amplifier with TPA31110 XH-A232, PCM5102 and ESP32
- Playing Audio with ESP32 and MAX98357
Si tienes alguna pregunta, siéntete libre de dejarla en los comentarios.
¡Feliz cacharreo ; )
FAQ
P: ¿Qué es el MAX98357A y por qué debería usarlo?
El MAX98357A es un amplificador de audio digital con DAC integrado, lo que significa que toma audio digital directamente del ESP32 usando I2S y entrega una señal ya amplificada que puede alimentar un altavoz sin necesidad de un amplificador extra, haciendo el circuito más simple y mejorando la calidad de sonido respecto al DAC interno del ESP32.
P: ¿Cómo se conecta el MAX98357A al ESP32?
El módulo usa tres señales I2S más alimentación.
Cableado típico:
ESP32_3V3 or 5V ----> VIN ESP32_GND ---------> GND ESP32_GPIO25 -----> BCLK ESP32_GPIO32 -----> LRC ESP32_GPIO33 -----> DIN
El ESP32 actúa como maestro I2S y envía los datos de audio, mientras el MAX98357A los recibe y los convierte en sonido.
P: ¿Puedo conectar un altavoz directamente al MAX98357A?
Sí, porque el MAX98357A ya incluye una etapa de amplificación, así que puedes conectar un altavoz directamente.
SPK+ ---- Speaker ---- SPK-
Los altavoces típicos son de 4Ω a 8Ω, 3W o más. El amplificador puede entregar unos 3W de potencia, suficiente para altavoces pequeños.
P: ¿Cómo obtengo sonido estéreo?
El MAX98357A es mono, así que para estéreo necesitas dos módulos.
ESP32 --> 2x MAX98357A --> 2x Speakers
Ambos módulos comparten las mismas señales I2S, pero usan resistencias para seleccionar los canales izquierdo y derecho.
SD -- 100kΩ -- 3.3V (left channel) SD -- 210kΩ -- 3.3V (right channel)
Así, cada amplificador reproduce un canal.
P: ¿Qué fuente de alimentación debo usar?
El módulo funciona con 3,3V o 5V, pero la alimentación es importante para un buen sonido. A volumen alto, el módulo puede consumir mucha corriente, así que alimentarlo desde el pin de 3,3V del ESP32 a menudo no es suficiente y puede causar distorsión o reinicios.
P: ¿Cómo puedo mejorar la calidad de sonido con filtrado de alimentación?
Una alimentación limpia es fundamental, porque el ruido afecta directamente la salida de audio. Puedes añadir condensadores:
VIN -- 100nF -- GND VIN -- 100µF -- GND
El condensador pequeño elimina el ruido de conmutación rápido, mientras que el grande suaviza el rizado de voltaje y previene caídas durante picos de audio fuertes.
Además puedes usar un condensador de filtrado:
5V -- 10Ω --+-- AMP_VIN | 220µF | GND
Esto reduce el ruido de USB o reguladores conmutados.
P: ¿Debo usar una fuente de alimentación externa?
Sí, especialmente para volumen alto, porque el MAX98357A puede consumir corrientes altas al reproducir audio fuerte, y el regulador del ESP32 puede no soportarlo de forma fiable.
External 5V ----> MAX98357A ESP32_GND ------> Shared GND
Esto mejora la estabilidad y reduce la distorsión.
P: ¿Cómo puedo aumentar el volumen?
El volumen depende de tres factores principales: voltaje de alimentación, ganancia del amplificador y tipo de altavoz. Para aumentar el volumen:
- Usa 5V en vez de 3,3V
- Usa un altavoz de menor impedancia (4Ω en vez de 8Ω)
Un altavoz de 4Ω consume más potencia y produce más volumen, pero también aumenta la carga sobre el amplificador.
P: ¿Qué es el pin GAIN y cómo afecta al sonido?
El pin GAIN ajusta el nivel de ganancia del amplificador.
GAIN -- GND (lower gain) GAIN -- VCC (higher gain) GAIN -- FLOAT (default)
Una ganancia mayor aumenta el volumen pero también puede aumentar el ruido y la distorsión, así que a menudo es mejor empezar con ganancia baja y ajustar por software.
P: ¿Por qué escucho ruido o siseo incluso cuando no hay audio?
El ruido puede venir de varias fuentes como rizado de alimentación, mala conexión a tierra o interferencias del ESP32. Soluciones comunes:
- Añade condensadores de desacoplo
- Usa una fuente de alimentación externa limpia
- Mantén los cables cortos
P: ¿Qué prácticas de cableado mejoran la calidad de sonido?
Un buen cableado es muy importante, especialmente para audio digital y amplificadores conmutados. Mantén los cables cortos:
ESP32 --> MAX98357A (short lines)
y usa conexión a tierra en estrella:
ESP32_GND ----+---- AMP_GND | POWER_GND
Evita pasar los cables de altavoz cerca de los de señal, porque las señales de conmutación de alta corriente pueden introducir ruido.
P: ¿Qué formatos de audio y funciones se soportan?
El MAX98357A soporta los formatos de audio digital típicos usados con ESP32.
- Audio de 16, 24 o 32 bits
- Tasas de muestreo de 8 kHz a 96 kHz

