在 Arduino Due 上实现语音识别与语音合成 - BitVoicer Server 方案
组件与材料
| Arduino Due | ×1 |
| SparkFun 电容麦克风模块 | ×1 |
| SparkFun 单声道音频放大器模块 | ×1 |
| 扬声器: 0.25W, 8Ω | ×1 |
| 面包板 | ×1 |
| 5mm 红色 LED | ×3 |
| 330Ω 电阻 | ×3 |
| 杜邦线 | ×1 |
所需工具
- 电烙铁 (通用)
软件与服务
- BitVoicer Server 1.0 (付费软件, $9.90) - 核心语音识别/合成服务端
项目背景
承接上一项目(仅控制 LED),本项目进阶实现:利用 Arduino Due 内置 DAC 进行语音合成播放。若使用其他 Arduino 板,需外接 DAC 并修改代码(BVSSpeaker 库不支持)。
演示视频中展示:语音控制 LED、播放合成语音回复、甚至演奏一段钢琴曲(Jingle)并同步 LED 模拟琴键亮灭(对应 C、D、E 键时序)。
系统数据流向
- 电容麦克风采集音频 → SparkFun 放大模块放大
- Arduino Due ADC 采样数字化、缓冲
- 通过串口流式传输至 BitVoicer Server
- Server 识别语音内容,映射预定义指令
- 指令(含合成语音音频流)回传 Arduino
- Arduino 解析指令:控制 LED / 将音频流入队 BVSSpeaker 类
- Due DAC + DMA 播放音频 → SparkFun 放大器驱动 8Ω 扬声器
材料清单与成本估算
- Arduino Due: ~$50
- SparkFun 电容麦克风: $7.95
- SparkFun 单声道音频放大器: $7.95
- BitVoicer Server 1.0: $9.90
- 8Ω 扬声器: ~$2
- 面包板: ~$10
- 3×LED + 3×330Ω 电阻: ~$1.75
- 杜邦线: ~$0.50
步骤 1:硬件接线
按下图接线。扬声器底部垫小橡胶垫防震动影响音质。




