2026寒假练 - 基于ESPHOME实现智能语音助手
该项目使用了ESPHOME框架/平台,实现了一个智能Home Assistant语音助手的设计,它的主要功能为:语音唤醒、自然语音对话、语音控制设备(LED三色灯、RGB灯带、 Home Assistant集成的设备)、查询传感器数据(温湿度传感器、Home Assistant集成的传感器),并通过套件自带摄像头实现实时视频监控;同时通过 OLED 屏幕实时展示语音助手运行状态、人机交互对话内容,借助 RGB 灯带呈现语音助手当前工作状态。。
标签
语音助手
ESPHome
HOME ASSISTANT
pysn2012
更新2026-03-24
103

一、任务介绍

自命题:以 ESPHome 为开发框架,基于 XIAO ESP32S3 SENSE 开发套件打造智能语音助手,无缝接入HOME ASSISTANT ,调用千问AI大模型实现智能化交互。实现语音唤醒、自然语音对话、语音控制设备(LED三色灯、RGB灯带、 Home Assistant集成的设备)、查询传感器数据(温湿度传感器、Home Assistant集成的传感器),并通过套件自带摄像头实现实时视频监控;同时通过 OLED 屏幕实时展示语音助手运行状态、人机交互对话内容,借助 RGB 灯带呈现语音助手当前工作状态。

使用到的模块:XIAO ESP32S3 SENSE(含摄像头、麦克风)、OLED 屏幕、LED三色灯、RGB灯带、温湿度传感器、MAX 98357A数字功放模块、扬声器等。

二、项目介绍

本项目依托 ESPHome 轻量化、易集成的开发特性,结合人工智能硬件实验套件,打造一款深度适配 Home Assistant 生态的智能语音助手。核心目标是成为智能家居的语音终端,通过自然语音交互方式,实现对本地设备(LED 三色灯、RGB 灯带、温湿度传感器等)和 Home Assistant 集成设备的管控,同时借助可视化、声音、灯光反馈手段提升人机交互体验,还可通过摄像头完成实时视频监控。

项目采用 “本地硬件交互 + 智能家居系统 + 云端 AI 大模型” 的三层协同架构,构建完整的智能交互:本地终端以 XIAO ESP32S3 SENSE 为核心完成感知、执行与状态展示,通过 ESPHome 与 Home Assistant 对接;由 Home Assistant OS 作为系统大脑完成核心调度,借助云端 STT/TTS 服务与 AI 大模型实现自然语言处理与智能应答,同时支持 Home Assistant APP/网页端的远程操控。

三、硬件介绍

人工智能硬件实验套件以Seeed XIAO ESP32-S3 Sense为核心主控,集成摄像头、麦克风等AI感知能力,搭配13个精选功能模块。本项目用到的模块主要有:

  • XIAO ESP32S3 SENSE:集成麦克风、摄像头,满足语音采集、图像采集、无线对接 Home Assistant 的核心需求;
  • OLED 屏幕:用于显示语音助手运行状态、人机对话文本内容等信息;
  • LED 三色灯:含红、绿、黄三色灯,因红灯引脚与数字功放模块冲突,实际只使用绿灯与黄灯;
  • RGB 灯带:通过不同灯光效果展示语音助手聆听、思考、回复三种状态;
  • 温湿度传感器:实时采集环境温湿度数据;
  • MAX 98357A 数字功放模块+扬声器:实现语音播报功能。

四、方案框图和项目设计思路

1)方案框图:

2)整体架构设计

项目采用 “本地硬件交互 + 智能家居系统 + 云端 AI 大模型” 的架构设计:

  • 本地终端以 XIAO ESP32S3 SENSE 为核心,承担耳朵、嘴巴、眼睛的角色,完成语音唤醒、语音采集、图像采集、外设驱动、状态显示、语音播放等功能,通过 ESPHome 接入 Home Assistant ;
  • 智能家居系统基于Home Assistant OS打造,作为整个系统的大脑,借助Home Assistant Cloud提供的STT、TTS服务,调用千问 AI 大模型处理自然语言,实现意图识别和指令生成,还可通过 Home Assistant APP 或网页端完成设备控制、信息查询与摄像头监控,最终达成 “意图理解——设备控制/数据查询/智能应答——状态反馈” 的全流程语音交互闭环。
