不到100行代码玩转Siri语音控制 | ESP32学习之旅-Arduino版-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1754|回复: 0

不到100行代码玩转Siri语音控制 | ESP32学习之旅-Arduino版

[复制链接]
发表于 2020-6-5 15:37 | 显示全部楼层 |阅读模式
本帖最后由 铁熊 于 2020-6-5 16:00 编辑

[md]大家好,我是铁熊。本期给大家带来的是:掌控板(ESP32) Siri 语音识别智能终端。

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2lyb25wYW5kYWFh,size_16,color_FFFFFF,t_70)

不好意思,用这种标题党的方式把你吸引进来,不到 100 行代码的确有点夸张,因为实际上核心代码:

**不到 50 行!**

**不到 50 行!**

**不到 50 行!**

国际惯例,访问链接查看演示效果:

[https://www.bilibili.com/video/av93961105/](https://www.bilibili.com/video/av93961105/)

# 项目概述

前一段时间,掌控板 2.0 正式上市了,但是呢第一批产品生产数量有限,所以很多朋友买不到最新版的板子。拿着手里的 1.0 版本,却只能眼巴巴看着别人用掌控板 2.0 玩语音识别了。

![可怜](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUva2UtbGlhbi5qcGc?x-oss-process=image/format,png)

所以我们要坚决对这种行为说不!在这篇文章中,我就教大家让任何版本的掌控板(或其他基于 ESP32、ESP8266 芯片的开发板)实现语音识别,而且识别的效果更好!

![反对到底](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvZmFuLWR1aS1kYW8tZGkuZ2lm)

在项目开始讲解之前,我们先来看一下完整思路。在这个项目中,我们将掌控板 ESP32 设置为一个 Web 服务器,当用户在网页上访问这个服务器 IP 地址的时候,就会跳出如下界面。

![webpage](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvd2VicGFnZS5wbmc?x-oss-process=image/format,png)

我们可以通过点击 **Light On** 或者 **Light Off** 按键,来控制掌控板上的 RGB LED 的亮灭,也可以访问这两个按键的对应 IP 地址,来控制 LED 灯的亮灭。这样就完成了基本的通过 Web 页面控制掌控板的功能。

![web控制框架](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvd2ViLWtvbmctemhpLWt1YW5nLWppYS5wbmc?x-oss-process=image/format,png)

在这基础之后,我们可以进一步通过设置一些语音助手,比如 Siri、天猫语音精灵等,通过语音命令访问这些 IP 地址,从而实现语音识别开关灯的功能。

![siri控制框架](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvc2lyaS1rb25nLXpoaS1rdWFuZy1qaWEucG5n?x-oss-process=image/format,png)

# 库文件安装

这个项目需要用到 3 个 Arduino 库:**Adafruit_NeoPixel**、**ESPAsyncWebServer**、**AsyncTCP**。

Arduino 库安装的教程不是本篇的重点,这里不再赘述,只给出 3 个库的网址,大家可以自行百度查找 Arduino 怎么安装库。

- Adafruit_NeoPixel:https://github.com/adafruit/Adafruit_NeoPixel
- ESPAsyncWebServer:https://github.com/me-no-dev/ESPAsyncWebServer
- AsyncTCP:https://github.com/me-no-dev/AsyncTCP

# Arduino 代码

先把完整的程序放出来,再进行讲解。

![arduino_code](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvYXJkdWlub2NvZGUucG5n?x-oss-process=image/format,png)

在程序的开头,我们首先引入了需要用到的库函数:

```c++
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include <Adafruit_NeoPixel.h>
```

然后设置网络的账号和密码:

```c++
const char *ssid = "wifi_name";
const char *password = "wifi_password";
```

接着定义了 NeoPixel 对象(RGB LED 灯)和 WebServer 对象:

```c++
Adafruit_NeoPixel pixels(3, 17, NEO_GRB + NEO_KHZ800);
AsyncWebServer server(80);
```

在初始化函数 **setup()** 中,我们首先对串口和 RGB 灯进行了初始化:

```c++
Serial.begin(9600);
pixels.begin();
```

然后将掌控板连接到网络,并把 IP 地址在串口中打印出来:

```c++
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
    delay(1000);
    Serial.println("Connecting to WiFi..");
}
Serial.println("WiFi connected");

// Print ESP32 Local IP Address and Some Tips
Serial.print("Open your brower, and visit: http://");
Serial.println(WiFi.localIP());
Serial.println();
```

最后就是最重要的 Web 服务器设置。关于 Web 服务器设置的详细教程,可以查看官网:https://github.com/me-no-dev/ESPAsyncWebServer

这里只放出本文需要的代码。当访问根目录“**/**”时,显示一些提示语;当访问“**/on**”目录时,设置 LED 灯为亮,并在串口和网页端显示提示语;当访问“**/off**”目录时,设置 LED 灯为灭,并在串口和网页端显示提示语。

```c++
// Root / Webpage
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/plain", "Turn On Light: IP/on\nTurn Off Light: IP/off");
});

// Webpage to turn on light
server.on("/on", HTTP_GET, [](AsyncWebServerRequest * request) {
    pixels.setPixelColor(0, 0xFF0000);
    pixels.setPixelColor(1, 0xFF0000);
    pixels.setPixelColor(2, 0xFF0000);
    pixels.show();
    Serial.println("Light is on");
    request->send_P(200, "text/plain", "Light is on");
});

// Webpage to turn off light
server.on("/off", HTTP_GET, [](AsyncWebServerRequest * request) {
    pixels.clear();
    Serial.println("Light is off");
    request->send_P(200, "text/plain", "Light is off");
});
```

在 setup() 函数的最后,运行 Web 服务器:

```c++
server.begin();
```

至此,整个程序就编写完成了,**在 loop() 函数中,不需要做任何事**,当然你也可以运行其他你想要的代码。

# 程序上传

在 Arduino 中选择掌控板或者 ESP32 相关的芯片,然后将程序上传,打开串口监视器,我们可以看到串口监视器中提示我们访问相应的网址。(如果没看到相应信息,可以按一下掌控板后面的 RST 按键,重启程序)

![串口监视器打印网址](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvY2h1YW4ta291LWppYW4tc2hpLXFpLWRhLXlpbi13YW5nLXpoaS5wbmc?x-oss-process=image/format,png)

打开电脑浏览器或者手机浏览器,访问相应的 IP 地址,这里是:192.168.10.202,我们可以看到网页上显示了相应的提示信息。访问地址 **192.168.10.202/on** 可以打开 LED 灯,访问地址 **192.168.10.202/off** 可以关闭 LED 灯。

![webpage精简版](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvd2VicGFnZS1qaW5nLWppYW4tYmFuLnBuZw?x-oss-process=image/format,png)

尝试访问对应的地址,当访问 **192.168.10.202/on** 时,浏览器和串口监视器中,都输出了相应的提示信息,同时我们也可以看到掌控板上的 RGB 灯也亮了起来。

![lighton](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvbGlnaHRvbi5wbmc?x-oss-process=image/format,png)

当访问 **192.168.10.202/off** 时,浏览器和串口监视器中,也都输出了相应的提示信息,同时掌控板上的 RGB 灯也熄灭了。

![lightoff](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvbGlnaHRvZmYucG5n?x-oss-process=image/format,png)

# 网页设计

*这部分不是本文的重点,也不会影响最终语音控制的效果,所以如果您对网页设计不感兴趣,也可以略过,直接跳转到下一节。*

在上文中,我们已经基本完成了通过网页来控制 LED 灯的相关功能,但是这个网页毕竟还是太简陋了。所以我们对网页稍微进行一些优化。

HTML 是用来设计网页的代码,它可以控制我们在浏览器中看到的网页的外观样式。由于本人对网页设计也不擅长,所以这里只放一个基础的外观改进代码。

![html_code](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvaHRtbGNvZGUucG5n?x-oss-process=image/format,png)

上述代码最终形成的效果如下。我们可以直接点击 **Light On** 和 **Light Off** 两个按钮(或链接)来控制 LED 的亮灭,从而避免了手动输入网址的麻烦。

![webpage](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvd2VicGFnZS5wbmc?x-oss-process=image/format,png)

**当然在这个项目中,不用设计 HTML 代码也是完全没有问题的,我们只是为了方便在网页上控制。**

设计完网页,我们要怎么加到代码中去呢?其实也很简单。

我们在程序开头定义一个字符串变量,将网页的代码保存到这个变量中:

```c++
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      html {
        text-align: center;
      }
    </style>
  </head>
  <body>
    <h2>mPython Light Switch</h2>
    <a href="/on">Light On</a>
    <p></p>
    <a href="/off">Light Off</a>
  </body>
</html>)rawliteral";
```

然后将几处 **server.on()** 代码中的 **request->send_P()** 部分都修改为如下代码即可:

```c++
request->send_P(200, "text/html", index_html);
```

这个时候,重新上传程序,再去访问相应的网页,你就可以看到网页编程上图所示的样子了。

### 放个预告

如果你对网页设计比较擅长的话,你也可以设计好看一些的页面,比如:

![webpage案例](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvd2VicGFnZS1hbi1saS5wbmc?x-oss-process=image/format,png)

我们不仅可以在网页中控制 LED 灯的亮灭,也可以显示各种传感器的信息,这些内容以后再讲。

# 语音助手设置

前面说了那么多,终于来到语音识别设置部分了。

你是不是很好奇,代码中完全没有语音识别相关的部分,我们怎么做到语音识别呢?其实也很简单,既然可以通过网页访问相应的网址,我们是不是也可以让语音助手来访问相应的网址呢?

由于笔者手上没有其他语音助手或者智能音箱类产品,所以这里以 Siri 为例。

打开 iOS 系统自带的**捷径** App(英文名称 **Shortcuts**),没有没有的话,也可以去 App Store 免费下载:

![捷径下载](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvamllLWppbmcteGlhLXphaS5qcGc?x-oss-process=image/format,png)

然后分别设置两个捷径,命名为**开灯**和**关灯**。两个捷径的设置都很简单,就是访问给定的 URL 地址。

![开灯捷径](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUva2FpLWRlbmctamllLWppbmcucG5n?x-oss-process=image/format,png)

![关灯捷径](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvZ3Vhbi1kZW5nLWppZS1qaW5nLnBuZw?x-oss-process=image/format,png)

由于 iPhone 中的捷径是支持 Siri 语音识别调用的,所以我们可以直接通过 Siri 来运行这两个捷径,从而达到语音开关灯的效果。

# 效果演示

唤醒你的 Siri 看看效果吧。不过这里需要注意的是,你的 iPhone 和掌控板,必须处于同一局域网中。

![Siri开灯](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pcm9ucGFuZGEtMTI1OTc4MTExNS5jb3MuYXAtc2hhbmdoYWkubXlxY2xvdWQuY29tLzIwMjAtMDMtMTUvc2lyaS1rYWktZGVuZy5wbmc?x-oss-process=image/format,png)

# 总结

在本章中,我们学习了:

- WebServer 的基础用法,可以通过浏览器网页来控制 LED 灯的亮灭;
- 然后通过设计 HTML 网页代码,让交互界面更加友好方便;
- 最后通过 iOS 的捷径应用,实现了语音识别间接控制 LED 灯的功能

通过类似的方法,我们还能同时控制更多的 LED 灯、其他执行器,甚至通过语音识别来获得相应传感器的信息。当然你也可以将 Siri 语音识别的文字返回给掌控板,实现更多复杂好玩的创意。

# 代码下载

点击下方链接,查看完整代码下载地址:

[https://mp.weixin.qq.com/s/iNKaNmAN3nTWsaPIg0lEXA](https://mp.weixin.qq.com/s/iNKaNmAN3nTWsaPIg0lEXA)[/md]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 05:38 , Processed in 0.070630 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表