关键电压提示: Due 工作电压 3.3V,建议将麦克风模块 VCC 接 3.3V。若用 5V 板(如 Uno),需在 3.3V 引脚与 AREF 引脚间跨接跳线作模拟参考电压。Due 已内部使用 3.3V 参考,无需跳线;且 Due 的 AREF 引脚通过电阻桥连接 MCU,使用前需拆除电阻 BR1。
步骤 2:上传 Arduino 代码
先在 Arduino IDE 导入 BitVoicer Server 库 (安装目录下的 .zip)。
代码结构 (BVS_Demo2.ino)
#include
#include
#include
#include
// 引脚定义
#define BVSM_AUDIO_INPUT 7
#define RED_LED_PIN 6
#define YELLOW_LED_PIN 9
#define GREEN_LED_PIN 10
// 通信参数
const unsigned long STATUS_REQUEST_TIMEOUT = 3000;
const unsigned long STATUS_REQUEST_INTERVAL = 4000;
const int MIC_BUFFER_SIZE = 64;
const int SPEAKER_BUFFER_SIZE = 128;
const int RECEIVE_BUFFER_SIZE = 2;
BVSP bvsp;
BVSMic bvsm;
BVSSpeaker bvss;
byte micBuffer[MIC_BUFFER_SIZE];
byte speakerBuffer[SPEAKER_BUFFER_SIZE];
byte receiveBuffer[RECEIVE_BUFFER_SIZE]; // [pin, value]
bool playLEDNotes = false;
unsigned int playStartTime = 0;
void setup() {
pinMode(RED_LED_PIN, OUTPUT); pinMode(YELLOW_LED_PIN, OUTPUT); pinMode(GREEN_LED_PIN, OUTPUT);
digitalWrite(RED_LED_PIN, LOW); digitalWrite(YELLOW_LED_PIN, LOW); digitalWrite(GREEN_LED_PIN, LOW);
Serial.begin(115200);
bvsp.begin(Serial, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL);
bvsp.frameReceived = BVSP_frameReceived;
bvsp.modeChanged = BVSP_modeChanged;
bvsp.streamReceived = BVSP_streamReceived;
bvsm.begin();
bvss.begin(DAC); // 使用 Due 内置 DAC
}
void loop() {
bvsp.keepAlive(); // 定时请求服务器状态
bvsp.receive(); // 处理接收帧/流
// 录音与上传
if (bvsp.isSREAvailable()) {
if (!bvsm.isRecording) { bvsm.setAudioInput(BVSM_AUDIO_INPUT, DEFAULT); bvsm.startRecording(); }
if (bvsm.available) {
if (bvsp.inboundMode == FRAMED_MODE) bvsp.setInboundMode(STREAM_MODE);
int bytesRead = bvsm.read(micBuffer, MIC_BUFFER_SIZE);
bvsp.sendStream(micBuffer, bytesRead);
}
} else {
if (bvsm.isRecording) bvsm.stopRecording();
}
bvss.play(); // 播放合成语音
if (playLEDNotes) playNextLEDNote(); // 同步 LED 与音乐
}
// 处理指令帧: 二进制数据控制LED(2字节:引脚,值), 字节255触发LED乐谱同步
void BVSP_frameReceived(byte dataType, int payloadSize) {
if (dataType == DATA_TYPE_BINARY) {
if (bvsp.getReceivedBytes(receiveBuffer, RECEIVE_BUFFER_SIZE) == RECEIVE_BUFFER_SIZE)
analogWrite(receiveBuffer[0], receiveBuffer[1]);
} else if (dataType == DATA_TYPE_BYTE) {
if (bvsp.getReceivedByte() == 255) { playLEDNotes = true; playStartTime = millis(); }
}
}
// 模式切换: 流模式→帧模式时停止播放
void BVSP_modeChanged() {
if (bvsp.outboundMode == FRAMED_MODE) bvss.finishPlaying();
}
// 接收音频流入队播放
void BVSP_streamReceived(int size) {
int bytesRead = bvsp.getReceivedStream(speakerBuffer, SPEAKER_BUFFER_SIZE);
bvss.enqueue(speakerBuffer, bytesRead);
}
// 根据时间轴同步点亮LED模拟钢琴键 (C/D/E)
void playNextLEDNote() {
unsigned long elapsed = millis() - playStartTime;
allLEDsOff();
if (elapsed >= 11500) { analogWrite(RED_LED_PIN, 0); playLEDNotes = false; }
else if (elapsed >= 9900) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 9370) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 8900) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 8610) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 8230) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 7970) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 7470) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 6760) analogWrite(GREEN_LED_PIN, 255); // E
else if (elapsed >= 6350) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 5880) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 5560) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 5180) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 4890) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 4420) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 3810) analogWrite(GREEN_LED_PIN, 255); // E
else if (elapsed >= 3420) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 2930) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 2560) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 2200) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 1930) analogWrite(YELLOW_LED_PIN, 255); // D
else if (elapsed >= 1470) analogWrite(RED_LED_PIN, 255); // C
else if (elapsed >= 1000) analogWrite(GREEN_LED_PIN, 255); // E
}
void allLEDsOff() {
analogWrite(RED_LED_PIN, 0); analogWrite(YELLOW_LED_PIN, 0); analogWrite(GREEN_LED_PIN, 0);
}
步骤 3:导入 BitVoicer Server 方案对象
BitVoicer Server 四大核心对象:
- Locations:物理位置,如 "Home"
- Devices:客户端设备,创建 Mixed 类型设备 "ArduinoDUE",**关键:限制 Data Rate 为 8000 samples/sec** 避免缓冲区溢出
- BinaryData:字节数组命令,每个 LED 开/关/亮度对应一个,共 18 个对象
- Voice Schemas:定义识别句子及触发命令序列、延时。例句 "play a little song" 包含两命令:先发字节 255 触发 LED 同步,再流式传输钢琴曲音频(8-bit mono PCM, 8kHz)
音频格式转换推荐:在线转 WAV (8-bit mono 8kHz)。
方案对象文件 (可直接导入):
Device.sof- 设备配置VoiceSchema.sof- 语音模式与命令
步骤 4:运行与总结
在 BitVoicer Server Manager 中启用 ArduinoDUE 设备,即开始流式识别。RX LED 闪烁指示上行音频流,TX LED 闪烁指示下行合成音频流。
下一项目计划:加入 WiFi 通信,一块主控 Arduino 语音控制多块从机,构建语音控制游戏系统。欢迎建议!
原理图

制造工艺
- 基于 Arduino 与 Python 的可靠 RFID 考勤系统
- DHT11 温湿度传感器项目:LED 指示与压电蜂鸣器报警
- 互动陀螺仪 LED 显示:NeoPixel Ring + Arduino Pro Mini
- Arduino Due 驱动 3.2″ TFT 实现温度监测与实时时钟
- Arduino + Android 蓝牙控制 Roomba Create 2 扫地机器人完整指南
- Arduino DIY 电压表:Nokia 5110 屏幕显示,手把手教学
- Arduino + MPU6050 姿态控制舵机:SG90 与 MG996R 精准跟随实战
- u-blox LEA-6H GPS 模块:Arduino 与 Python 集成指南
- Blynk + Arduino 读取 DHT11 温湿度数据教程
- 用 Arduino Uno 和 1Sheeld 构建 4x4x4 LED 立方体 - 互动音乐可视化项目
- Arduino GPS与TFT触摸屏扩展板:实时定位显示项目
- 使用 Arduino Uno 和蓝牙实现遥控小车:分步指南