【花雕学编程】ESP32 DeepSeek 之智能家居语音助手(支持上下文记忆)

《Arduino 手册(思路与案例)》栏目介绍:
在电子制作与智能控制的应用领域,本栏目涵盖了丰富的内容,包括但不限于以下主题:Arduino BLDC、Arduino CNC、Arduino E-Ink、Arduino ESP32 SPP、Arduino FreeRTOS、Arduino FOC、Arduino GRBL、Arduino HTTP、Arduino HUB75、Arduino IoT Cloud、Arduino JSON、Arduino LCD、Arduino OLED、Arduino LVGL、Arduino PID、Arduino TFT,以及Arduino智能家居、智慧交通、月球基地、智慧校园和智慧农业等多个方面与领域。不仅探讨了这些技术的基础知识和应用领域,还提供了众多具体的参考案例,帮助读者更好地理解和运用Arduino平台进行创新项目。目前,本栏目已有近4000篇相关博客,旨在为广大电子爱好者和开发者提供全面的学习资源与实践指导。通过这些丰富的案例和思路,读者可以获取灵感,推动自己的创作与开发进程。
https://blog.csdn.net/weixin_41659040/category_12422453.html

ESP32 DeepSeek 中的智能家居语音助手(支持上下文记忆)
1、主要特点
上下文记忆功能:
智能家居语音助手具备上下文记忆能力,能够在对话中保持信息的连续性。用户在多轮对话中所提供的信息可以被存储和引用,从而提供更自然的交互体验。
语音识别与合成:
结合先进的语音识别和合成技术,助手能够准确理解用户的语音指令,并以自然的语音反馈,增强用户体验。
设备控制能力:
语音助手可以控制家庭中的各种智能设备,如灯光、温控、安防系统等,用户可以通过语音指令轻松管理家庭环境。
集成多种服务:
支持集成多种在线服务,如天气查询、日历提醒、音乐播放等,用户可以通过语音助手获取信息和娱乐内容,方便快捷。
基于 ESP32 平台:
利用 ESP32 的强大计算能力和低功耗特性,语音助手在资源有限的环境中高效运行,非常适合家庭使用。
2、应用场景
家居自动化:
用户可以通过语音助手实现智能家居设备的自动化控制,提升家庭生活的便利性和舒适度。
家庭娱乐:
智能语音助手可用于家庭娱乐系统的控制,用户可以通过语音播放音乐、视频,或查询娱乐内容,增强家庭互动体验。
日常生活助手:
语音助手可以作为日常生活的辅助工具,提供日程管理、提醒服务、天气预报等功能,帮助用户高效管理日常事务。
安全监控:
结合家居安防系统,语音助手能够提供安全监控服务,用户可以通过语音查询家中安全状态,增强家庭安全感。
老年人和残障人士辅助:
对于老年人和身体残障人士,语音助手提供了无障碍的控制方式,帮助他们更方便地管理家庭环境,提高生活质量。
3、注意事项
语音识别准确性:
语音识别的准确性可能受到环境噪音和口音的影响,需确保使用高质量的麦克风和适当的降噪技术,以提高识别效果。
上下文管理复杂性:
实现上下文记忆功能需设计复杂的状态管理系统,以确保助手能够正确理解和引用之前的对话信息,避免信息混淆。
用户隐私与数据安全:
语音助手可能涉及用户的个人信息,需确保数据传输和存储的安全性,保护用户隐私。
设备兼容性:
需要确保语音助手能够与多种品牌和类型的智能家居设备兼容,提供无缝的控制体验。
资源管理:
尽管 ESP32 性能较强,但在处理复杂的语音识别和上下文记忆任务时,需合理管理系统资源,避免因资源耗尽导致的性能下降。

