跳转到内容

语音控制集成

语音控制集成

本节介绍如何为智能家居面板添加语音控制功能。学习完成后,您将能够:

  • 理解 ESP32 语音控制的技术方案
  • 实现简单的语音命令识别和响应
  • 将语音命令转换为 MQTT 控制指令
  • 评估语音控制方案的技术边界

在开始本节之前,请确保:

  • 已完成 MQTT 通信配置
  • 了解基础的语音识别概念
  • I2S 麦克风模块已接线
方案方式优点缺点成本
离线语音识别ESP32-SR 模块无需网络、延迟低命令有限$5-8
在线语音识别云端 API(百度/阿里)识别准确率高需要网络、有延迟API 费用
语音唤醒 + 命令离线唤醒 + 在线识别低功耗、高准确率实现复杂$8-15
外部语音助手对接 Alexa/Google Home生态成熟需要额外设备$30-50

ESP32-SR 是专用的语音识别模块,通过 UART 与 ESP32 通信:

#include <SoftwareSerial.h>
// ESP32-SR 连接
#define SR_RX 16
#define SR_TX 17
#define SR_BAUD 9600
SoftwareSerial srSerial(SR_RX, SR_TX);
class VoiceRecognition {
private:
// 命令 ID 映射
struct CommandEntry {
int id;
const char* name;
const char* mqttTopic;
const char* mqttPayload;
};
CommandEntry commands[] = {
{1, "打开灯光", "home/light/livingroom/set", "{\"state\":\"ON\"}"},
{2, "关闭灯光", "home/light/livingroom/set", "{\"state\":\"OFF\"}"},
{3, "打开空调", "home/climate/livingroom/mode/set", "\"cool\""},
{4, "关闭空调", "home/climate/livingroom/mode/set", "\"off\""},
{5, "离家模式", "home/scene/livingroom/trigger", "\"离家\""},
{6, "回家模式", "home/scene/livingroom/trigger", "\"回家\""},
{7, "睡眠模式", "home/scene/livingroom/trigger", "\"睡眠\""},
{8, "温度设为26度", "home/climate/livingroom/temperature_set", "\"26\""},
};
public:
bool begin(int rx, int tx) {
srSerial.begin(SR_BAUD, SWSERIAL_8N1, rx, tx);
delay(1000);
// 配置命令列表
for (const auto& cmd : commands) {
srSerial.print("CMD_SET,");
srSerial.print(cmd.id);
srSerial.print(",");
srSerial.println(cmd.name);
delay(100);
}
srSerial.println("SAVE"); // 保存配置
return true;
}
// 检查语音识别结果
int checkCommand() {
if (srSerial.available()) {
String response = srSerial.readStringUntil('\n');
response.trim();
if (response.startsWith("CMD_RECV,")) {
int cmdId = response.substring(9).toInt();
return cmdId;
}
}
return -1;
}
// 执行语音命令
void executeCommand(int cmdId, PubSubClient* mqtt) {
for (const auto& cmd : commands) {
if (cmd.id == cmdId) {
Serial.printf("语音命令: %s\n", cmd.name);
mqtt->publish(cmd.mqttTopic, cmd.mqttPayload);
// 刷新 UI 显示
update_voice_feedback(cmd.name);
return;
}
}
}
};
VoiceRecognition voice;

另一种方案:外部语音助手(如 Amazon Alexa、Google Home)通过 MQTT 将语音指令转发到系统:

