# WiFi模块（ESP8266)

## 技能技模块介绍

### 简介

本模块使用乐鑫官方基于ESP8266EX的型号ESP-WROOM-02D, 4MB QSPI Flash。模块经过美国FCC, 欧洲CE-RED, 日本TELEC以及韩国KC认证。

用户可以使用该模块的全部功能，而非普通的串口透传模块。

### 模块结构

模块包括自动下载电路及通信模块。自动下载电路参照官方建议使用2个S8050三极管，接收来自CH340C下载器的RTS以及DTR信号并触发下载时序。

### 硬件连接

连接到Nyboard上：

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irviyPdr2PsEbkor%2F0.jpeg?generation=1617168141572643\&alt=media)

下载程序：

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvjW_RDxOjLCyP5%2F1.jpeg?generation=1617168141596850\&alt=media)

## 环境准备

我们使用Arduino下的ESP8266编程环境。

### 2.1 准备下载地址

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvkUJ5_1r1gD3K3%2F2.png?generation=1617168141547390\&alt=media)

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvlJePFPtyyeWCT%2F3.png?generation=1617168141572772\&alt=media)

下载地址为：<http://arduino.esp8266.com/stable/package_esp8266com_index.json>. 将其粘贴至Arduino首选项的附加开发板URL中即可。

随后打开“开发板管理器”，输入ESP8266或8266搜索，如下图所示：

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvmPFfuEya3p5AG%2F4.png?generation=1617168141629841\&alt=media)

下载ESP8266 by ESP8266 社区这个支持包即可。

### 配置开发板

下载完成后，我们选择：ESP8266 Board（当前最新版本为2.74）-> Generic ESP8266 Module， 如下图所示。

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvo7f6leOeV6h63%2F6.png?generation=1617168141549058\&alt=media)

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvpVY5VMod57KQ7%2F7.png?generation=1617168141550638\&alt=media)

接着我们来配置以下参数：

| 参数名称          | 含义         | 选择参数               |
| ------------- | ---------- | ------------------ |
| Builtin Led   | LED引脚      | 2                  |
| Upload Speed  | 上传程序速率     | 921600（115200会比较慢） |
| CPU Frequency | 处理器频率，越高越强 | 160MHz             |
| Flash Size    | 闪存空间及分区    | 4MB即可（单独解释OTA）     |
| Reset Method  | 复位方法       | DTR复位              |
| lwIP variant  | 轻量IP协议栈选择  | V2 Lower memory    |
| Erase Flash   | 擦除flash的方法 | Only sketch（只擦程序区） |

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvqPyTY6gEBKGRf%2F8.png?generation=1617168141562220\&alt=media)

### Flash空间的规划

这里单独提一下Flash大小和分区。

#### Arduino 与 ATMega328P

Arduino UNO使用的ATMega328P内置32KB的Flash和1KB的EEPROM。当使用Arduino的时候，我们是这样划分Flash和EEPROM的：

| Arduino Boot Loader | Sketch（程序区） |   | EEPROM |
| ------------------- | ----------- | - | ------ |
| 1KB                 | 31KB        |   | 1KB    |

#### 2.3.2 ESP8266 的Flash划分

如果按照我们选的ESP8266 4MB Flash的划分方式，如下图：

| ESP Boot loader | Program-A | Program-B | Data area(File system) |
| --------------- | --------- | --------- | ---------------------- |
| In SoC Flash    | 1019KB    | 1019KB    | 2MB                    |

相比UNO使用整块的Flash存储Sketch程序，我们使用2个小块来分别存储A程序和B程序，并单独划分了一块数据区。这样的好处是什么呢？为什么叫OTA模式呢？

当您拿到8266模块时，内置程序位于A区，B区域和文件系统区域为空，Boot loader控制程序从A区启动。

当需要无线更新时，我们把新的程序存储至B区域。此时若发生传输中断，下次启动时依然由Boot loader控制程序从A区启动。

当更新并校验数据完毕后，Bootloader启动项默认编程B，下次开机时从B区启动。

数据区相对程序区是独立的，程序可以直接读写数据区的数据，也可以使用客户端直接上传数据。

当擦除程序时，只会擦除程序区，而数据分区默认不会擦除。

### 测试下载

配置好后，我们使用Arduino经典的“Blink”程序来测试ESP8266开发板。打开Blink工程，配置好开发板，将模块插在USB下载器的通信模块调试接口上，下载Blink例程。相比UNO编译时间稍长，Linking后会以百分比的形式显示下载进度：

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2Fdocs%2F-MX5in6n7A0W1Y5xGIQc%2F-MX5irvs91y6flRguFm3%2F10.png?generation=1617168141552677\&alt=media)

