本项目基于 MAX78000 平台,围绕“离线语音识别 + 智能家居控制”这一典型边缘 AI 场景展开。我们从官方示例入手,逐步摸清了模型训练、量化、部署以及应用层开发的完整流程。项目经历了从中期“能运行例程但无法识别自定义语音”,到终期成功实现多关键词语音识别、LED灯阵控制以及LVGL屏幕可视化反馈的完整演进。
一、中期探索:从例程到自定义数据
1. 项目介绍与硬件平台
本次项目基于MAX78000FTHR开发板,旨在通过离线语音识别控制LED灯的亮灭,并在屏幕上实时反馈识别结果,模拟一个简单的智能家居控制场景。


2. 开发环境搭建
官方资料完备,首先需要更新调试工具固件。机器学习模型训练部分必须在Linux环境下进行,而外设开发和程序烧录则可以在Windows或Linux上完成。本项目选择在Linux(WSL2)中进行模型训练,在Windows中进行应用开发与调试。
3. Windows端SDK与例程运行
通过Maxim的SDK下载工具获取开发包,其IDE基于Eclipse定制。首先导入并运行hello_world示例熟悉编译烧录流程,随后导入关键语音识别示例kws20_demo。
该例程能够识别20个英文关键词(up, down, left, right, stop, go, yes, no, on, off, one, two, three, four, five, six, seven, eight, nine, zero),其他语音则归类为unknown。
4. Linux端模型训练流程初探
在kws20_demo例程中,我们看到了cnn.c、weights.bin等由模型训练生成的文件。这表明自定义语音识别的核心在于生成属于自己的这几个文件。
环境配置:在WSL2中,需安装匹配的CUDA工具包(如需GPU加速)、PyTorch以及官方提供的ai8x-training、ai8x-synthesis库。
关键步骤:
- 理解数据流:重点分析
ai8x-training/datasets/kws20.py脚本。它定义了数据集(Google Speech Commands V2)的加载、预处理及类别。
- 首次修改验证:为验证自定义流程,我们修改
kws20.py中KWS_20数据集的output字段,仅保留right, left, unknown三项,并相应调整weight。
- 执行训练与生成:运行
./scripts/train_kws20.sh进行训练,再通过ai8x-synthesis中的脚本生成C工程所需的三个文件。
- 部署验证:将生成的文件替换到Windows端的
kws20_demo工程中,并修改main.c中的关键词数组,编译烧录后,确认板子只能识别“right”和“left”。
5. 尝试引入自定义语音数据
基于以上验证,我们推测只要将自己的语音数据加入训练集即可。于是,我们采集了“开灯”、“关灯”的语音,并使用Audacity软件将其处理为符合要求的格式:
- 采样率:16kHz
- 编码:16-bit PCM
- 声道:单声道
- 格式:WAV
将处理好的约20个样本文件放入ai8x-training/data/KWS/raw目录下的kai和guan文件夹中,并相应修改了kws20.py中的类别字典和数据集定义。然而,重新训练并部署后,识别效果未达预期,推测原因是自定义数据量太少,模型未能充分学习特征。
中期小结:此阶段成功跑通了官方例程,理解了模型训练到部署的基本流程,并尝试加入自定义数据,但因数据量不足未能成功。这为后续终期实现指明了方向——需要大规模、高质量的自定义语音数据集。
二、终期实现:完整的离线语音智能家居模拟
1. 硬件扩展
- 8x8 LED点阵屏:通过两片74HC595串联控制,仅需3个GPIO引脚。
- 2.4寸触摸屏:驱动芯片为ILI9341,用于显示GUI及识别结果。


2. 软件实现
(1)大规模自定义模型训练
数据采集与处理:为了提升识别率,我们系统性采集了5个关键词(“打开”、“关闭”、“开灯”、“关灯”、“测试”)的语音数据。邀请10位发言人,每人每个词录制约30条,共获得约1500条原始语音。随后进行精细的裁剪和格式转换,确保每条语音长度合适且格式规范。
数据集整合:将处理好的5类语音文件夹(重命名为英文open, close, kai, guan, test)移至ai8x-training/data/KWS/raw目录下,与原有官方数据集合并。
关键脚本修改:
-
kws20.py:
- 更新
class_dict字典,加入新增的5个类别。
- 修改
datasets列表中KWS_20的output字段,定义我们最终要训练的9个关键词('backward','forward','open','close','kai','guan','test', 'left', 'right')和一个UNKNOWN类。
- 对应调整
weight权重。
- 将
KWS_20_get_datasets函数中的num_classes参数改为9(不含UNKNOWN)。
-
模型配置文件:修改ai8x-training/models/ai85kws20net.py中AI85KWS20Net类的num_classes参数为10(9个关键词+1个未知类)。
执行训练与部署:
# 在 ai8x-training 目录下执行训练
./scripts/train_kws20.sh
# 训练完成后,在 ai8x-synthesis 目录下进行量化与生成
./scripts/gen_kws20_max78000.sh
将生成的cnn.c、cnn.h、weights.bin文件复制到自己的MAX78000工程中,并更新main.c中的关键词数组。
(2)LVGL图形库移植与显示优化
为在屏幕上实现美观的GUI,我们尝试移植LVGL v8.3。主要步骤包括:
- 将LVGL源码加入项目。
- 实现
disp_init()(基于MAX78000官方TFT驱动)和disp_flush()(用于刷新显示)两个关键函数。
- 调用
lv_port_disp_init()初始化显示驱动。
遇到的问题与解决:移植LVGL 8.3后,编译出现Flash空间溢出错误(溢出约13KB)。为解决此问题,我们回退至更轻量级的LVGL 7.11版本,成功编译并运行。
(3)应用逻辑整合
在主循环中,将语音识别结果与硬件控制、GUI更新联动:
- 识别到“开灯”/“kai”等指令,点亮LED点阵并更新屏幕状态。
- 识别到“关灯”/“guan”等指令,关闭LED点阵。
- 屏幕通过LVGL控件实时显示当前识别出的关键词和系统状态。
3. 项目成果展示
最终项目实现了离线、多关键词的语音识别,并能可靠地控制LED点阵显示不同图案,同时在TFT屏幕上通过简洁的GUI提供视觉反馈。整个系统运行在MAX78000这一低功耗的边缘设备上,无需连接网络。


4. 总结
本项目完成了一个从模型训练、优化部署到上层应用开发的完整边缘AI案例。核心体会在于:针对边缘设备的模型训练,高质量、足量的自定义数据集是识别效果的关键;同时,在资源受限的MCU上进行开发,需要权衡功能与资源(如Flash/RAM空间),例如在图形库选型上选择更轻量的版本。通过本次实践,深入掌握了MAX78000 AI MCU在离线语音识别场景下的全栈开发流程。