💡 划重点
- 主控与核心模块:ESP32 + MAX98357A 功放 + INMP441 数字麦克风 + MicroSD 卡
- 使用场景:儿童早教拼图游戏,每拼对一块拼图,机器人复读孩子刚才说出的单词或短句
- 实现方式:轻触开关检测拼图槽位是否压入,麦克风录制 3 秒语音存入 SD 卡,拼图事件触发立即回放
- 成本控制:全部物料约 53 元,远低于 85 元目标,使用面包板加 3D 打印外壳,无需额外扩展板
- 编程框架:Arduino + ESP32 I2S 全双工模式,代码清晰,适合硬件编程入门
需求洞察
目标用户:3~6 岁学龄前儿童及其家长,特别是有英语启蒙或语言发育需求的家庭。
真实痛点:传统木质拼图只有图形配对,缺乏语言反馈,孩子易觉得枯燥;市面上的有声拼图价格较高(百元以上),且内容固定,不能输入自己的声音。家长希望有一种低成本、可自定义、能鼓励孩子开口说的教具。
为什么值得做:语音复读结合拼图动作,能同时刺激听觉、触觉和运动记忆,形成“发音‑拼图完成‑听到回声”的正向循环。孩子为听到自己的声音被复读,更愿意主动发音,练习发音准确度。整套方案只采用通用音频模块,家长可自行录制方言、英语或绘本角色对话,极大扩展使用场景。
方案设计
感知层
- 拼接检测:在每一块拼图底部安装一个轻触开关(微动开关),当拼图块压入正确位置时,开关导通,ESP32 检测 GPIO 下降沿中断。
- 语音采集:INMP441 I2S 数字硅麦直接连接 ESP32 I2S‑0 输入通道,支持 16 kHz 单声道录音,拾音距离可达 30 cm。
- 存储:MicroSD 卡通过 SPI 方式连接,存放 WAV 格式的录音文件,文件名与拼图槽位编号对应(如 /slot1.wav)。
控制层
- 主控芯片:ESP32‑DevKitC(双核 Xtensa LX6),利用 FreeRTOS 双线程:一个线程负责音频流录放,另一个处理按钮中断与状态管理。
- 状态机:空闲→等待拼图匹配→进入录音模式(LED 闪烁)→等待释放或超时→保存文件→回放→返回空闲。
- I2S 全双工:BCLK 与 LRC 同时连接 INMP441 和 MAX98357A,数据线分用 DIN(输出)与 I2S 输入(GPIO32),实现硬件同步,避免软件转发延迟。
执行层
- 音频输出:MAX98357A 单声道 D 类功放驱动 4Ω 3W 喇叭,音量可调,音质满足儿童友好型高音清晰度。
- 提示反馈:板载 LED 指示录音/回放状态,并通过喇叭发出简短合成提示音“叮咚”。
日志/联网层(可选扩展)
- 目前版本不联网,本地完成录放,满足儿童隐私要求。未来可通过 ESP32 Wi‑Fi 将录音上传到家长手机 APP 做成长记录,或下载新词语包。本次不纳入成本。
物料清单
| 序号 | 物料名称 | 数量 | 用途 | 估算单价(元) |
|---|---|---|---|---|
| 1 | ESP32‑DevKitC | 1 | 主控制器,双核 240 MHz | 18 |
| 2 | MAX98357A 模块 | 1 | I2S D 类功放,驱动喇叭 | 5 |
| 3 | INMP441 数字麦克风模块 | 1 | I2S 输入,高灵敏度收音 | 6 |
| 4 | MicroSD 卡 SPI 模块 | 1 | 存储录音文件,带卡槽 | 3 |
| 5 | 8 GB MicroSD 卡 | 1 | 存放 WAV 文件 | 10 |
| 6 | 喇叭(4Ω 3W,直径 40mm) | 1 | 语音输出 | 5 |
| 7 | 轻触开关 | 4 | 拼图槽位检测(预留 4 个槽) | 0.25×4=1 |
| 8 | LED(5mm 红色) | 1 | 状态指示 | 0.2 |
| 9 | 电阻(220Ω) | 1 | LED 限流 | 0.1 |
| 10 | 面包板 + 跳线 | 1套 | 电路连接 | 5 |
| 11 | MicroUSB 供电线 | 1 | 供电 | 1 |
| 合计 | 53.3 |
成本控制在 85 元以内,剩余预算可用于 3D 打印拼图底板外壳。
接线与结构
接线原则:遵循给定的 I2S 引脚配置,并利用 ESP32 I2S‑0 的全双工能力,使 INMP441 和 MAX98357A 共享 BCLK 和 LRC,数据线各自独立。SD 卡使用 SPI 总线,避免引脚冲突。
| 功能 | ESP32 GPIO | 连接器件 | 说明 |
|---|---|---|---|
| I2S 位时钟 | 26 | MAX98357A BCLK, INMP441 SCK | 两者共用 BCLK |
| I2S 左右时钟 | 25 | MAX98357A LRC, INMP441 WS | LRC 决定采样频率(16 kHz) |
| I2S 数据输出 | 22 | MAX98357A DIN | 功放数据输入 |
| I2S 数据输入 | 32 | INMP441 SD | 麦克风数字输出,连接 ESP32 I2S 输入引脚 |
| SD 卡 SPI CS | 5 | SD 模块 CS | 片选 |
| SD 卡 SPI SCK | 18 | SD 模块 SCK | 时钟 |
| SD 卡 SPI MISO | 19 | SD 模块 MISO | 主入从出 |
| SD 卡 SPI MOSI | 23 | SD 模块 MOSI | 主出从入 |
| 拼图按钮 | 13 | 轻触开关(公共端接地) | 低电平有效,内部上拉 |
| 状态 LED | 15 | 经 220Ω 电阻到 LED 阳极 | 阴极接地 |
| 电源 | 5V/3.3V | ESP32 与模块 | ESP32 USB 供电,模块吸取 3.3V |
结构设计:将 ESP32 和模块放置在拼图底板下方,麦克风朝上开孔拾音,喇叭安装在侧方出音孔。4 个轻触开关直接焊接在拼图槽位的底部,用弹簧片保证拼图压入时可靠导通。
核心代码
采用 Arduino 框架,基于 ESP32 的 I2S 驱动和 SD 库,实现录音‑保存‑回放闭环。
#include <driver/i2s.h>
#include <SD.h>
#include <FS.h>
#define I2S_BCLK 26
#define I2S_LRC 25
#define I2S_DOUT 22
#define I2S_DIN 32
#define SD_CS 5
#define BUTTON 13
#define LED 15
// I2S 配置
const i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | 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_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = 512,
.use_apll = false,
};
const i2s_pin_config_t pin_config = {
.mck_io_num = I2S_PIN_NO_CHANGE,
.bck_io_num = I2S_BCLK,
.ws_io_num = I2S_LRC,
.data_out_num = I2S_DOUT,
.data_in_num = I2S_DIN,
};
void setup() {
Serial.begin(115200);
pinMode(BUTTON, INPUT_PULLUP);
pinMode(LED, OUTPUT);
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM_0, &pin_config);
if(!SD.begin(SD_CS)) Serial.println("SD 卡初始化失败");
}
void loop() {
if(digitalRead(BUTTON) == LOW) { // 拼图按下
digitalWrite(LED, HIGH);
recordWav("/slot1.wav", 3); // 录音 3 秒
digitalWrite(LED, LOW);
playWav("/slot1.wav"); // 回放
}
delay(100);
}
void recordWav(const char* path, int seconds) {
File file = SD.open(path, FILE_WRITE);
if(!file) return;
// 写入 WAV 头(简化,实际需 44 字节头)
uint8_t wavHeader[44] = { /* 读者补全 WAV 头 */ };
file.write(wavHeader, 44);
size_t bytesToRead = seconds * 16000 * 2; // 16-bit mono
int16_t sample;
while(bytesToRead--) {
size_t bytesRead;
i2s_read(I2S_NUM_0, &sample, sizeof(sample), &bytesRead, portMAX_DELAY);
file.write((uint8_t*)&sample, sizeof(sample));
}
file.close();
}
void playWav(const char* path) {
File file = SD.open(path);
if(!file) return;
file.seek(44); // 跳过 WAV 头
int16_t sample;
while(file.available()) {
file.read((uint8_t*)&sample, sizeof(sample));
size_t bytesWritten;
i2s_write(I2S_NUM_0, &sample, sizeof(sample), &bytesWritten, portMAX_DELAY);
}
file.close();
}
骨架代码给出了可编译的录音与回放核心,读者需补全 WAV 头结构,并调整录音时长,实际使用中可扩展多槽按钮。
调试步骤
- 基础检查:用万用表确认轻触开关在拼图压下时与 GND 导通,放开时悬空。
- I2S 输出测试:写一段循环播放 1 kHz 正弦波的代码,确认喇叭发出清晰单音,验证 MAX98357A 接线正确。
- 麦克风测试:将麦克风信号路由到同一条 I2S 总线的输出,对麦克风说话,检查喇叭是否传出自己的声音(旁路自测)。
- SD 卡读写:单独创建一个小文件,写入“Hello”,再读出并打印串口,确保 SPI 接线和卡格式正确。
- 按钮中断响应:通过串口监视 BUTTON 引脚状态,确保拼图触发时不会误触发多次。
- 完整流程:上电,压下轻触开关,LED 闪烁 3 秒,松开后立即听到复读,确认音质流畅无噪音。
设计图
儿童拼图机器人语音复读结构flow
1
感知输入
→
2
控制处理
→
3
执行反馈
→
4
数据上报