- 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。
1、 爬坑学习新旅程,虚拟机搭建esp32开发环境,打印 “Hellow World”。
2、 巧用eclipes编辑器,官方教程在在Windows下搭建esp32开发环境,打印 “Hellow World”。
3、 认识基本esp32的GPIO接口,开始点亮您的第一盏 LED和中断回调实现按键功能 。
4、体会esp32的强大的定时器功能, 实现定时2s闪烁一盏LED灯。
5、接触实践esp32的pwm宽度脉冲功能, 实现呼吸效果闪烁一盏LED灯。
6、smartConfig和微信airKiss在esp32的实现,一键配网轻松快捷连接路由器。
7、利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。
8、esp32上实现本地 UDP 客户端和服务端角色,在局域网内实现通讯。
9、esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。
10、乐鑫esp32 SDK编程利用rmt驱动ws2812七彩灯,实现彩虹渐变效果。
11、入门 乐鑫esp-adf 音频框架开发,esp32造一个蓝牙耳机,实现切换歌曲,获取歌曲信息等功能。
12、开源一个微信公众号airkiss配网esp32以及局域网发现功能的工程,分享一个airkiss配网小工具。
13、esp32 内置 dns 服务器,无需外网访问域名返回指定网页。
14、esp32 sdk编程实现门户强制认证,连接esp32热点之后,自动强制弹出指定的登录界面。
15、认识本地离线语音唤醒识别框架 esp-skainet ,实现较低成本的硬件语音本地识别控制。
16、学习本地语音唤醒离线识别框架 esp-skainet ,如何修改唤醒词? 如何自定义命令词?如何做意图动作?
17、全网首发,乐鑫esp32 sdk直连京东微联·小京鱼 · IoT开放平台,实现叮咚音响语音智能控制。
文章目录
- 一、前言
- 二、框架是基于什么算法的
- 2.1 疑问:唤醒词支持哪几个?可以自定义吗?
- 2.2 疑问:支持自定义命令词吗?比如识别 “我要开飞机”
- 2.3 算法模型 WakeNet 和 识别模型 MultiNet
- 2.3.1 唤醒词识别
- 2.3.2 语音命令识别
- 三、开发板、编译、体验
- 3.1 开发板选择?
- 3.2 拉取代码和指定idf路径
- 3.3 编译 “垃圾分类” 识别工程
- 另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈!
一、前言
记得最早一次听到语音识别的芯片是 科大讯飞的,那时候公司确实做出来一个本地离线识别的产品,但是后面就不再做了,我问了问主管,说是成本太高了!
后来,我去科大讯飞官网看了看开发板,貌似1600rmb一个开发板,不过那时候是 2017年的事情了,现在就不知道行情了;不过在某宝看到语音识别模块倒是一堆的,注意是模块,叫你串口通讯或者写txt文档进去,不开放二次开发;也许也有二次开发的,但是入门门槛高,价格就不菲了;
上个月,我在乐鑫的公众号看到了语音唤醒框架 esp-skainet
,那时候,仅仅支持 esp-lyart
开发板,我立刻去某宝买了一个,等了足足一个星期,终于到手了,很高兴,轻松地实现了本地语音识别;
也许,如何使用乐鑫的产品在某些人说来是很轻松的,但是群里依然有人会问我可以实现语音控制吗?这里,我就详细为大家做一个笔记,或者你认为是一个教程也无妨!但,足够帮到您的开发,我认为这个博文就是有价值的!!
二、框架是基于什么算法的
首先,必须知道 ESP-Skainet
是乐鑫自研推出的智能语音助手,目前支持唤醒词识别和命令词识别。
它以最便捷的方式支持基于乐鑫的 ESP32
芯片的唤醒词识别和命令词识别应用程序的开发。使用 ESP-Skainet,您可以轻松构建唤醒词识别和命令词识别应用程序。
2.1 疑问:唤醒词支持哪几个?可以自定义吗?
答: 目前,官网文档是唤醒词仅仅开放了如下几个:“Hi,乐鑫”,“你好小智”,“你好小鑫”,“hi,Jeson”,但是目前为止,我在开发过程中看到代码仅仅有:“Hi,乐鑫”,“你好小智” 开放,没看到其他唤醒词,可能是因为还没全部放在开源代码中吧。 但是,这足够我们使用开发了!如需自定义唤醒词,比如 “Hi,靓仔”,但是需要商务合作申请!
2.2 疑问:支持自定义命令词吗?比如识别 “我要开飞机”
答:嗯嗯!支持自定义命令词,目前官方示范是 中文命令词,这点我觉得很 nice,别说你要开飞机,你要放大炮开火箭识别都没问题,但是:仅仅支持 100个命令词;
2.3 算法模型 WakeNet 和 识别模型 MultiNet
既然是语音唤醒,本地识别,就离不开算法模型和识别模型,而ESP-Skainet
是基于乐鑫又一个仓库 esp_sr
为基础的。而 esp_sr
提供语音识别相关方向算法模型,目前主要包括三个模块:
- 唤醒词识别模型 WakeNet
- 语音命令识别模型 MultiNet
- 声学算法:AEC(Acoustic Echo Cancellation), VAD(Voice Activity Detection), AGC(Automatic Gain Control), NS(Noise Suppression)
2.3.1 唤醒词识别
唤醒词模型 WakeNet,致力于提供一个低资源消耗的的高性能模型,支持类似“Alexa”,“天猫精灵”,“小爱同学”等唤醒词的识别。
目前乐鑫免费开放“Hi,乐鑫”等唤醒词。如果用户需要其它唤醒词,乐鑫提供有唤醒词定制服务,具体可参考 乐鑫语音唤醒词定制流程。
2.3.2 语音命令识别
命令词识别模型 MultiNet ,致力于提供一个灵活的离线语音命词识别框架。用户可方便根据需求自定义语音命令,无需重新训练模型。
目前模型支持类似“打开空调”,“打开卧室灯”等中文命令词识别,自定义语音命令词最大个数为 100。
英文命令词定义将在下一版提供支持。
三、开发板、编译、体验
3.1 开发板选择?
因为是 esp32
芯片开发,不得不有 esp32
芯片开发基础!仓库代码已经支持了2个开发板分别是:esp-lyart-mini
和 esp-lyart v4.3
,在某宝有得卖,不得不吐槽,mini
板子价格还更贵一丢丢,哈哈!
esp-lyart-mini
官网旗舰店购买传送门:点击esp-lyart v4.3
官网旗舰店购买传送门:点击
上面开发板的最大区别是一个是单麦的,一个是双麦的;更多不同,自行去查询;下面再贴出二者的介绍文档!
esp-lyart-mini
官网介绍文档:点击esp-lyart v4.3
官网介绍文档:点击
3.2 拉取代码和指定idf路径
首先,不管是linux或者windows,你得有 make 环境,自行搭建,或者看我环境搭建的博文;现在也支持 cmake 了,编译更快!
拉取代码,git操作克隆,这个操作拉取了 idf 工程和skainet示范,但是过程可能需要十几分钟,因为GitHub在国外,没办法,耐心等待吧!
git clone --recursive https://github.com/espressif/esp-skainet.git
指定依赖的idf编译为 esp-skainet
里面的 idf
,比如这样:
export IDF_PATH=“E:/Espressif/Esp32/esp-idf/home/XuHongYss/esp-idf-3.1/esp-skainet/esp-idf”
3.3 编译 “垃圾分类” 识别工程
最近国家提倡的“垃圾分类” 很流行,下面,带领大家走一个垃圾分类的识别工程 garbage_classification;
下面我通过配置,选择开发板为 esp-lyart v4.3
;
然后,就开始编译吧;下面我是 windows平台,端口是27;耐心等待编译!
make flash monitor ESPPORT=COM27
然后,对开发板说 “Hi,乐鑫” ,这时候,指示灯会亮起来,说明唤醒成功,之后说 “篮球”,它会对应的播放:“湿垃圾” 、 “干垃圾”
本地能识别的词语列表,可以看到是一个一个词语的拼音,我已经注释如下:
---------------------SPEECH COMMANDS---------------------
Command ID0, phrase 0: wei sheng zhi //卫生纸
Command ID0, phrase 1: shi zhi jin //湿纸巾
Command ID0, phrase 2: shi pin dai //食品袋
Command ID0, phrase 3: can jin zhi //餐巾纸
Command ID0, phrase 4: niao bu shi //尿不湿
Command ID0, phrase 5: mao sha //毛纱
Command ID0, phrase 6: mao fa //毛发
Command ID0, phrase 7: yi ci xing can ju //一次性餐具
Command ID0, phrase 8: jiu mao jin //旧毛巾
Command ID0, phrase 9: tao ci zhi pin //陶瓷制品
Command ID0, phrase 10: bei ke //贝壳
Command ID0, phrase 11: fa jiao //发胶
Command ID0, phrase 12: sao ba //扫把
Command ID0, phrase 13: da huo ji //打火机
Command ID1, phrase 14: gua zi ke //瓜子壳
Command ID1, phrase 15: cha ye zha //茶叶渣
Command ID1, phrase 16: ji rou //鸡肉
Command ID1, phrase 17: cai ye //菜叶
Command ID1, phrase 18: gua guo pi //瓜果皮
Command ID1, phrase 19: sheng fan sheng cai //剩饭剩菜
Command ID1, phrase 20: zhong yao yao zha //中药药渣
Command ID1, phrase 21: bing gan //饼干
Command ID1, phrase 22: yu mi //玉米
Command ID1, phrase 23: ji gu tou //鸡骨头
Command ID1, phrase 24: xi hong shi //西红柿
Command ID1, phrase 25: hua sheng ke //花生壳
Command ID2, phrase 26: niu kou dian chi //纽扣电池
Command ID2, phrase 27: guo qi yao pin //过期药品
Command ID2, phrase 28: lao shu yao //老鼠药
Command ID2, phrase 29: fei yao pin //非药品
Command ID2, phrase 30: fei you qi //废油漆
Command ID2, phrase 31: you qi tong //油漆桶
Command ID2, phrase 32: ying guang deng //荧光灯
Command ID2, phrase 33: sha chong ji //杀虫剂
Command ID3, phrase 34: su liao ping //塑料瓶
Command ID3, phrase 35: yi la guan //易拉罐
Command ID3, phrase 36: kuai di zhi xiang //快递纸箱
Command ID3, phrase 37: jiu bao zhi //旧报纸
Command ID3, phrase 38: guan tou he //罐头盒
Command ID3, phrase 39: ying su liao //硬塑料
Command ID3, phrase 40: bao zhuang zhi //包装纸
Command ID3, phrase 41: jiu tie guo //旧铁锅
Command ID3, phrase 42: lan qiu //篮球
Command ID3, phrase 43: bo li hu //玻璃壶
Command ID3, phrase 44: jiu wan ju //旧玩具
---------------------------------------------------------
那么它是如何识别是干垃圾还是湿垃圾的呢?可从上面看到,有个 ID0 、ID1 、ID2 、ID3 ,而在代码中,我们这样处理:
void speech_commands_action(int command_id)
{printf("Commands ID: %d.\n", command_id);switch (command_id) {case 0:iot_dac_audio_play(playlist[0].data, playlist[0].length, portMAX_DELAY);printf("干垃圾(Residual Waste)\n");break;case 1:iot_dac_audio_play(playlist[1].data, playlist[1].length, portMAX_DELAY);printf("湿垃圾(Household Food Waste)\n");break;case 2:iot_dac_audio_play(playlist[2].data, playlist[2].length, portMAX_DELAY);printf("有害垃圾(Hazardous Waste)\n");break;case 3:iot_dac_audio_play(playlist[3].data, playlist[3].length, portMAX_DELAY);printf("可回收垃圾(Recyclable Waste)\n");break;default:break;}
}
好了,目前就先这样带领大家入门,下篇会给大家介绍如何自定义命令词,比如“我要开火车”、“开灯”,然后做出指定的动作,比如开灯,关灯,敬请期待!!也欢迎加群讨论!!
另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈!
- 玩转
esp8266
带你飞、加群付费QQ
群,不喜的朋友勿喷勿加:434878850 - esp8266源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp8266
- esp32源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp32
- 关注下面微信公众号二维码,干货多多,第一时间推送!