1、基础语音助手
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
String contextMemory = ""; // 上下文记忆
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
}
void loop() {
String userInput = "Turn on the light"; // 示例用户输入
String response = getResponse(userInput);
Serial.println("Response: " + response);
delay(5000);
}
String getResponse(String userInput) {
// 更新上下文记忆
if (userInput.indexOf("light") != -1) {
contextMemory = "light on";
}
// 发送请求获取响应
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "http://api.example.com/response?query=" + userInput + "&context=" + contextMemory;
http.begin(url);
int httpResponseCode = http.GET();
String payload = "{}"; // 默认返回空 JSON
if (httpResponseCode > 0) {
payload = http.getString();
}
http.end();
return payload;
}
return "No WiFi connection";
}
- 增强语音助手(上下文处理)
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
String contextMemory = ""; // 上下文记忆
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
}
void loop() {
String userInput = "Set temperature to 22 degrees"; // 示例输入
String response = getResponse(userInput);
Serial.println("Response: " + response);
delay(5000);
}
String getResponse(String userInput) {
// 更新上下文记忆
if (userInput.indexOf("temperature") != -1) {
contextMemory = "temperature set";
}
// 发送请求获取响应
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "http://api.example.com/response?query=" + userInput + "&context=" + contextMemory;
http.begin(url);
int httpResponseCode = http.GET();
String payload = "{}"; // 默认返回空 JSON
if (httpResponseCode > 0) {
payload = http.getString();
}
http.end();
return payload;
}
return "No WiFi connection";
}
3、完整的语音助手(多种命令与上下文记忆)
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
String contextMemory = ""; // 上下文记忆
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
}
void loop() {
String userInput = "Turn off the light"; // 示例输入
String response = getResponse(userInput);
Serial.println("Response: " + response);
userInput = "What is the current temperature?"; // 示例输入
response = getResponse(userInput);
Serial.println("Response: " + response);
delay(5000);
}
String getResponse(String userInput) {
// 更新上下文记忆
if (userInput.indexOf("light") != -1) {
contextMemory = userInput.indexOf("off") != -1 ? "light off" : "light on";
} else if (userInput.indexOf("temperature") != -1) {
contextMemory = "temperature queried";
}
// 发送请求获取响应
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "http://api.example.com/response?query=" + userInput + "&context=" + contextMemory;
http.begin(url);
int httpResponseCode = http.GET();
String payload = "{}"; // 默认返回空 JSON
if (httpResponseCode > 0) {
payload = http.getString();
}
http.end();
return payload;
}
return "No WiFi connection";
}
要点解读
上下文记忆:
通过字符串变量 contextMemory 来存储上下文状态,使得语音助手能够记住用户的请求和状态。这种设计可以提高对话的连贯性和智能性。
命令解析:
使用 indexOf 方法解析用户输入的命令,根据不同的关键字更新上下文记忆。这种方式简化了命令处理,适合初步实现语音助手功能。
HTTP 请求与响应:
通过 HTTPClient 发起请求以获取响应,结合上下文信息提高了对话的灵活性。响应可以来自外部 API,增强了助手的功能。
多命令支持:
第三个示例展示了如何处理多种命令(例如开关灯和查询温度),实现了基本的多任务能力。这使得助手能够适应用户的多样化需求。
可扩展性:
所有代码示例都以函数方式组织,便于后续的功能扩展和维护。可以轻松增加更多的命令解析逻辑、上下文管理或与其他设备的交互。

