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

【花雕学编程】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 #include #include #include 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\";}
  1. 增强语音助手(上下文处理)
#include #include #include #include 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 #include #include #include 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 #include #include #include #include // 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 #include // 省略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配置与设备定义// 场景模式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版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。

在这里插入图片描述