ESP8266的Arduino支持文件较大，Blink使用了257KB的Flash及26.8KB的RAM。

## 下载WiFi控制固件

固件地址：<https://github.com/PetoiCamp/OpenCat/tree/main/ModuleTests/ESP8266WiFiController>

该工程包括4个文件：

* ESP8266WiFiController.ino ：Arduino项目文件，包含核心代码
* mainpage.h：以字符串存储的主页文件
* actionpage.h：以字符串存储的动作遥控网页文件
* calibrationpage.h：以字符串存储的校准舵机网页文件

请将它们放置于名为”ESP8266WiFiController“的文件夹内，打开ino文件，并下载至ESP8266 WiFi模块上即可。

## 使用说明

完成WiFi模块的代码下载后，第一次使用建议连接在下载器上。

打开手机的WiFi并搜索网络，会搜索到一个名为“Bittle-AP”的无加密的无线热点，点击连接。

<figure><img src="https://201656985-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQ6a951Q6Jn1Zzt5Ajr-3369173170%2Fuploads%2FIXO28nMNw98k3UBWO6br%2FMobile.jpg?alt=media&#x26;token=d344899e-5b63-4f43-b096-4280d3d0135f" alt=""><figcaption><p>手机wifi设置页面</p></figcaption></figure>

![电脑wifi节点列表](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQ6a951Q6Jn1Zzt5Ajr%2F-MYsASVWL_vlk8R4Uof4%2F-MYsG4JXdih1tbpvpXKq%2Fimage.png?alt=media\&token=4c649315-2fc4-42a1-a9c2-9f6b121dc2cf)

{% hint style="info" %}
如果您的手机有自动网络优化功能，因为Bittle的WiFi热点是没有Internet连接的，手机会自动切换至有网络连接的WFi网络或启用数据流量。
{% endhint %}

连接“Bittle-AP”后，默认浏览器会自动跳转至Bittle无线模块的”WiFiManager“页面。

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQ6a951Q6Jn1Zzt5Ajr%2F-MYsASVWL_vlk8R4Uof4%2F-MYsGMdMordfoNrxMUkJ%2Fimage.png?alt=media\&token=d0b4c46f-e966-4e4c-af19-27bfbd3947eb)

如果没有跳转，**默认网关地址为：192.168.4.1**。请打开浏览器手工输入后进入配网页面。点击“Configure WiFi” 配置无线网络。

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQ6a951Q6Jn1Zzt5Ajr%2F-MYsASVWL_vlk8R4Uof4%2F-MYsGTcz6Y5mneBZgFhC%2Fimage.png?alt=media\&token=3c4b3df3-58bc-46ea-a6df-a418db65f7e6)

在WiFiManager页面，Bittle的无线模块会自动搜索附近全部的WiFi SSID并显示。点击您自己的WiFi SSID并输入密码后，Bittle会首选连接到这个网络。