3)核心功能设计
  • ESPHOME配置开发:基于 ESP-IDF 框架进行 ESPHome 配置,完成所有硬件设备与功能模块的驱动开发,同时实现语音唤醒、语音助手、OLED 屏幕显示页面、RGB 灯带状态效果等功能的配置与集成。
  • 本地语音唤醒:采用 microWakeWord 本地语音唤醒技术,将唤醒模型集成至 ESP32S3 固件中,唤醒成功后 RGB 灯带将触发声光提示,语音助手随即进入对话接收状态;
  • 双层语音交互:唤醒后采集用户语音指令,采用分层处理逻辑提升响应效率与交互深度:
    ① 快速意图识别:无需调用大模型,实现简单设备控制指令的极速响应(如 “打开绿灯”“打开黄灯” 等);
    ② LLM 深度理解:调用千问 AI 大模型进行语义解析,支持深度自然对话与复杂任务处理;
  • 多维状态反馈:交互全程通过双渠道实现状态可视化,OLED 屏幕实时显示对话内容、设备运行状态等信息,RGB 灯带按预设规则呈现语音助手不同工作状态。
4)开发流程

项目从平台搭建到硬件开发,从固件编译到测试落地分步开发:

  • 搭建 Home Assistant OS 平台,完成 Home Assistant Cloud、魔搭 AI 对话代理的配置,以及 Home Assistant 语音助手的整体参数设置;
  • 针对 XIAO ESP32S3 SENSE 进行 ESPHome 专属配置,开发硬件驱动与功能逻辑;
  • 通过 Github Actions 实现固件的自动化编译,将编译完成的固件烧录至 ESP32S3 硬件;
  • 完成硬件设备的配网与 Home Assistant 平台接入,开展全功能联调与项目测试。

五、开发实现流程

1)开发环境
  • 操作系统:WINDOWS 10
  • 开发软件:VS Code或Notepad++、GIt Bash
  • 调试工具:ESPConnect
  • 固件烧录:ESPConnect、ESPHome 在线工具(web.esphome.io)、乐鑫 Flash Download Tool
2)编程语言
  • 核心开发语言:YAML(ESPHome 配置文件编写);
  • 辅助开发语言:C/C++(语音助手、硬件控制逻辑实现);
  • 脚本语言:Shell(HAOS配置、Git 仓库操作)。
3)HAOS安装

本项目将 HAOS 烧录至树莓派作为智能家居系统核心,烧录操作非项目重点,具体步骤参考树莓派官方文档:https://www.raspberrypi.com/documentation/computers/getting-started.html#installing-the-operating-system

4)Home Assistant Cloud配置

Home Assistant Cloud 提供 1 个月免费试用服务,包含完整的 STT(语音转文字)、TTS(文字转语音)功能,配置步骤如下:

  • 进入Home Assistant 后台「设置」→「Home Assistant Cloud」页面,按引导注册并登录,系统会自动创建一个新的语音助手。

  • 随后在「设置」→「语音助手」中,进入该助手配置页,设置好语音转文字和文字转语音服务(对话代理可暂不设置)。

5)魔搭AI对话代理

参考开源项目文档完成配置:https://github.com/yanfeng17/yanfeng_ai_task

配置完成后,返回 Home Assistant「语音助手」配置页,将对话代理选择为 Yanfeng AI 即可。

6) ESPHome 配置

ESPHome是一个用于控制ESP8266/ESP32设备的强大系统,通过YAML配置文件即可轻松定义设备功能和Home Assistant集成,无需编写复杂代码。

因项目需通过 GitHub Actions 实现固件在线编译,需基于 ESPHome 官方语音助手仓库进行定制化开发(官方仓库未适配 SEEED XIAO ESP32S3 SENSE 开发板),具体步骤与核心配置如下:

