ESP8266 发起 HTTP 请求

ESP8266 是一款非常小巧的物联网芯片,在烧录了 AT 固件后,可以通过串口传递指令,进行 Wi-Fi 连接和发起 HTTP 请求。

市面上有许多集成了 ESP8266 芯片的开发板,例如 ESP-01 或 ESP-01S。笔者使用的是 ESP-01,已经预先刷好了 AT 固件。

准备工作

要将 ESP-01 连接到电脑上,需要准备一个 USB 转 TTL 模块,其输出接口应包括 VCC,GND,TX 和 RX。值得注意的是,ESP8266 芯片的供电电压是 3.3V,如果模块输出的 VCC 是 USB 的 5V 电压,那么不能直接接上 ESP-01,否则会造成损坏。

如果没有现成的硬件,用一块 Arduino 单片机也可以代替,因为 Arduino 单片机上是有 USB 转 UART 芯片的。向 Arduino 烧录一个空程序(即 setuploop 函数都为空的程序),就可以利用单片机上的 TX 和 RX 接口与 ESP-01 进行串口通讯了。不过这时要注意供电问题,ESP-01 在连接网络时功耗会增加,直接用 Arduino Nano 的 3.3V 输出可能带不动,会导致 ESP-01 重启。

连接方式

ESP-01 的引脚定义如下图所示。

使用时,将 VCC 和 CH-PD 接 3.3V 高电平,GND 接地,TX 和 RX 则连接到 USB 转 TTL 的模块(或者 Arduino 单片机)的 RX 和 TX 上。

串口测试

连接好之后,ESP-01 开发板上的电源指示灯会亮起。在电脑上打开串口通讯软件,例如 Arduino IDE 自带的串口监视器。AT 固件默认的参数是:串口波特率为 115200,换行符为 NL 和 CR。

接下来,可以通过 AT+GMR 命令查看固件信息:

其它常见的 AT 命令可以参考以下文章:
ESP8266_AT Wiki
ESP8266 - AT Command Reference

ESP-01 上电自检时也会向串口打印出信息,但在一般的串口监视器中会显示为乱码。原因是 ESP-01 用的晶振是 26MHz 而非 40MHz,其串口波特率为。这个波特率并不常见(Arduino IDE 中就没有),因此无法正确显示。

Wi-Fi 连接

首先将 ESP8266 重置,然后设置为 AP + Station 模式。

1
2
3
AT+RST
AT+CWMODE=3
AT+CWLAP

最后一个 AT+CWLAP 命令将搜索附近的 Wi-Fi 并显示出来。
随后,使用 AT+CWJAP 命令,指定 SSID 和密码用于连接 Wi-Fi:

1
AT+CWJAP="ssid","pwd"

ssidpwd 根据情况替换。如果连接成功,将返回

1
2
WIFI CONNECTED
WIFI GOT IP

接下来就可以发起请求了。我们以 World Time API 为例,这个网站可以根据客户端 IP 获得时间。

发起 HTTP 请求

发起请求使用 AT+CIPSTART 命令:

1
AT+CIPSTART="TCP","worldtimeapi.org",80

然后用 AT+CIPSEND 指定发送的内容长度。这一步非常关键,需要了解 HTTP 请求报文的格式。请求报文由 4 部分组成:请求行、请求头部、空行、请求数据;换行符为 \r\n。例如,对 World Time API 的请求是这样的:

1
2
3
GET /api/ip.txt HTTP/1.1
Host: worldtimeapi.org

注意最后的空行,它用来标识请求头部的数据已结束。这三行(加上换行符)一共是 52 个字符,因此先输入以下命令:

1
AT+CIPSEND=52

ESP8266 会返回一个 >,提示可以接收请求报文了。然后再输入前面给出的内容:

1
2
3
GET /api/ip.txt HTTP/1.1
Host: worldtimeapi.org

这里没有回显,每输入一行要按一下回车。全部输入完后,ESP8266 会发起请求,而 HTTP 响应的内容会被打印出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
>
Recv 52 bytes

SEND OK

+IPD,906:HTTP/1.1 200 OK
Connection: keep-alive
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers:
Cache-Control: max-age=0, private, must-revalidate
Content-Length: 309
Content-Type: text/plain; charset=utf-8
Cross-Origin-Window-Policy: deny
Date: Thu, 03 Sep 2020 03:51:48 GMT
Server: Cowboy
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Request-Id: f747d52b-09b0-401c-ae5e-5a36c1489b57
X-Runtime: 1ms
X-Xss-Protection: 1; mode=block
Via: 1.1 vegur

abbreviation: CST
client_ip: 124.64.16.34
datetime: 2020-09-03T11:51:48.793540+08:00
day_of_week: 4
day_of_year: 247
dst: false
dst_from:
dst_offset: 0
dst_until:
raw_offset: 28800
timezone: Asia/Shanghai
unixtime: 1599105108
utc_datetime: 2020-09-03T03:51:48.793540+00:00
utc_offset: +08:00
week_number: 36

最后使用 AT+CIPCLOSE 命令结束请求即可。


参考文章:HTTP 概述