![](https://201656985-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQ6a951Q6Jn1Zzt5Ajr%2F-MYsASVWL_vlk8R4Uof4%2F-MYsGZcOK9Lt8U6R9coG%2Fimage.png?alt=media\&token=71e30254-67e4-4dcc-b9b6-77bebcf592bc)

连接成功后，Bittle会打印出DHCP分配的IP地址。如果您是高阶用户，也可以在Arduino中配置固定的IP地址。

<figure><img src="https://201656985-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQ6a951Q6Jn1Zzt5Ajr-3369173170%2Fuploads%2F4iejnXWY6g1UBvRazNUt%2FSerial_Monitor.jpeg?alt=media&#x26;token=449ab1ce-b0a7-411e-93ab-3f7f3102d300" alt=""><figcaption></figcaption></figure>

在浏览器中输入WiFi模块分配到的IP地址后，即可访问Bittle的控制界面。

<figure><img src="https://201656985-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQ6a951Q6Jn1Zzt5Ajr-3369173170%2Fuploads%2FrPFkLntPotHfldng6EWV%2Fhome.jpeg?alt=media&#x26;token=2dfff5ea-1e0d-4c5d-8de4-ba6cc28add69" alt=""><figcaption><p>主页</p></figcaption></figure>

<figure><img src="https://201656985-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQ6a951Q6Jn1Zzt5Ajr-3369173170%2Fuploads%2F0RP8CtepMd5fe9R9gmqV%2FActions02.jpeg?alt=media&#x26;token=f86f3795-05bb-42ce-8c71-dd16441bcea9" alt=""><figcaption><p>技能控制页面</p></figcaption></figure>

<figure><img src="https://201656985-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQ6a951Q6Jn1Zzt5Ajr-3369173170%2Fuploads%2FChYWS0tHs6XcvYwoUiTd%2FJointCalibration02.jpeg?alt=media&#x26;token=c57bd806-2a35-4c46-b9ac-39f87c0e8bd8" alt=""><figcaption><p>关节校准页面</p></figcaption></figure>

## 示例代码简介

示例代码是一个简单的web服务器例子，包含2个HTML页面。2个页面以字符串常量的形式存储在2个头文件中。这样的做的好处是避免了不停调用client.print函数将网页的html弄得比较乱。

### 3.1 设置WiFi热点

首先设置好需要接入的WiFi热点账户和密码，之前的程序我们在Arduino代码中使用字符串配置WiFi账号和密码，当网络环境发生变化的时候需要重新烧录程序，非常不便。

为了方便使用我们使用了WiFiManager库，可以以Web的方式配置WiFi接入点的信息。

```
  // WiFiManager
  WiFiManager wifiManager;

  // Start WiFi manager, default gateway IP is 192.168.4.1
  wifiManager.autoConnect("Bittle-AP");
```

### 3.2 新建web服务器对象

新建一个web服务器的对象，配置端口80（常用的HTTP服务器端口）

```
ESP8266WebServer server(80);
```

### 3.3 配置3个http响应函数

HTTP响应函数的功能是对传来的HTTP请求作出反馈

```
void handleMainPage() {
  server.send(200, "text/html", renderHtml(FPSTR(mainpage), "Home"));
}

void handleCalibrationPage() {
  server.send(200, "text/html", renderHtml(FPSTR(calibrationpage), "Calibration"));
  Serial.print("c");
}
```

这2个handler函数返回200（OK）以及对应的网页HTML代码供客户端显示。

```
void handleActionPage() {
  if (server.hasArg("name"))
      String _ = sendCmd();
  // Return to actionpage after CMD
  server.send(200, "text/html", renderHtml(FPSTR(actionpage), "Actions"));
}
```

handleActionPage函数略微有一些不同，这是一个带参数传递的http请求处理函数。例如：当参数为“gyro”，调用sendCmd函数，将其转换为机器人可识别的串口指令“g”,（开关陀螺仪）通过WiFi模块的串口发送给机器人，这样我们的机器人就会执行指令。

那么这个“gyro”参数是怎么生成和传递的呢？是因为我们给服务器发送了这样一条带值传递的HTTL request：

```
http：//IP address or DomainName/actionpage?name=gyro
```

服务器通过函数解析其中的actionpage参数，解析出name是gyro。

这条URL，我们可以直接在浏览器中用键盘输入后执行，更常用的方法是在我们的ActionPage网页文件，为 **GyroOn/Off** 按钮增加一个链接。当按下（onclick）**GyroOn/Off** 按钮时，会向主机发送上面的URL。完整的**GyroOn/Off** 按钮配置如下：

```
<button style="width: 100%" onclick="httpGet('/actionpage?name=gyro')">GyroOn/Off</button>
```

执行完name解析后，我们令其返回ActionPage，否则网页就白屏了。

```
server.send(200, "text/html", renderHtml(FPSTR(actionpage), "Actions");
```

最后我们定位接受到的HTTP请求对应的处理函数

```
server.on("/", handleMainPage);
server.on("/actionpage", handleActionPage);
server.on("/calibrationpage", handleCalibrationPage);
```

### 3.4 启动服务

```
server.begin();
Serial.println("HTTP server started");
```

## 处理客户请求

服务器一旦启动将会一直运行，而客户端的HTTP请求会从不停的发送。每次都需要处理：“连接 – 处理请求 – 断开”，所以客户端的请求是主循环。

好在ESP8266的web服务器库已经为我们做好了这一复杂的过程。我们只需要在主循环中调用客户端处理函数，按照我们刚刚设置好的服务器处理策略进行处理。

```
void loop(void){
 server.handleClient();
}
```

这样一个最简单的web控制的服务器端就做好了。

## 更多玩法

相比Nyboard主板的ATMega328P，ESP8266的资源更多，玩法也更多。比如：

基于HTTP的Restful的控制API，并连接物联网平台

MQTT和Node-Red的消息传递；

使用WiFi给模块更新固件；

使用ESP8266强大的CPU作为Nyboard的协处理器，处理运动数据或存储更多动作。
