💡 划重点
- 主控芯片:ESP32
- 音频输入:INMP441 I2S 数字麦克风
- 音频输出:MAX98357A I2S 功放模块
- 本地存储:MicroSD 卡
- 交互方式:拼图触点触发录音与复读
- 使用场景:儿童语言启蒙、拼图游戏即时语音反馈
- 目标成本:85 元以内
需求洞察
目标用户是 3—6 岁儿童及其家长。这个阶段孩子处于语言模仿敏感期,喜欢重复发音,也喜欢动手拼接玩具。传统拼图玩具完成之后缺少声音反馈,孩子容易失去兴趣;家长希望玩具能引导孩子开口,并即时复读孩子的发音,帮助纠正和模仿。
真实痛点有三:普通拼图安静无声,完成拼图后没有鼓励语音;家长无法时刻陪练发音;带联网功能的智能玩具价格偏高且涉及隐私。本项目用 ESP32 加本地 SD 卡实现离线的“录—存—播”闭环,成本低、无隐私风险,值得作为儿童教育硬件原型进行开发。
方案设计
感知层:由 INMP441 数字麦克风采集儿童短语音;同时将拼图块位置映射为多个 GPIO 输入,通过触碰开关或导电触点检测拼图是否放到位。
控制层:ESP32 作为主控,负责麦克风 I2S 输入、扬声器 I2S 输出、SD 卡读写和拼图触点状态判断。录音时通过 I2S 外设将麦克风数据写入 SD 卡形成 WAV 文件;播放时读取 SD 卡文件并发送给 MAX98357A。
执行层:MAX98357A 是 I2S D 类功放模块,可直接驱动 3W 小扬声器,播放复读语音和鼓励提示音。
日志/联网层:SD 卡保存每次触发时间、录音文件名和拼图编号,便于家长查看学习记录;ESP32 本身支持 Wi-Fi,后续可扩展为可选联网上报,但不作为基础功能。
物料清单
| 物料 | 数量 | 用途 | 估算单价(元) | 小计(元) |
|---|---|---|---|---|
| ESP32 DevKitC 开发板 | 1 | 主控 | 22 | 22 |
| MAX98357A 模块 | 1 | 音频功放输出 | 7 | 7 |
| INMP441 麦克风模块 | 1 | 语音采集 | 10 | 10 |
| MicroSD 卡模块 | 1 | 音频存储接口 | 4 | 4 |
| 16GB TF 卡 | 1 | 保存录音与日志 | 13 | 13 |
| 3W 8Ω 小扬声器 | 1 | 复读发声 | 4 | 4 |
| 轻触开关或导电触点 | 6 | 拼图块触发输入 | 6 | 6 |
| TP4056 锂电池充电模块 | 1 | 充电管理 | 3 | 3 |
| 603040 锂电池 | 1 | 供电 | 9 | 9 |
| 洞洞板、线材、电阻 | 1 | 连接与固定 | 6 | 6 |
合计:84 元,符合 85 元目标成本。
接线与结构
使用给定的 GPIO,并对麦克风接口保持 32、33、35 不变。SD 卡走 SPI,避免与 I2S 引脚冲突。
| 模块 | 信号 | ESP32 GPIO |
|---|---|---|
| MAX98357A | BCLK | 26 |
| MAX98357A | LRC | 25 |
| MAX98357A | DIN | 22 |
| MAX98357A | VIN/GND | 5V/GND |
| INMP441 | SCK | 32 |
| INMP441 | WS | 33 |
| INMP441 | SD | 35 |
| INMP441 | L/R | GND |
| SD 卡 | CS/MOSI/MISO/SCK | 5/23/19/18 |
| 拼图触点 1—6 | 输入 | 13/14/27/12/15/4 |
微调说明:麦克风使用 32、33、35 是因为这三个脚靠近 ESP32 的 I2S 外设,便于布线,同时避开 SD 卡 SPI 与启动引脚。拼图触点使用上拉输入,公共端接 GND,按下时输入低电平。
核心代码
采用 Arduino/PlatformIO 骨架,便于直接编译验证。
#include <Arduino.h>
#include <SD.h>
#include <SPI.h>
#include <driver/i2s.h>
#define I2S_BCLK 26
#define I2S_LRC 25
#define I2S_DIN 22
#define MIC_SCK 32
#define MIC_WS 33
#define MIC_SD 35
#define SD_CS 5
#define TRIG_PIN 13
void setup() {
Serial.begin(115200);
if (!SD.begin(SD_CS)) {
Serial.println("SD错误");
}
i2s_config_t mic_cfg = {
.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_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 256
};
i2s_pin_config_t mic_pin = {
.bck_io_num = MIC_SCK,
.ws_io_num = MIC_WS,
.data_in_num = MIC_SD,
.data_out_num = I2S_PIN_NO_CHANGE
};
i2s_driver_install(I2S_NUM_0, &mic;_cfg, 0, NULL);
i2s_set_pin(I2S_NUM_0, &mic;_pin);
i2s_config_t spk_cfg = mic_cfg;
spk_cfg.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX);
i2s_pin_config_t spk_pin = {
.bck_io_num = I2S_BCLK,
.ws_io_num = I2S_LRC,
.data_out_num = I2S_DIN,
.data_in_num = I2S_PIN_NO_CHANGE
};
i2s_driver_install(I2S_NUM_1, &spk;_cfg, 0, NULL);
i2s_set_pin(I2S_NUM_1, &spk;_pin);
}
void loop() {
if (digitalRead(TRIG_PIN) == LOW) {
File rec = SD.open("/last.wav", FILE_WRITE);
if (rec) {
rec.close();
Serial.println("录音文件已创建");
}
delay(500);
}
delay(20);
}
调试步骤
- 先检查 3.3V 与 5V 供电是否正常,确认锂电池电压不低于 3.6V。
- 单独测试 SD 卡,上电后串口应无“SD错误”输出。
- 测试扬声器通路,向 MAX98357A 写入测试数据,听是否有提示音。
- 测试麦克风通路,用串口打印一次 I2S 读取的数据长度,确认非零。
- 按下拼图触点,串口应能识别低电平并创建录音文件。
- 联调录音与复读,确认 SD 卡中 last.wav 能正常写入并被播放。