访问 ESPHome 官方语音助手仓库https://github.com/esphome/wake-word-voice-assistants,先将仓库 FORK 至个人 GitHub 账号,再通过 Git Bash 克隆到本地开发环境;

进入本地克隆仓库目录,复制esp32-s3-box-3文件夹并重新命名为eetree-ai,保留语音助手核心逻辑,针对 SEEED XIAO ESP32S3 SENSE 开发板做定制化修改,包括开发板基础配置、外设模块驱动、OLED 屏幕显示、摄像头功能配置等。部分代码解析如下:

① 音频部分:XIAO ESP32S3 SENSE使用的是PDM麦克风,搭配的是MAX 98357A功放模块,配置如下:

# I2S 音频总线
i2s_audio:
- id: i2s_mic
i2s_lrclk_pin: GPIO42 # PDM_CLK
- id: i2s_out_bus
i2s_lrclk_pin: GPIO7 # ← LRC / WS
i2s_bclk_pin: GPIO8 # ← BCLK

# PDM 麦克风
microphone:
- platform: i2s_audio
id: box_mic
i2s_audio_id: i2s_mic
adc_type: external
i2s_din_pin: GPIO41 # PDM DATA
pdm: true
sample_rate: 16000
bits_per_sample: 16bit
channel: left

# MAX 98357A
speaker:
- platform: i2s_audio
id: box_speaker
i2s_audio_id: i2s_out_bus
i2s_dout_pin: GPIO9
dac_type: external
sample_rate: 16000
bits_per_sample: 16bit
channel: right # MAX 98357A默认是右声道
buffer_duration: 100ms

② OLED显示页面:ESPHOME的官方仓库使用图片表示语音助手状态,OLED屏幕只有2色,显示图片效果不好,我改为纯文字方案。配置如下:

display:
- platform: ssd1306_i2c
id: oled128
model: "SSD1306 128x64"
i2c_id: i2c_bus
address: 0x3C
update_interval: never
# 定义了多个显示页面,每个页面是一个独立的绘制函数
pages:
# 空闲页面
- id: idle_page
lambda: |-
it.fill(id(bg_color));
it.printf(30, 20, id(font_main), id(text_color), "%s", "待机状态");
id(draw_active_timer_widget).execute();
# 监听页面
- id: listening_page
lambda: |-
it.fill(id(bg_color));
it.printf(30, 20, id(font_main), id(text_color), "%s", "聆听状态");
id(draw_active_timer_widget).execute();
# 思考页面
- id: thinking_page
lambda: |-
it.fill(id(bg_color));
it.printf(0, 0, id(font_main), id(text_color), "%s", "思考:");
const int start_y = 16;
const int line_height = 12;
const int max_width = 128;
std::string text = id(text_request).state.c_str();
int y = start_y;
std::string line;
for (size_t i = 0; i < text.size() && y < 64;) {
uint8_t c = text[i];
int len =
(c & 0x80) == 0x00 ? 1 :
(c & 0xE0) == 0xC0 ? 2 :
(c & 0xF0) == 0xE0 ? 3 : 4;
std::string next = line + text.substr(i, len);
int x1, y1, w, h;
it.get_text_bounds(
0, y,
next.c_str(),
id(font_small),
esphome::display::TextAlign::TOP_LEFT,
&x1, &y1, &w, &h
);
if (w > max_width) {
it.printf(0, y, id(font_small), id(text_color), "%s", line.c_str());
y += line_height;
line.clear();
} else {
line = next;
i += len;
}
}
if (!line.empty() && y < 64) {
it.printf(0, y, id(font_small), id(text_color), "%s", line.c_str());
}
id(draw_active_timer_widget).execute();
# 回复页面
- id: replying_page
lambda: |-
it.fill(id(bg_color));
it.printf(0, 0, id(font_main), id(text_color), "%s", "回复:");
const int start_y = 16;
const int line_height = 12;
const int max_width = 128;
std::string text = id(text_response).state.c_str();
int y = start_y;
std::string line;
for (size_t i = 0; i < text.size() && y < 64;) {
uint8_t c = text[i];
int len =
(c & 0x80) == 0x00 ? 1 :
(c & 0xE0) == 0xC0 ? 2 :
(c & 0xF0) == 0xE0 ? 3 : 4;
std::string next = line + text.substr(i, len);
int x1, y1, w, h;
it.get_text_bounds(
0, y,
next.c_str(),
id(font_small),
esphome::display::TextAlign::TOP_LEFT,
&x1, &y1, &w, &h
);
if (w > max_width) {
it.printf(0, y, id(font_small), id(text_color), "%s", line.c_str());
y += line_height;
line.clear();
} else {
line = next;
i += len;
}
}
if (!line.empty() && y < 64) {
it.printf(0, y, id(font_small), id(text_color), "%s", line.c_str());
}
id(draw_active_timer_widget).execute();
# 定时器结束页面
- id: timer_finished_page
lambda: |-
it.fill(id(bg_color));
it.printf(30, 20, id(font_main), id(text_color), "%s", "时间结束");
# 错误页面
- id: error_page
lambda: |-
it.fill(id(bg_color));
it.printf(25, 20, id(font_main), id(text_color), "%s", "呃,出错了");
# 无Home Assistant页面
- id: no_ha_page
lambda: |-
it.fill(id(bg_color));
it.printf(25, 20, id(font_main), id(text_color), "%s", "未连接HA");
# 无WiFi页面
- id: no_wifi_page
lambda: |-
it.fill(id(bg_color));
it.printf(25, 20, id(font_main), id(text_color), "%s", "未连接wifi");
# 初始化页面
- id: initializing_page
lambda: |-
it.fill(id(bg_color));
it.printf(35, 20, id(font_main), id(text_color), "%s", "加载中");
# 静音页面
- id: muted_page
lambda: |-
it.fill(id(bg_color));
it.printf(35, 20, id(font_main), id(text_color), "%s", "静音状态");
id(draw_active_timer_widget).execute();

③ WS2812灯带效果:根据语音助手工作状态配置专属灯效,聆听——白色呼吸灯效,思考——蓝色扫描灯效,回复——语音律动灯效。配置如下:

light:
# 绿灯
- platform: binary
id: green_light
name: "Green Light"
output: green_led
restore_mode: ALWAYS_OFF
# 黄灯
- platform: binary
id: yellow_light
name: "Yellow Light"
output: yellow_led
restore_mode: ALWAYS_OFF
# WS2812灯带
- platform: esp32_rmt_led_strip
id: ws2812_strip
name: "WS2812 Strip"
pin: GPIO2
num_leds: 10
chipset: WS2812
rgb_order: GRB
restore_mode: ALWAYS_OFF
effects:
# Listening 灯效:白色呼吸
- pulse:
name: "Listening Breathing"
transition_length: 1.2s
update_interval: 1.2s
min_brightness: 5%
max_brightness: 25%
# Thinking 灯效:蓝色扫描
- addressable_scan:
name: "Thinking Scan"
move_interval: 80ms
scan_width: 2
# Replying 灯效:语音律动
- random:
name: "Replying Voice Pulse"
transition_length: 150ms
update_interval: 120ms

④ 摄像头:将OV3660摄像头打造成Home Assistant的一个实体,实现视频监控功能。配置如下:

esp32_camera:
name: ESP32 Camera
external_clock:
pin: GPIO10 # XCLK_GPIO_NUM
frequency: 20MHz
i2c_id: camera_i2c
data_pins: [GPIO15, GPIO17, GPIO18, GPIO16, GPIO14, GPIO12, GPIO11, GPIO48]
vsync_pin: GPIO38
href_pin: GPIO47
pixel_clock_pin: GPIO13 # PCLK_GPIO_NUM
# power_down_pin: -1 # PWDN_GPIO_NUM (未使用)
# reset_pin: -1 # RESET_GPIO_NUM (未使用)
resolution: 640x480 # QVGA - 分辨率
jpeg_quality: 15 # 适合高分辨率的质量设置 (10=最高质量, 63=最低质量)
vertical_flip: true # 上下翻转图像
horizontal_mirror: true # 左右翻转图像
# 图像调整参数 - 改善亮度
brightness: 1 # 亮度调整 (-22, 默认0)
contrast: 0 # 对比度调整 (-22, 默认0)
saturation: 0 # 饱和度调整 (-22, 默认0)
# 自动曝光和增益控制
aec_mode: auto # 自动曝光控制
aec2: true # 启用高级自动曝光
ae_level: 1 # 自动曝光级别 (-22, 默认0)
agc_mode: auto # 自动增益控制
agc_gain_ceiling: 2x # 增益上限 (2x, 4x, 8x, 16x, 32x, 64x, 128x)
wb_mode: auto # 自动白平衡
7) 在线编译固件

由于国内网络环境限制,本地编译固件易出现依赖包下载失败的问题,推荐使用 GitHub Actions workflows 进行云端编译。

GitHub Actions 是 GitHub 提供的自动化工具,由官方或社区维护的虚拟环境(Linux/Windows/macOS 及容器)执行,实现代码编译、测试、发布、通知等自动化工作。

本地 ESPHome 配置完成后,通过 Git Bash 将修改后的代码推送到个人 GitHub 仓库:

git status
git add .
git commit -m "add eetree ai"
git push

回到个人 GitHub 仓库,①点击GitHub Actions,②左侧选择工作流(build eetree_ai ESPHOME),③右侧点击Run workflow → Run workflow,手动触发工作流:

工作流跑完后状态显示 ✅,④点击该条记录,⑤在底部 Artifacts下载编译好的固件:

8)固件烧录

下载的固件包包含 3 个文件,其中firmware.factory.bin为完整可烧录固件。

推荐使用 ESPHome 在线工具烧录(操作简单、无需安装软件),也可使用乐鑫官方 Flash Download Tool,以下为 ESPHome 在线工具烧录步骤:

  • 访问 ESPHome 在线工具:https://web.esphome.io/
  • 将 XIAO ESP32S3 开发板通过 USB 数据线连接至电脑,进入下载模式:按住 BOOT 键和 RST 键,先释放 RST 键,再释放 BOOT
  • 在在线工具页面点击CONNECT按钮,在弹出的设备列表中选择XIAO ESP32S3对应的串口(如 COM6,可通过设备管理器查看)

  • 连接成功后,点击页面中的INSTALL按钮,在弹出的固件选择窗口中,选择固件文件,上传之前编译好的固件firmware.factory.bin

  • 点击右下角的INSTALL开始烧录,工具会自动擦除原有固件、写入新固件
  • 烧录完成后,按开发板上的 RST 键重启设备

六、功能展示

1)网络配置

ESPHome 官方默认采用 AP 配网模式,设备首次启动后可通过以下两种方式完成 WiFi 配置,适配 2.4G WIFI:

  • 方式 1:通过 ESPHome 在线工具(https://web.esphome.io/)完成 WiFi 配置——点击在线工具的CONNECT,连接成功后点击右下角的三个点图标,选择Configure WIFI---->CONNECT TO WIFI,输入WiFi 名称和密码,设备会自动连接网络并完成初始化。
  • 方式 2:手动AP配网 —— 使用手机 / 电脑连接设备启动后发出的 WiFi 热点(名称格式通常为xiao-esp32s3-XXXX),连接成功后会自动弹出 WiFi 选择界面,选择你的 2.4G WiFi 并输入密码,即可完成设备联网。

配网完成后,打开Home Assistant,进入「设置」→「设备与服务」,系统应能自动发现xiao-esp32s3设备。

2)基础设置

