本文作者:

开源电子平台兴起以来,诞生了不少的创客们,他们用天马行空的想象力,创造出各种新鲜有趣的作品,他们热衷于改变千篇一律的生活,享受科技创造带来的乐趣。其中与我们的生活息息相关的就包括智能家居相关的作品,在这方面国内外大牛们各显神通,纷纷创造出自己独特的智能家居作品,例如智能窗帘、智能宠物投食机、家庭气象站、智能小夜灯等居家必备的实用项目。

我自己也喜欢改造家里的电器,赋予传统家具新鲜的活力,让它们知冷暖,变成真正的生活小帮手。但随着改造或者是创造出的智能家居项目越来越多,他们的控制变得越来越困难:往往需要切换到不同 App 去控制不同的设备,这变得相当繁琐,而且它们之间是相互独立的。那有没有办法使他们有机结合在一起呢?

语音控制就是一个非常理想的控制方法,我们只需要一句话就可以获取各种传感器的信息,也可以控制各种执行器完成我们的操作。本期教程就教大家打造一个智能家居语音助理,通过语音识别享受智能家居带来的便捷与乐趣。

先来看一下演示视频,对本期教程实现的效果有一个大致的了解。视频中演示了如何用语音控制灯的开关、查询灯的状态以及获取室内温度。

作品效果图

可以通过继电器将本项目中的 LED 灯换成普通的灯泡,视觉效果更佳,如下图所示。利用这种方式,我们可以控制的设备就不仅仅是模拟的 LED 灯了,而是智能家居里的各种设备。

设计思路

下面开始详细讲解程序设计过程,项目框架如下:

语音助理控制端,我们采用 M5StickC 开发板来编程,因为 M5StickC 开发板集成了电池、麦克风以及屏幕,可以实现方便地实现语音识别,是一个比较理想的测试模块。

智能小灯与传感器受控端,我们采用 ESP8266 结合各种传感器来制作,ESP8266 是一款性价比很高的开发板,性能强大,同时又可以连接 WiFi,接入各种物联网平台。

物联网方面,我们采用 Blynk 物联网框架,因为 Blynk 是一个相对简单实用的物联网平台,拥有丰富的控制组件,仅需少量代码即可完成复杂的物联网开发,又因其具有开放 API,故而可以轻松的集成到种物联网项目或者是自己 DIY 的 App 当中。

准备工作

我们使用 Arduino 软件来编写本项目的程序,开发板选择 ESP8266 及 ESP32 类型。至于如何在 Arduino 中配置 ESP8266 及 ESP32 的开发环境,不在本文的介绍范围,请自行查阅相关资料。

要完成本课程的项目,需准备如下材料:

  • M5StickC 开发板;

  • ESP8266 开发板;

  • DHT11 温湿度传感器。

电路接线

DHT11 温湿度传感器连接 ESP8266 开发板的 GPIO5 接口。注意视频中使用的开发板与下图不同。视频中采用了一块集成的 ESP8266 开发板,自带 DHT11 温湿度传感器,省去了接线的烦恼。但是掌握了接线原理,使用任何 ESP8266 开发板都是可以的。

语音助理程序设计(控制端)

第一步:获取语音助理项目及授权码

此处我使用的 Blynk 服务器是国内第三方搭建的免费服务器,地址是:blynk.mixly.org

