摘要:本文主要介绍开发板搭配的语音底座(Atomic Voice Base)的使用方法,实现一个通过串口输入任意按键开始/停止录制音频,并实时显示当前录制时长的录音机功能;
一、硬件介绍
产品特点
AtomS3R-CAM AI Chatbot 套件由控制器与语音底座两大核心部分组成;
控制器部分采用AtomS3R-CAM (集成0.3MP GC0308摄像头、9轴IMU、IR发射管等);
语音底座部分采用Atomic Voice Base (基于ES831音频编解码芯片);


主要特性
集成 ESP32-S3-PICO-1-N8R8 主控
0.3MP GC0308 摄像头
九轴传感器系统
8MB Flash 和 8MB PSRAM
集成红外发射管
可扩展的引脚与接口
全双工 I2S 语音
MEMS 数字麦克风
功能引脚示意图


二、功能实现
1、硬件介绍
Atomic Voice Base 是一款专为 M5 Atom 系列主机设计的语音识别底座,采用了ES8311单声道音频解码器、MEMS麦克风和NS4150B功率放大器,该设备支持全双工通信;

主要特性
单声道音频编解码
MEMS 麦克风
D类功放扬声器
引脚原理图
MIC / Speaker:Atomic Voice Base 麦克风支持的采样率范围为 16KHz-64KHz;

特性

实物效果搭建

2、功能效果
1、安装Arduino 底座驱动库


功能:通过串口输入任意按键开始/停止录制音频,并实时显示当前录制时长的录音机效果;
按任意键 → 开始录制
再次按任意键 → 停止录制
按任意键 → 播放录制内容
循环到第1步 (若录制达到60秒自动停止,循环至第3步)
三、代码编写
相关代码
#include <M5Unified.h>
#include <M5EchoBase.h>
// 音频参数配置
#define SAMPLE_RATE 16000
#define MAX_RECORD_SECONDS 60
#define MIC_GAIN ES8311_MIC_GAIN_6DB
M5EchoBase echobase;
static uint8_t *buffer = nullptr;
static uint32_t actual_record_size = 0;
static uint32_t actual_record_seconds = 0;
// 等待按键按下
void waitForKeyPress(const char *prompt) {
Serial.println(prompt);
while (!Serial.available()) {
M5.update();
delay(10);
}
while (Serial.available()) { Serial.read(); }
}
// 检查是否有按键按下
bool isKeyPressed() {
if (Serial.available()) {
while (Serial.available()) { Serial.read(); }
return true;
}
return false;
}
void setup() {
auto cfg = M5.config();
cfg.serial_baudrate = 115200;
M5.begin(cfg);
delay(1000);
while (Serial.available()) { Serial.read(); }
// 初始化 EchoBase
Serial.print("正在初始化 EchoBase... ");
if (!echobase.init(SAMPLE_RATE, 38, 39, 7, 6, 5, 8, Wire)) {
Serial.println("初始化失败!");
while (true) { delay(1000); }
}
Serial.println("初始化成功!");
echobase.setSpeakerVolume(70);
echobase.setMicGain(MIC_GAIN);
echobase.setMute(true);
uint32_t buffer_size = echobase.getBufferSize(MAX_RECORD_SECONDS, SAMPLE_RATE);
// 检查内存
size_t psram_free = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
if (psram_free < buffer_size) {
Serial.printf("PSRAM 不足!需要: %d, 可用: %d\n", buffer_size, psram_free);
while (true) { delay(1000); }
}
buffer = (uint8_t *)malloc(buffer_size);
if (!buffer) {
Serial.println("内存分配失败!");
while (true) { delay(1000); }
}
Serial.printf("缓冲区分配成功 (%.1f KB)\n", buffer_size / 1024.0);
Serial.println("\n===== 功能说明 =====");
Serial.println("1. 按任意键 → 开始录制");
Serial.println("2. 按任意键 → 停止录制");
Serial.println("3. 按任意键 → 播放录制内容");
Serial.println("4. 循环到第1步");
Serial.println("(录制达到60秒自动停止,进入第3步)");
Serial.println("====================\n");
}
void loop() {
waitForKeyPress("按任意键开始录制...");
Serial.println("\n===== 开始录制 =====");
Serial.println("(按任意键停止,最长60秒)");
echobase.setMute(true);
delay(50);
// 每次录制前重置
actual_record_size = 0;
actual_record_seconds = 0;
bool stopped_by_user = false;
uint32_t chunk_size = echobase.getBufferSize(1, SAMPLE_RATE);
uint8_t *chunk_buffer = (uint8_t *)malloc(chunk_size);
if (!chunk_buffer) {
Serial.println("分段缓冲区分配失败!");
return;
}
while (actual_record_seconds < MAX_RECORD_SECONDS) {
if (!echobase.record(chunk_buffer, chunk_size)) {
Serial.println("录音失败!");
free(chunk_buffer);
return;
}
memcpy(buffer + actual_record_size, chunk_buffer, chunk_size);
actual_record_size += chunk_size;
actual_record_seconds++;
Serial.printf("录制中: %d 秒\n", actual_record_seconds);
if (isKeyPressed()) {
stopped_by_user = true;
Serial.println("检测到按键,停止录制!");
break;
}
}
free(chunk_buffer);
if (actual_record_seconds >= MAX_RECORD_SECONDS && !stopped_by_user) {
Serial.println("已达到最大录制时长 (60秒)");
}
Serial.printf("录制完成: %d 秒, %d 字节 (%.1f KB)\n",
actual_record_seconds, actual_record_size, actual_record_size / 1024.0);
Serial.printf("PSRAM 剩余: %.1f MB\n\n",
heap_caps_get_free_size(MALLOC_CAP_SPIRAM) / (1024.0 * 1024.0));
if (actual_record_size == 0) {
Serial.println("没有录制任何内容\n");
return;
}
waitForKeyPress("按任意键播放录音...");
Serial.println("\n===== 开始播放 =====");
echobase.setMute(false);
delay(50);
if (!echobase.play(buffer, actual_record_size, false)) {
Serial.println("播放失败!");
echobase.setMute(true);
return;
}
Serial.println("播放完成!\n");
echobase.setMute(true);
delay(200);
}四、程序烧录
1、连接USB数据线至开发板;
2、选择端口号对应的开发板;
3、点击 上传 烧录程序到开发板上;

五、效果演示

我要赚赏金
