I2S 音频实战:麦克风录音与 MP3 播放
📅 2026-05-21 · 📂 硬件编程 · ⏱ 阅读约 5 分钟
📺 B站推荐视频:ESP32之播放WAV音频文件(使用I2S)
概述
让 ESP32 能听会说。I2S(Inter-IC Sound)是数字音频传输的标准接口,通过 I2S 麦克风录音、I2S 功放播放,实现语音助手、MP3 播放器、对讲机等功能。
物料清单
| 物料 | 型号/参数 | 参考价格 |
|---|
| I2S 麦克风 | INMP441 MEMS 全向麦克风 | ~8元 |
| I2S 功放 | MAX98357A 3W D类功放 | ~6元 |
| 喇叭 | 3W 4Ω 小喇叭(直径 28-40mm) | ~5元 |
| ESP32 开发板 | ESP32-S3(推荐,SRAM 更大) | ~20元 |
| 杜邦线 | 母对母 10cm 6根 | ~3元 |
接线图(I2S 共享总线)
🔌 接线
ESP32 GPIO INMP441 MAX98357A
GPIO26 (BCLK) SCK BCLK
GPIO25 (LRC) WS LRC
GPIO33 (DIN) SD —
GPIO32 (DOUT) — DIN
3.3V VDD VIN
GND GND GND
⚠️ INMP441 的 L/R 引脚接地(左声道)
⚠️ MAX98357 的 SD 引脚接GPIO使能, GAIN悬空=9dB
基础代码:SD 卡 MP3 播放器
// 用 ESP8266Audio 库播放 MP3
#include "Audio.h"
#include "SD.h"
Audio audio;
void setup() {
SD.begin();
audio.setPinout(26, 25, 32); // BCLK, LRC, DOUT
audio.setVolume(12); // 0-21
audio.connecttoFS(SD, "/song.mp3");
}
void loop() { audio.loop(); }
进阶:I2S 麦克风录音
// I2S 录音5秒
#include <driver/i2s.h>
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_STD_I2S,
.dma_buf_count = 8,
.dma_buf_len = 1024,
};
i2s_pin_config_t pin_config = {
.bck_io_num = 26, .ws_io_num = 25,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = 33,
};
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM_0, &pin_config);
int16_t samples[16000 * 5]; // 5秒缓冲
size_t bytes_read;
i2s_read(I2S_NUM_0, samples, sizeof(samples), &bytes_read, portMAX_DELAY);
// 写入WAV文件到SD卡...
实战场景一:离线语音助手
场景:说"开灯"就亮灯,说"温度"就播报温度。物料:ESP32-S3 + INMP441 + MAX98357 + 小喇叭,总成本不到 40 元。应用:用百度语音识别 API(免费 5 万次/天)或 ESP-SR(乐鑫离线识别),结合之前学的 GPIO 控制继电器开灯、DHT22 测温后 OLED 显示+TTS 语音播报。全栈联动:麦克风→百度ASR→语义理解→TFT显示+喇叭播报+WiFi上报云端。
实战场景二:DIY 对讲机
场景:两个 ESP32 通过 WiFi 互传语音,实现局域网对讲。应用:一方 I2S 录音→UDP 发送,另一方 UDP 接收→I2S 播放。延迟可做到 100ms 以内。物料:2 套 ESP32 + INMP441 + MAX98357 + 喇叭,总成本不到 80 元。
常见问题
⚠️ 录音全是噪音 — 确认 INMP441 的 L/R 引脚接地(左声道),否则数据错位。
⚠️ 播放无声 — MAX98357 的 SD 引脚需拉高使能,GAIN 引脚不能悬空。
⚠️ ESP32-S3 上 I2S 冲突 — I2S_NUM_0 可能被 TFT 占用,试试 I2S_NUM_1。