En este post te enseñaré a reproducir un sonido estático usando la ESP32-CAM y el amplificador Max98357A usando I2S.
El audio reproducido será uno que guardaremos en la propia flash de la ESP32-CAM. Esto es para hacer una prueba rápida y comprobar que las conexiones son correctas, que el Max98357a funciona, que el altavoz está bien y que la ESP32-CAM está en perfectas condiciones.
Compatibilidad de pines
Estuve haciendo pruebas con los pines y estos son los resultados.
| GPIO | Probado con | Notas Adicionales |
|---|---|---|
| 16 | Todos | Compatible con todos |
| 0 | BCLK | No probado con los demás |
| 3 | LRC | No probado con los demás |
| 1 | Todos | Compatible con todos |
| 12 | Todos | Compatible con todos |
| 13 | LRC y BCLK | Compatible solo con LRC y BCLK |
| 15 | BCLK | No probado con los demás |
| 14 | BCLK | No probado con los demás |
| 2 | BCLK | No probado con los demás |
| 4 | LRC | No probado con los demás, también enciende el flash |
Si quieres usar Serial pero no usar la SD entonces usa los pines 13, 12 y 15, solo ten cuidado con el DIN
Conexión
Los pines quedan como se ve a continuación. Toma en cuenta que yo no uso la SD ni la comunicación Serial, por lo que soy libre de usar todos los pines de arriba y estos de la tabla.
| ESP32-CAM | MAX98357A | Definición en código |
|---|---|---|
| GPIO 1 UOT | DIN | I2S_DOUT_AMPLIFICADOR |
| GPIO 2 | BCLK | I2S_BCLK_AMPLIFICADOR |
| GPIO 16 | LRC | I2S_LRC_AMPLIFICADOR |
| GND | GND | |
| VCC | VIN |
Código fuente
El archivo sonidos.h queda así. Solo debes cambiar el sonido y la longitud usando https://notisrac.github.io/FileToCArray/
Asegúrate de cambiar longitudSonidoFotoEnviadaExitosamente con lo que la
herramienta te diga en array size is tamaño
#include <Arduino.h>
// array size is 38694
const int longitudSonidoFotoEnviadaExitosamente = 38694;
static const byte sonido_reproducir_foto_enviada_exitosamente[] PROGMEM = {
0x52, 0x49, 0x46, 0x46, 0x1e, 0x97, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
/**Aquí más bytes que no pondré. Sácalos tú mismo */
};
Y el main.cpp queda así:
#include <Arduino.h>
#include "driver/i2s.h"
#include "sonidos.h"
#define I2S_DOUT_AMPLIFICADOR 1
#define I2S_BCLK_AMPLIFICADOR 2
#define I2S_LRC_AMPLIFICADOR 16
#define SAMPLE_RATE 8000
#define BITS_PER_SAMPLE 16
#define PIN_I2S_AMPLIFICADOR I2S_NUM_0
#define LONGITUD_HEADER_WAV 44
void inicializar_i2s_amplificador()
{
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_t)BITS_PER_SAMPLE,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = 64,
.use_apll = true,
};
i2s_pin_config_t pin_config = {
.bck_io_num = I2S_BCLK_AMPLIFICADOR,
.ws_io_num = I2S_LRC_AMPLIFICADOR,
.data_out_num = I2S_DOUT_AMPLIFICADOR,
.data_in_num = I2S_PIN_NO_CHANGE};
esp_err_t err = i2s_driver_install(PIN_I2S_AMPLIFICADOR, &i2s_config, 0, NULL);
if (err != ESP_OK)
{
// Serial.printf("Error al instalar I2S amp: %d\n", err);
}
err = i2s_set_pin(PIN_I2S_AMPLIFICADOR, &pin_config);
if (err != ESP_OK)
{
// Serial.printf("Error al configurar pines amp: %d\n", err);
}
// Serial.println("Driver I2S instalado y configurado amp");
}
void reproducirSonidoEstatico()
{
size_t bytes_faltantes = longitudSonidoFotoEnviadaExitosamente - LONGITUD_HEADER_WAV;
size_t bytes_reproducidos;
esp_err_t err = i2s_write(
PIN_I2S_AMPLIFICADOR,
/*Aquí avanzamos 44 bytes para omitir el header WAV*/
sonido_reproducir_foto_enviada_exitosamente + LONGITUD_HEADER_WAV,
longitudSonidoFotoEnviadaExitosamente - LONGITUD_HEADER_WAV,
&bytes_reproducidos,
portMAX_DELAY);
if (err != ESP_OK)
{
// Serial.printf("Error al escribir I2S: %d\n", err);
}
else if (bytes_reproducidos != bytes_faltantes)
{
// Serial.printf("Advertencia: No se escribieron todos los bytes. Escritos: %u / Total: %u\n", bytes_reproducidos, bytes_faltantes);
}
else
{
// Serial.println("Reproducción de WAV completada.");
}
}
void setup()
{
// Serial.begin(115200);
// Serial.println("Hola setup");
ledcSetup(0, 5000, 8);
ledcAttachPin(4, 0);
inicializar_i2s_amplificador();
}
void loop()
{
ledcWrite(0, 0);
reproducirSonidoEstatico();
ledcWrite(0, 1);
delay(500);
}
Platformio.ini
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32cam]
platform = espressif32
board = esp32cam
framework = arduino
monitor_speed=115200
monitor_rts = 0
monitor_dtr = 0
Reproducir sonido estático con ESP32-CAM
Al cargar y ejecutar el código en la ESP32-CAM se va a reproducir el sonido estático en formato WAV cada medio segundo.
Con esto podrás comprobar si la ESP32-CAM funciona correctamente así como su puerto I2S para el amplificador.
Por cierto, ten cuidado al usar I2S_NUM_0 para tus conexiones
si también usas la cámara integrada OV2640 porque si usas la cámara
no puedes usar el I2S_NUM_0, debes usar el I2S_NUM_1 como
lo comprobé al
transmitir el audio y video de la ESP32-CAM al mismo tiempo