4、基础家电控制(支持设备上下文记忆)
功能:通过语音指令控制灯光、窗帘等设备,能记住最近操作的设备(如用户说 “打开它” 时,自动控制上一次提到的设备)。
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>
#include <vector>
#include <string>
// WiFi配置
const char* ssid = "your_ssid";
const char* password = "your_password";
// 设备定义与状态
struct Device {
String name; // 设备名称(如"客厅灯")
String type; // 类型("light"/"curtain")
bool status; // 状态(true=开/false=关)
};
std::vector<Device> devices = {
{"客厅灯", "light", false},
{"卧室窗帘", "curtain", false}
};
// 上下文记忆:存储最近操作的设备
String lastDevice = "";
// 语音指令解析(模拟,实际需对接语音识别API)
String parseVoiceCommand(String command) {
// 简化的指令匹配(实际需用NLP库)
if (command.indexOf("打开") != -1) {
for (auto& dev : devices) {
if (command.indexOf(dev.name) != -1) {
dev.status = true;
lastDevice = dev.name; // 更新上下文
return dev.name + "已打开";
}
}
// 处理"打开它"(引用上下文)
if (command.indexOf("它") != -1 && lastDevice != "") {
for (auto& dev : devices) {
if (dev.name == lastDevice) {
dev.status = true;
return lastDevice + "已打开";
}
}
}
return "未找到设备";
}
// 关闭指令类似(省略)
return "指令未识别";
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi连接成功");
}
void loop() {
// 模拟语音输入(实际从麦克风或API获取)
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
String response = parseVoiceCommand(command);
Serial.println("回应:" + response);
// 打印当前设备状态(调试用)
for (auto& dev : devices) {
Serial.print(dev.name + "状态:");
Serial.println(dev.status ? "开" : "关");
}
}
delay(100);
}
5、定时任务管理(支持对话上下文引导)
功能:用户可通过语音设置设备定时任务(如 “定时关灯”),助手会主动询问缺失信息(如 “请问定时多久后关闭?”),并记住对话流程中的中间结果。
#include <WiFi.h>
#include <Ticker.h>
// 省略WiFi配置(同案例一)
// 定时任务结构
struct TimerTask {
String device;
int delaySec; // 延迟秒数
bool active;
};
TimerTask currentTask;
String对话状态 = "idle"; // 上下文状态:idle/等待设备/等待时间
// 语音解析与上下文引导
String handleCommand(String command) {
if (对话状态 == "idle") {
if (command.indexOf("定时") != -1) {
对话状态 = "等待设备";
return "请问要控制哪个设备?";
}
return "请说'定时+设备'开始设置";
}
if (对话状态 == "等待设备") {
for (auto& dev : devices) {
if (command.indexOf(dev.name) != -1) {
currentTask.device = dev.name;
对话状态 = "等待时间";
return "请问多久后执行?(单位:秒)";
}
}
return "未找到该设备,请重新说设备名称";
}
if (对话状态 == "等待时间") {
int sec = command.toInt();
if (sec > 0) {
currentTask.delaySec = sec;
currentTask.active = true;
对话状态 = "idle";
// 启动定时(实际需用Ticker库实现)
return "已设置" + currentTask.device +
sec + "秒后执行任务";
}
return "请输入有效的秒数";
}
return "操作失败";
}
void setup() {
// 初始化代码(同案例一)
}
void loop() {
// 模拟语音输入(实际从麦克风获取)
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
String resp = handleCommand(cmd);
Serial.println("回应:" + resp);
}
delay(100);
}
6、场景模式控制(支持多轮上下文关联)
功能:支持 “回家模式”“离家模式” 等场景切换,用户可追问细节(如 “回家模式把温度调到多少?”),助手能关联当前场景回答。
#include <WiFi.h>
// 省略WiFi配置与设备定义
// 场景模式
struct Scene {
String name;
String desc; // 场景描述(含设备状态)
int temp; // 关联温度(示例参数)
};
std::vector<Scene> scenes = {
{"回家模式", "灯光开启,窗帘打开", 26},
{"离家模式", "所有设备关闭", 0}
};
String currentScene = ""; // 当前激活场景(上下文)
// 场景控制与上下文关联
String handleSceneCommand(String command) {
// 激活场景
for (auto& scene : scenes) {
if (command.indexOf(scene.name) != -1) {
currentScene = scene.name;
return "已激活" + scene.name + ":" + scene.desc;
}
}
// 追问场景细节(关联当前场景上下文)
if (currentScene != "" && command.indexOf("温度") != -1) {
for (auto& scene : scenes) {
if (scene.name == currentScene) {
return currentScene + "默认温度为" +
String(scene.temp) + "℃";
}
}
}
// 退出场景
if (command.indexOf("退出场景") != -1) {
currentScene = "";
return "已退出当前场景";
}
return "未识别场景指令";
}
void setup() {
// 初始化代码(同案例一)
}
void loop() {
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
String resp = handleSceneCommand(cmd);
Serial.println("回应:" + resp);
}
delay(100);
}
要点解读
上下文记忆实现机制
采用 “状态变量 + 结构化存储” 实现上下文:案例一用lastDevice记录最近操作设备,案例二通过对话状态变量管理流程节点,案例三用currentScene关联场景上下文。实际应用中可扩展为循环队列存储多轮对话历史,结合关键词匹配召回上下文。
语音指令处理逻辑
代码中简化了指令解析(字符串匹配),实际需对接语音识别 API(如百度 AI、阿里云)将语音转文本,再通过 NLP 库(如 IntentClassifier)提取意图(如 “控制”“查询”“设置”)和实体(设备名、时间、参数),提升指令识别准确率。
硬件资源适配
ESP32 的 RAM 有限,需优化上下文存储:①用轻量数据结构(如struct而非类);②限制对话历史长度(如保留最近 5 轮);③避免频繁字符串拼接,改用StringBuilder库减少内存碎片。
网络与离线平衡
语音转文本和 NLP 解析可选择 “在线 API + 本地缓存” 模式:联网时调用云端 AI 提升识别率,离线时启用本地关键词匹配(如通过fuzzywuzzy库实现模糊匹配),确保基本功能可用。
扩展性设计
代码采用模块化结构:①设备 / 场景定义与业务逻辑分离,新增设备只需扩展devices数组;②上下文处理独立为函数,便于替换为更复杂的记忆算法(如基于 TF-IDF 的上下文关联);③控制逻辑预留接口,可通过 MQTT 协议对接智能家居网关(如 Home Assistant)。
注意,以上案例只是为了拓展思路,仅供参考。它们可能有错误、不适用或者无法编译。您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。

更多推荐


所有评论(0)