// Node-RED Flow: 语音命令到 MQTT
[
{
"id": "voice_command_in",
"type": "mqtt in",
"topic": "home/voice/command",
"server": "localhost"
},
{
"id": "voice_parser",
"type": "function",
"func": `
var text = msg.payload.text || msg.payload;
// 关键词匹配
var commands = [
{pattern: /打开.*灯/, topic: "home/light/livingroom/set", payload: '{"state":"ON"}'},
{pattern: /关闭.*灯/, topic: "home/light/livingroom/set", payload: '{"state":"OFF"}'},
{pattern: /空调.*26/, topic: "home/climate/livingroom/temperature_set", payload: '26'},
{pattern: /离家/, topic: "home/scene/livingroom/trigger", payload: '"离家"'},
{pattern: /回家/, topic: "home/scene/livingroom/trigger", payload: '"回家"'},
{pattern: /温度.*高点?/, topic: "home/climate/livingroom/temperature_set", payload: '26'},
{pattern: /温度.*低点?/, topic: "home/climate/livingroom/temperature_set", payload: '22'}
];
for (var cmd of commands) {
if (cmd.pattern.test(text)) {
return {topic: cmd.topic, payload: cmd.payload};
}
}
// 未识别
return {topic: "home/voice/response", payload: "抱歉,无法识别该命令"};
`
},
{
"id": "voice_command_out",
"type": "mqtt out",
"qos": 1,
"server": "localhost"
}
]
// 语音反馈 UI
lv_obj_t* voiceIndicator;
lv_obj_t* voiceFeedback;
lv_timer_t* voiceTimer;
void create_voice_ui() {
// 语音状态指示器
voiceIndicator = lv_label_create(screen);
lv_label_set_text(voiceIndicator, "🎤");
lv_obj_set_style_text_font(voiceIndicator, &lv_font_montserrat_24, 0);
lv_obj_align(voiceIndicator, LV_ALIGN_BOTTOM_RIGHT, -20, -20);
// 语音反馈标签
voiceFeedback = lv_label_create(screen);
lv_label_set_text(voiceFeedback, "");
lv_obj_set_style_text_font(voiceFeedback, &lv_font_montserrat_16, 0);
lv_obj_set_style_text_color(voiceFeedback, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_align(voiceFeedback, LV_ALIGN_BOTTOM_MID, 0, -50);
}
void update_voice_feedback(const char* command) {
lv_label_set_text_fmt(voiceFeedback, "语音: %s", command);
lv_obj_clear_flag(voiceFeedback, LV_OBJ_FLAG_HIDDEN);
// 3 秒后自动消失
if (voiceTimer) lv_timer_del(voiceTimer);
voiceTimer = lv_timer_create([](lv_timer_t* t) {
lv_obj_add_flag(voiceFeedback, LV_OBJ_FLAG_HIDDEN);
}, 3000, NULL);
lv_timer_set_repeat_count(voiceTimer, 1);
}
// PIR + 语音反馈:有人靠近时显示语音提示
void check_proximity_voice() {
if (sensors.motionDetected && !isVoicePromptShown) {
lv_label_set_text(voiceFeedback, ""你好"唤醒语音控制");
lv_obj_clear_flag(voiceFeedback, LV_OBJ_FLAG_HIDDEN);
isVoicePromptShown = true;
}
// 10 秒后隐藏提示
if (isVoicePromptShown && millis() - lastMotionTime > 10000) {
lv_obj_add_flag(voiceFeedback, LV_OBJ_FLAG_HIDDEN);
isVoicePromptShown = false;
}
}
限制因素离线方案在线方案
命令数量20-50 条无限制
识别准确率80-90%95-98%
响应延迟0.5-1s1-3s(含网络)
抗噪能力一般(<60dB)良好(使用降噪)
多语言需定制原生支持
离线运行✅ 支持❌ 需要网络
能力说明买家沟通要点
免提控制无需触摸面板”做饭时你说’关灯’,面板自动响应”
场景快速一句话触发场景”说’睡觉了’,所有灯关闭窗帘落下”
无障碍老人儿童友好”不用学习App,说话就能控制”
离线可用不依赖云服务”即使断网,语音控制依然可用”

本节介绍了智能家居面板的语音控制集成:

  1. 方案选择:离线语音识别(ESP32-SR)vs 在线语音 API
  2. 关键词匹配:Node-RED 进行语音命令的关键词解析
  3. LVGL 反馈:语音控制状态和命令反馈的 UI 显示
  4. MQTT 集成:语音命令通过 MQTT 转换为设备控制指令
  5. 技术边界:离线方案命令有限但延迟低,在线方案准确率高但依赖网络