在 Home Assistant 中完成设备添加后,需进行初始化设置。

  • 音量调节:设备默认播放音量较低,建议在设备配置页将音量调至最大。

  • 唤醒词与语音助手设置:设置唤醒词为 OK,NABU (实测该唤醒词识别灵敏度最优,其他唤醒词效果受发音影响可能较差),设置助手为Home Assistant Cloud。

3)网页或APP控制

可通过 Home Assistant 网页端或 APP 对所有设备进行控制,可操作功能包括:摄像头实时监控、WS2812 RGB 灯带开关、绿灯/黄灯单独开关、温湿度查询、设备静音等。

  • 点击ESP32 Camera ,打开摄像头实时监控画面:

  • 点击Green Light和Yellow Light开关,打开绿灯和黄灯

也可以在网页端查询DHT11上传的温湿度。

网页控制效果展示:详见演示视频。

4)语音控制

通过唤醒词 Okay NABU 唤醒语音助手,发出指令(如:打开绿灯DHT温度和湿度),OLED屏幕会清晰显示对话内容,包括指令文本及回复结果。

待命状态:

简单指令(响应迅速):

思考状态:

智能问答:

语音控制全流程效果展示:详见演示视频。

七、项目中遇到的难题及解决方法

难题 1:除了 Okay NABU ,其他语音唤醒灵敏度低

我尝试了 microWakeWord 自带的 Hey Jarvis 唤醒词,发现识别灵敏度极低,经常无响应;又尝试安装 OpenWakeWord ,使用开源的 小智、小爱 等中文唤醒词,唤醒率均不高。

解决方法:确定 Okay NABU 为适配性最优的唤醒词。如果后续要使用其他唤醒词,建议使用自己的语音进行训练,提高唤醒效果。

难题 2:STT、LLM、TTS响应速度慢

语音交互过程中,LLM和TTS响应速度偏慢。当使用快速意图识别控制设备时,响应速度与小智(https://xiaozhi.me/)相当;但使用LLM 深度理解时,需等待数秒才能得到反馈,与小智的响应体验差距较大。

解决方法:受云端服务和网络传输延迟双重影响,暂时无法解决此问题。建议优先使用快速意图识别控制设备,减少LLM和TTS的调用。

难题 3:RGB 灯带语音律动灯效无法精准联动

项目设计时,计划让 WS2812 RGB 灯带根据语音播放的频率、节奏实现同步律动灯效,但实际开发中,无法获取设备语音播放的实时频率数据,无法实现灯效与语音的精准联动。

解决方法:采用随机律动的灯效方案替代,虽能在语音回复阶段呈现动态效果,但无法与语音节奏联动,后续进一步探索音频数据获取与灯效联动的实现方式。

八、心得体会

通过本项目的开发和学习,我完成了一次从理论到实操的完整智能家居项目实践,收获颇丰。

软件开发方面:不仅深入掌握了 ESPHome 的 YAML 配置、硬件驱动开发,以及设备与 Home Assistant 的对接等技术,还对 “本地硬件交互 + 智能家居系统 + 云端 AI 大模型” 的开发框架有了更直观、深刻的理解,清晰认识到各环节之间的技术衔接逻辑。

硬件设计方面:通过对人工智能硬件实验套件的组装、调试,我补充了不少硬件相关知识,从各类模块的接口匹配、排线焊接,到硬件文档的查阅与解读,动手能力和硬件认知都得到了提升。

整个开发过程中,也遇到了语音唤醒、响应速度、灯效联动等一系列技术难题。在排查问题、尝试解决的过程中,学到了很多实战经验,同时也清晰认识到商用智能产品与自制项目在技术优化、体验打磨上的差距。

附件下载
eetree_ai.factory.yaml
factory配置文件
eetree_ai.yaml
主配置文件
build-eetree_ai.yml
GIthub工作流
firmware.factory.bin
完整固件
团队介绍
我是pysn2012,一名初中学生,课余主要学习 Python、MicroPython 编程和树莓派开发,特别喜欢动手 DIY,比如制作遥控小车、搭建智能家居系统、各类趣味物理实验等。
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号