使用 Blynk App 扫描下面的二维码,就可以克隆智能家居助理项目,并且复制 Blynk 授权码备用。(对 Blynk 不熟悉的朋友,可以参考裘炯涛和陈众贤老师编写的《物联网So Easy!》这本书,上面有很多 Blynk 物联网的基础知识及案例,可以帮助大家快速入门。

第二步:获取 M5 语音识别授权码

我们先去 M5 官方网站(https://m5stack.com/pages/download)下载并安装 M5Burner 烧录软件。如下图所示,打开 M5Burner 软件插入 M5StickC 开发板,选择自己的端口号,然后选择 ATOM 模块看到 EchoSTT 点击 Get Token 获取语音识别授权码,获取到授权码后复制该授权码备用。完成这些步骤之后就可以关闭 M5Burner 软件了。

第三步:修改程序

使用 Arduino IDE 软件选择本教程附录的 voice_assistant 程序并打开(程序下载方法见文末)。主要代码如下:

// Blynk与联网相关库
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>// 语音识别相关库
#include <driver/i2s.h>
#include <HTTPClient.h>
#include "BaiduRest.h"// M5StickC相关库(含TFT彩屏库)
#include <M5StickC.h>#include "image.h"  // 图片取模数据
#include "Function_wrapper.h"  // 函数封装// -------------------------- 用户设置开始 ------------------------------ //
// -------------------------------------------------------------------- //// WiFi账号与密码
char ssid[] = "********";
char pass[] = "********";// 语音识别授权码
#define voiceAuth "f008d1c88064c8c38084de074b73b823"// Blynk授权码
char auth[] = "SDzbDasOYxRDYqr7NdZiSIk2VSI52e6b";// -------------------------------------------------------------------- //
// -------------------------- 用户设置结束 ------------------------------ //BaiduRest rest;uint8_t microphonedata0[1024 * 80];
size_t byte_read = 0;
int16_t *buffptr;
uint32_t data_offset = 0;
String speakStr;
bool speakFlag = false;
String feedback;
String Control_instruction;// Blynk反馈信息显示
BLYNK_WRITE(V1) {feedback = param.asStr();Serial.println(feedback);M5TextDisplay(feedback);
}// API指令转接
BLYNK_WRITE(V2) {Control_instruction = param.asStr();Serial.println(Control_instruction);// 解析虚拟引脚数据uint8_t Virtual_pin = String(String(Control_instruction).substring(0, 2)).toInt();String Value = String(Control_instruction).substring(2, String(Control_instruction).length());// 将解析指令发送到对应解析虚拟引脚触发webhook请求Blynk.virtualWrite(Virtual_pin, Value);
}// M5StickC屏幕显示
void M5TextDisplay(String Text) {M5.Lcd.setRotation(1);M5.Lcd.fillScreen(BLACK);M5.Lcd.setCursor(10, 5);M5.Lcd.writeHzk(utf8togb2312(String(Text).substring(((1 - 1) * 3), (9 * 3))));M5.Lcd.setCursor(10, 30);M5.Lcd.writeHzk(utf8togb2312(String(Text).substring(((10 - 1) * 3), (18 * 3))));M5.Lcd.setCursor(10, 55);M5.Lcd.writeHzk(utf8togb2312(String(Text).substring(((19 - 1) * 3), (27 * 3))));
}void setup()
{Serial.begin(9600);// M5显示屏初始化M5.begin();M5.Lcd.setRotation(0);M5.Lcd.setTextSize(1);M5.Lcd.setTextColor(WHITE, BLACK);M5.Lcd.loadHzk16();M5.Axp.ScreenBreath(10);M5.Lcd.drawXBitmap(0, 40, network, 80, 80, RED);  // 显示WiFi离线图标// M5按键初始化pinMode(37, INPUT_PULLUP);// 连接Blynk服务器Blynk.begin(auth, ssid, pass, "blynk.mixly.org", 8080);// 麦克风初始化Serial.println("Init microphone");InitI2SSpeakOrMic(1);delay(100);rest.settoken(voiceAuth);M5.Lcd.drawXBitmap(0, 40, network, 80, 80, GREEN);  // 显示WiFi在线图标M5.Lcd.setRotation(1);
}void loop()
{// 按下M5按键开始语音识别if (!digitalRead(37)){M5.Lcd.setRotation(0);M5.Lcd.fillScreen(BLACK);M5.Lcd.drawXBitmap(0, 17, microphone, 80, 125, GREEN);data_offset = 0;speakFlag = false;// 麦克风开始录音InitI2SSpeakOrMic(0);while (1){i2s_read(I2S_NUM_0, (char *)(microphonedata0 + data_offset), 1024, &byte_read, (100 / portTICK_RATE_MS));data_offset += 1024;// 松开M5按键或超时停止录音if (digitalRead(37) || data_offset >= 81919)break;}Serial.println("end");// 提交录音,若果识别成功返回识别文字if (rest.Pcm2String(microphonedata0, data_offset, DEV_PID_MANDARIN, &speakStr) != -1){Serial.println("Speech recognition success!");Serial.println(speakStr);if (speakStr.equals("")) {M5TextDisplay("您没有说话!");   // 未说话反馈显示} else {Blynk.virtualWrite(V0, speakStr);  // 识别语音结果文本发送到Blynk显示M5TextDisplay(speakStr);  // M5屏幕显示语音识别结果文本}speakFlag = true;} else {Serial.println("Voice recognition failed!");M5TextDisplay("语音识别失败!");}}Blynk.run();
}

替换程序中的 WiFi 网络信息、语音识别授权码及 Blynk 授权码。若使用其他 Blynk 服务器,请同时修改程序中的 Blynk 服务器地址。然后在 Arduino IDE 中选择自己的 M5StickC 串口号,开发板选择 ESP32 开发板下的 M5Stick-C 开发板。

Blynk 中的文本显示标签 V0 主要用于调试目的,可以显示语音识别的结果;

文本显示标签 V1 用于反馈状态的显示,当 V1 数据发生改变时,将触发 V1 发送事件,将 V1 数据发送到语音助理进行显示;

指令输入框 V2 用来发送控制指令,指令格式为 xxXXX,如 03on,其中 03 为固定两位数字不足位请补 0,该数字代表了语音助理未被使用到虚拟引脚,on 为智能家居有效控制指令。语音助理将指令进行解析,并且拆分为虚拟引脚号 Virtual_pin 及有效控制指令 Value。解析完成后对 Blynk 的虚拟引脚 Virtual_pin 发送控制指令 Value,从而触发 Blynk 的 webhook 组件发送 http 请求,控制其他设备或是获取状态,webhook 组件将在后面进行具体介绍。此处用到了条件控制组件 Eventor Settings,该组件用于判断语音识别的文本是否是特定关键字(例如开灯或关灯之类的关键字),当为特定关键字时,设置指令输入虚拟引脚 V2 的值为相关智能家居的有效控制指令。其工作流程如下图所示:

智能小灯程序设计(受控端)

使用 Blynk App 扫描下面的二维码,克隆智能小灯项目,并且复制 Blynk 授权码备用。

受控端智能小屋程序比较简单,直接采用 Mixly 软件进行图形化编程,程序如下:

注意这里有两个授权码,第一个授权码是智能小灯的授权码,第二个是语音助理的桥接授权码。关于 Blynk 桥接知识的讲解,可以参考裘炯涛和陈众贤老师编写的《物联网So Easy!》这本书,上面有很多 Blynk 物联网的基础知识及案例,可以帮助大家快速入门。

程序控制 ESP8266 板载指示灯的亮灭,当虚拟引脚 V0 按钮按下时,将 V0 数据发送到 ESP8266。ESP8266 收到 V0 数据后进行打印并判断:当发送 1 时将 GPIO2 设置为低电平,板载指示灯点亮;当发送 0 时将 GPIO2 设置为高电平,板载指示灯熄灭。

虚拟管脚 V2 用于开放控制指令。当 Blynk 反馈输入框输入控制指令时,ESP8266 接收指令并处理。当发送指令 on 时将板载指示灯状态变量 control 设置为 1,同时将状态发送到 Blynk 刷新按钮状态,桥接虚拟引脚给 M5StickC 语音助理反馈处理信息并显示,其他指令类似分析方法,示例中提供了on、off、Inquire、temperature 四个指令接口,分别用来开灯、关灯、查询状态及查询 DHT11 的温度。当然你还可以添加更多的执行器或者传感器来满足你的控制需求。

自定义语音指令

在讲解自定义语音指令设置前,我们先来了解下 Blynk 开放 API、Webhook 组件、Eventor Settings 组件,这将有助于你理解自定义语音指令运行的逻辑是什么。

Blynk 开放 API 介绍

Blynk 开放了一些 API,可以让我们更加灵活地访问或者控制 Blynk 物联网项目,这里我仅介绍 Blynk 虚拟引脚的数据修改 API,对于其他 Blynk 开放 API 请参考以下网址进行学习:

https://blynkapi.docs.apiary.io/#reference/0/write-pin-value-via-get/write-pin-value-via-get

Blynk 修改虚拟引脚值的 API 格式为:

http://<blynk-cloud.com>/<auth_token>/update/<pin>?value=<value>

  • 其中 <blynk-cloud.com> 为 Blynk 官方服务器地址,如果使用本地服务器,如本文使用的服务器,请对应设置为 blynk.mixly.org:8080;

  • <auth_token> 为被控项目的具体项目授权码,<pin> 为控制的虚拟引脚,最后的 <value> 为想要设置的虚拟引脚值。

例如智能小灯项目中,我们使用了虚拟引脚 V1 作为控制指令的输入接口,我们在浏览器中输入:

http://blynk.mixly.org:8080/UDKsGEONVb7UrcafQ7T47SNLt902Wzjb/update/V1?value=on

就可以在 ESP8266 的板载指示灯将被点亮,同时语音助理上面也会显示智能小灯的反馈信息。

通过这个例子,相信你已经简单了解了 Blynk API 是什么了,它可以灵活性应用在很多项目中,将 Blynk 与其他库或组件有机结合到一起。

Blynk Webhook 组件介绍

Webhook 组件是 Blynk 的特殊功能组件之一,它能够发送 http 请求,获取网络的各种数据,例如可以用它来获取天气、查询快递等等。

只需要知道信息流的 API 就无所不能,例如语音助理就是将录音文件发送到百度 API 进行语音识别,然后返回语音识别结果。理论上来说,通过在线语音合成,我们完全可以将智能家居的反馈文本朗诵出来。

我们来看一下 Webhook 组件的设置界面都有哪些东西。

Webhook 组件有三个特点:

  • 第一是触发方式。Webhook 组件可以由虚拟引脚的值改变进行触发,虚拟引脚值的改变可以是 APP 改变的,亦可以是硬件端发送的数据变化而改变,其触发限制为 1 秒触发一次,当然你可以通过修改服务器配置来解除此限制;

  • 第二是参数提交方式。你可以将虚拟引脚的值作为参数进行提交,此时将虚拟引脚值用 /pin/ 占位符来代替,例如:

    http://blynk.mixly.org:8080/UDKsGEONVb7UrcafQ7T47SNLt902Wzjb/update/V1?value=/pin/;

  • 第三是 Webhook 数据的获取方式。其获取方式与普通虚拟引脚从 APP 发送到硬件相同。在语音助理这个项目当中我们获取的是字符串类型的数据。

Blynk Eventor Settings 组件介绍

Blynk 条件控制组件 Eventor Settings 可以用来使用条件触发动作,其触发条件可以是虚拟引脚的值大于某个值、等于某个值或者是出现特定字符串等,也可以是某个星期几的某个时间点等为条件进行触发。触发后的动作可以设置某个虚拟引脚值、打开某个 GPIO、发送通知邮件、设置组件属性等。

在语音助理这个项目当中我们就是通过判断语音识别文本数据 V0 是否等于某个特定关键词来进行触发的,其触发动作为修改控制指令 V2 的值并发送到语音助理,最后由语音助理解析指令,进而触发 Webhook 组件发送控制请求获得反馈的。具体例子我们见下面的创建语音控制。

创建语音控制

语音控制自定义流程如下,我们按照下面的步骤添加语音指令即可享受语音控制带来的乐趣,对于同一项目你仅需创建条件触发关键词而无需修改 Webhook 组件属性。按教程所示方法制作的物联网项目,一个 Webhook 组件即代表这个物联网项目本身。

小结

通过本次教程,我们学会了如何使用在线语音识别识别任意语音,M5StickC 的语音识别是基于百度的短句语音识别,其支持语言有普通话、普通话/简单英语、英语、粤语四种模式,本教程使用的是第一种普通话模式,对于其他的语言请参考库文件 BaiduRest 进行相关参数设置。

教程中我们介绍了 Blynk 开放 API 以及 Blynk Webhook 组件的使用方法,教程中的相关技巧或许可以让你对 Blynk 有更深入的了解,Blynk 作为一款快速原型开发的物联网平台,可以轻松的实现我们的各种创意而无需学习复杂的编程知识,相信你通过本教程的知识能够创造出更多有趣的物联网项目。

值得一提的是,在本教程中我们使用按钮去使用语音识别,你完全可以加上语音唤醒以达到更加灵活的使用目的,这将比某爱、某猫控制智能家居来的更加灵活,而且完全可以自定义,如果你想让语音助理能够开口说话不妨试试语音合成吧。

想到即做到,让我们一起捣鼓一起创造吧。我是默,我们下期再见!

代码下载

关注公众号“铁熊玩创客”,后台回复“语音助理”,就可以获取本次课程的全部源码下载链接。


欢迎转发朋友圈。如需转载,请注明出处和原作者。

点个在看支持一下吧 ↓↓↓

DIY 智能家居语音助理 —— 语音控制万物相关推荐

  1. 2022-2028全球与中国智能家居数字助理(语音)市场现状及未来发展趋势

    本文研究全球及中国市场智能家居数字助理(语音)现状及未来发展趋势,侧重分析全球及中国市场的主要企业,同时对比北美.欧洲.中国.日本.东南亚和印度等地区的现状及未来发展趋势.  2021年全球智能家居数 ...

  2. 开源项目搭建私有物联网智能家居接入天猫精灵控制

    开源项目搭建私有物联网智能家居接入天猫精灵控制 最近几年随着物联网的高速发展,众多智能硬件厂商都开发出自己的智能家居产品,都想在物联网智能家居市场上占有自己的一席之地,而随着众多智能音箱的问世,智能家 ...

  3. 智能家居 (6) ——语音识别线程控制

    目录 语音识别线程控制代码 inputCommand.h mainPro.c voiceControl.c 代码测试 往期文章 语音识别线程控制代码 inputCommand.h #include & ...

  4. 安卓手机远程控制DIY智能家居设备(ESP8266)

    一.准备材料: 手机(安卓手机,如果没有请忽略整篇文章). 电脑(windows, 如果没有请忽略整篇文章,此文章不适合大神阅读). DIY智能设备(ESP8266基本上是绕不过去的,如果没有那就买一 ...

  5. 从零开始的DIY智能家居--自己在家手搓一套人脸识别智慧猫眼系统

    前言 ​ 最近整理资料的时候,才发现之前写的一个智慧猫眼的爱智场景没有给大家写文章介绍,可能有的小伙伴之前也看到爱智官方引用我的这个代码给大家进行了一个直播演示,我个人还是觉得自己也有必要简单介绍一下 ...

  6. android客户端显示拓扑结构,基于WIFI构建的智能家居系统综合接入及控制装置(Android客户端及综合测控).doc...

    基于WIFI构建的智能家居系统综合接入及控制装置(Android客户端及综合测控) 毕 业 论 文(设计) 中文题目: 基于WIFI构建的智能家居系统综合接入 及控制装置(安卓及综合测控) 英文题目: ...

  7. 汽车与智能家居互联时代 语音控制很关键

    来源: I CTA 编译:网易智能 nariiy 摘要:对于大多数人而言,最昂贵的两个物件是家和汽车.如今,技术将这二者联系在一起,并互为延伸.在不断加速发展的趋势中,智能家居和联网汽车正在融合,而这 ...

  8. 毕业/课程设计——基于STM32的智能灯光控制系统(物联网、智能家居、手机APP控制、语音控制)

    文章首先介绍本系统所包含的功能,主要包含六方面功能,之后逐步分享开发过程,其流程如下:点亮灯带(三极管)→调节灯光亮度(PWM)→为系统添加远程控制功能→为系统添加语音识别功能→添加超声波姿态监测功能 ...

  9. Marvell深耕智能家居行业 赞同语音控制将成必然发展趋势

    物联网的发展速度之快,超出了很多人的想象.而在这其中,智能家居的发展尤为引人注目.根据Ovum<智能家居预测:2015-2020>报告显示,未来四年及以后,智能家居技术的普及将会出现加速. ...

最新文章

  1. C语言程序设计 搜集C/C++编译器
  2. STP文件服务器,综合监控stp服务器
  3. 如何安全的在不同工程间安全地迁移asset数据?三种方法
  4. 三大主流开源工作流引擎技术分析与市场预测
  5. 【随感】i'm new here
  6. ecms 列表模板php,帝国CMS列表页模板list.var分别调用年月日(显示个性时间日期)
  7. html页面加载动画尺寸,6种CSS3加载动画
  8. mysql 5.5 外键_MySQL 5.5添加外键失败,错误[HY000] [150]和[HY000] [1005]
  9. zookeeper 进入客户端_Zookeeper基础知识简单介绍
  10. cookie与session的比较
  11. 为Mac任意命令设置快捷键
  12. mess组网 中继_Mesh路由和无线中继的差距在哪里?谁才是更好的选择?
  13. 7大需求分析方法与5大分析过程
  14. 欧几里得(Euclid)算法
  15. 尚硅谷前端框架vue语法(二)
  16. gitlab上创建新的分支并发布代码
  17. NetInside可观测分析平台上线了
  18. 【干货】磨金石教育UI快速入门!U设计基础知识整理,新人必备
  19. 0000-0-1-C语言可以做什么C语言可以干啥C++语言可以做什么C++语言可以干啥C语言就业前景C++就业前景
  20. ASO优化:为什么要做APP竞品分析

热门文章

  1. 西门子808 802 828 PLC密码获取
  2. 前端面试总结 -- 网络基础之 HTTP 和 HTTPS
  3. opencv-黑马程序员---Chapter1 opecv简介
  4. 大型数据库设计原理实验1
  5. stm32f429的u-boot、uclinux内核烧写说明
  6. 软件测试的自我修养:正向思维与逆向思维
  7. php php_zip.dll,php_zip.dll下载|
  8. 骨干是折腾出来的 读书笔记1
  9. 输入被除数和除数,求商
  10. 产品经理眼中的MVP