0:前语

推荐太极创客,学习ESP8266模块的更多知识。

1:连线

ESP8266通过串口与电脑或者其他单片机实现交互,串口的使用比较简单。以最简单的ESP8266模块为例进行介绍。其他模块可能已经有了usb type-c或者其他接口,就直接用对应接口的线和设备连接就可以了。下图的模块,没有usb接口,因此需要我们自己连线。

模块共引出了8个引脚,其中,

VCC:接3.3V电压,为模块供电。

GUD:接地

GPIO0:平时直接悬空。需要刷固件的时候接地。

CH_PD:通过一个10K电阻接3.3V电压,表示模块处于工作状态。否则将不工作。

串口通信引脚,

RXD:串口输入,表示这个引脚会接收其他模块传入的信息。与其他模块的TX引脚相连。

TXD:串口输出,接其他模块的RX引脚,把数据传给其他模块。

通过FTDI USB to TTL模块,可以将ESP直接和电脑连接。只需要将对应引脚与FTDI模块相连即可。

2:简单开始

下图为一个FTDI模块。将其引脚与ESP模块各引脚相连。

下载FTDI模块的芯片驱动,直接搜索对应芯片就能找到。安装驱动后,将连接好的FTDI模块插入电脑,在电脑设备管理器中,能找到端口一栏,多了这个模块的端口比如(COM6)

随意下载一个串口助手,选择FTDI模块的端口,设置波特率为115200,结束符为NL和CR。其他的默认。

在串口助手上发送:AT

串口助手的窗口会返回:OK,或者ERROR。

如果返回OK,那么就可以通过AT指令操作ESP芯片连接WIFI或者作为AP让别人连wifi了。

如果返回ERROR,那么就需要更新固件,以让ESP支持AT指令。

未必一定要直接将ESP与电脑连接,也可以和其他单片机连接,通过对其他单片机编程,向ESP发送AT指令。重要的是,理解ESP的工作方式。

3:更新固件

如果你不小心将ESP配置错了,又不知道怎么去将它出厂设置,或者你发送AT指令总是返回ERROR,那么你就需要学习如何更新芯片固件。

更新固件需要用到FTDI模块,将FTDI和ESP连接,FTDI连接电脑。

首先下载Flash下载工具。只有Windows系统能用。

然后下载最新版本的ESP8266 NONOS SDK。并解压。

接线,需要注意,GPIO0引脚必须接地

序号 引脚名称 I/O 描述 DC特性 备注
1 UTXD AT 串口发送输出 3.3V 开机时禁止下拉
2 GND
3 CH_PD(EN) 模块断电信号 3.3V 1)高电平工作; 2)低电平模块供电关掉;
4 GPIO2 预留,默认悬空 3.3V 开机上电时必须为高电平,禁止硬件下拉;内部默认已拉高
5 GPIO16 I 复位信号(RESET) 3.3V 低电平复位,高电平工作(默认高);
6 GPIO0 模块状态灯/工作模式选择 3.3V 1)默认WiFiStatus:WiFi工作状态指示灯控制信号;2)工作模式选择:上拉:FlashBoot,工作模式;下拉:UARTDownload,下载模式(下载固件);
7 VCC I 模块采用单电源供电,通过 1 个VCC 电源引脚供电,电压范围:3.0V-3.6V,电流>600mA Vmax=3.6VVmin=3.0VVnorm=3.3V 电源供电能力请大于600mA;否则可能会引起模块工作异常,或者无线性能不好。
8 URXD AT 串口发送输入 3.3V

打开flash_download_tool_v3.8.5.exe。选择Developer模式。

选择8266芯片

然后在之前解压的SDK中找到C:\Users……\ESP8266_NONOS_SDK-3.0.4\bin\boot_v1.6.bin文件刷入地址0x00000中

然后点击START按钮开始,如果显示等待上电,在保证GPIO0接地的情况下,将RST引脚接地再断开。

至此固件等待刷新完毕。

4:AT指令

完整的AT指令PDF

常见的指令:

基础命令

  • 测试:AT
  • 复位:AT+RST
  • 恢复出厂设置:AT+RESTORE
  • 查询本机IP和MAC:AT+CIFSR

模式命令

  • 查询模式:AT+CWMODE?
  • 设置模式 1:STA 2:AP 3:both:AT+CWMODE=1
  • (STA)查询当前可用AP :AT+CWLAP
  • (STA)加入可用AP :AT+CWJAP=“ssid”,“psw”
  • (STA)退出当前AP :AT+CWQAP
  • (AP)设置AP参数,ssid+psw+chn+ecn+n+01 :AT+CWSAP=“哈哈”,“12345678”,3,3,4,0
  • (AP)查询AP参数:AT+CWSAP?

客户端|服务器设置

  • 查询是否多连接 是1,否0 :AT+CIPMUX?
  • 设置启动多连接1,单链接0(重启后默认0):AT+CIPMUX=1
  • (多连接)关闭服务器,就是开启多连接客户端,默认是0 :AT+CIPSERVER=0
  • (多连接)开启服务器,:开启+端口号port。 此时客户端要连本机,远程地址为 IP+Port :AT+CIPSERVER=1,8080
  • (多连接)发送数据 id+Byte:AT+CIPSEND=0,10
  • (多连接)关闭TCP/UDP连接,id:AT+CIPCLOSE=0
  • (客户端单连接)建立TCP/UDP连接:AT+CIPSTART=“TCP”,“192.168.4.2”,100
  • (客户端单连接)发送数据,Byte :AT+CIPSEND=10
  • (客户端单连接)使能穿透模式:AT+CIPMODE=1
  • (客户端单连接)进入透传模式发送:AT+CIPSEND
  • (客户端单连接)退出透传:+++
  • (客户端单连接)关闭TCP/UDP连接:AT+CIPCLOSE
  • (客户端多连接)建立TCP/UDP连接,id,TCP/UDP,IP,端口:AT+CIPSTART=0,“TCP”,“192.168.4.2”,100

其他

如果需要用到ESP通过软串口连接Arduino单片机,就需要修改ESP的波特率,ESP默认波特率是115200,而软串口只能是9600,修改波特率AT指令

AT+CIOBAUD=9600

如果返回ERROR,可以尝试

AT+UART=9600,8,1,0,0

5:使用Arduino IDE编写程序

ESP8266是可以直接使用Arduino IDE上烧录程序的。为了在Arduino IDE上直接编写程序,首先需要导入ESP8266的库。

  1. 在IDE的文件->首选项里边的附加开发板管理网址输入https://github.com/esp8266/Arduino/releases/download/2.5.0/package_esp8266com_index.json

或者http://arduino.esp8266.com/stable/package_esp8266com_index.json

之后点击好。

  1. 在 工具->开发板选择最上方开发板管理器,之后搜索esp即可出现esp8266,选择版本之后进行安装即可。

  1. 在Arduino IDE 菜单>工具>开发板>开发板管理器 中选择你正在使用的8266开发板。

如果你不清楚自己使用的是哪个开发板,可以选择generic esp8266 module,这是通用板子。

  1. 选择正确的端口。如果不知道自己板子连接电脑上的是哪个端口,可以打开电脑的设备管理器,其中有端口一栏,有详细信息。
  2. 上载程序前,将GPIO0引脚下拉接地,并将RST引脚接地在放开,上载程序时,GPIO0引脚需保持接地状态。上载完毕,将GPIO0引脚放空,并再次将RST引脚接地放开,切换到运行状态。

6:Https请求程序

这里以企业微信api发送应用消息为例,简述https请求中的get和post请求。http请求更为简单。网上资料也更多。

要调取企业微信api首先需要仔细阅读其开发文档

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <ArduinoJson.h>

//WiFi连接信息(注意:需要自行修改以下内容否则ESP8266无法连接WiFi)
#define ssid "SSID" //WiFi名称
#define password "PASSWORD" //WiFi密码

//https://qyapi.weixin.qq.com网站的指纹。
//esp通过https访问网站,都需要自己通过浏览器获取指纹,获取方法可自行搜索,在参考资料中也有文章,指纹一般几个月就需要更新一次。浏览器打开https://qyapi.weixin.qq.com/cgi-bin/gettoken获取指纹,而不只是只有主机名。
const char fingerprint[] PROGMEM = "790e6e32485bb89503ac6da87d948f5e634322a7";

//HTTPS端口443
const int httpsPort = 443;
// 企业微信api相关
String tokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
String sendMsgUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";
//以下信息需要替换,这里的均不可用
String corpid = "ww98b3k1b63788a7ad";//你的企业id
String corpsecret = "Kh8asfasfaTrbSwRBGK5H0osnfasakjkmSYCqV3Tgcs";//你的企业应用密钥
String agentid = "1000002";//你的企业应用id

//获取企业微信access_token
String get_token(){
String token = "123";
String requestUrl = tokenUrl + "?corpid="+corpid+"&corpsecret="+corpsecret;
//https需要创建一个加密路径
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setFingerprint(fingerprint);
//创建一个HTTP客户端
HTTPClient https;
//http和https的区别就是https.begin中的*client。如果没有*client,那么发送出去的就是http请求
//建立连接
if (https.begin(*client, requestUrl)) { // HTTPS
Serial.print("[HTTPS] GET...\n");
// 发送get请求
int httpCode = https.GET();
//如果httpCode小于零则连接错误
if (httpCode > 0) {
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);

// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
//将返回的json序列,放到json变量
String json = https.getString();
Serial.println(json);
// 创建DynamicJsonDocument对象,json中的参数为4个。
const size_t capacity = JSON_OBJECT_SIZE(4) + 290;
DynamicJsonDocument doc(capacity);
//反序列化数据
deserializeJson(doc, json);
if(doc["errcode"].as<int>()==0){
token = doc["access_token"].as<String>();
}
}
} else {
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}

https.end();
} else {
Serial.printf("[HTTPS] Unable to connect\n");
}

return token;
}

//调用企业微信api,发送信息。
void send_msg(String msg){
//调用get_token函数,获取token
String token = get_token();
//token=123表示get_token()函数请求token失败。
//如果失败,可能还需要其他步骤,比如重新获取。这里没有完善。
if (token == "123"){
Serial.println("not get token");
return;
}else{
Serial.println("got token");
}
//构造请求url
String requestUrl = sendMsgUrl + token;
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setFingerprint(fingerprint);
HTTPClient httpClient;

//与微信服务器建立连接
httpClient.begin(*client,requestUrl);
//构建json数据,用于发送请求内容
String json = "{\"touser\":\"@all\",\"msgtype\":\"text\",\"agentid\":1000002,\"text\":{\"content\":\""+msg+"\"},\"safe\":0,\"enable_id_trans\":0,\"enable_duplicate_check\":0,\"duplicate_check_interval\":1800}";
//发送请求内容
Serial.println(json);
//将请求数据放到POST()中。
int httpCode = httpClient.POST(json);
//这里没有读取服务器返回的json数据,最好还是提取出来,判断是否发送成功。可自行添加代码
if (httpCode > 0) {
//将服务器响应头打印到串口
Serial.println("[HTTP] POST... code:"+ httpCode);
//将从服务器获取的数据打印到串口
if (httpCode == HTTP_CODE_OK) {
Serial.println("Send success");
Serial.println("return str:"+httpClient.getString());
}
} else {
Serial.println("send failure");
}
//关闭ESP8266与服务器连接
httpClient.end();
}

//Wifi init
void wifi_init(){
Serial.begin(9600);
WiFi.mode(WIFI_STA); //设置ESP8266为无线终端工作模式

WiFi.begin(ssid, password); //连接WiFi
Serial.println("");

Serial.println("Connecting"); Serial.println("");

// 等待连接
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

//成功连接后通过串口监视器显示WiFi名称以及ESP8266的IP地址。
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}

void setup() {
wifi_init();
send_msg("hello world!");
}

void loop() {
}

ArduinoJSON库需要在IDE库管理中搜索安装,

其他库都是随ESP8266库一起安装的。

json格式化和转义:http://www.bejson.com/

ArduinoJson Assistant:https://arduinojson.org/v6/assistant/

关于ArduinoJSON详细教程可见参考资料章节

7:低功耗方案

ESP8266提供三种省电模式。

当我们的程序在某个时间段不需要使用wifi模块时,可让它进入睡眠模式,

Modem-Sleep模式:wifi与路由器保持连接,只在间断的时间里发送一个消息以保持连接。

Light-Sleep模式:在Modem-Sleep的基础上,关闭CPU。在esp循环任务长时间不需要esp工作时,会自动进入此模式。

Deep-Sleep模式:断开wifi。可用户配置。

deepsleep模式提供定时器唤醒和外部IO唤醒两种方案。

  1. 定时器唤醒

将RST引脚接GPIO16。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* ESP8266 Deep sleep mode example
* Rui Santos
* Complete Project Details https://randomnerdtutorials.com
*/

void setup() {
Serial.begin(115200);
Serial.setTimeout(2000);

// Wait for serial to initialize.
while(!Serial) { }

// Deep sleep mode for 30 seconds, the ESP8266 wakes up by itself when GPIO 16 (D0 in NodeMCU board) is connected to the RESET pin
Serial.println("I'm awake, but I'm going into deep sleep mode for 30 seconds");
ESP.deepSleep(30e6);

}

void loop() {
}

ESP-01芯片,GPIO16引脚并没有引出,所以,很难将RST引脚与其相接。

  1. 外部唤醒。

将RST与外部单片机的IO口相接,当外部IO给RST一个低电平时,芯片将重启激活。

例如使用按钮来提供低电平

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* ESP8266 Deep sleep mode example
* Rui Santos
* Complete Project Details https://randomnerdtutorials.com
*/

void setup() {
Serial.begin(115200);
Serial.setTimeout(2000);

// Wait for serial to initialize.
while(!Serial) { }

// Deep sleep mode until RESET pin is connected to a LOW signal (for example pushbutton or magnetic reed switch)
Serial.println("I'm awake, but I'm going into deep sleep mode until RESET pin is connected to a LOW signal");
ESP.deepSleep(0);
}

void loop() {
}
  1. 有的ESP模块上面带有LED灯,采用低功耗方案,务必将LED移除。

8:与其他单片机通讯

ESP通过串口可与其他单片机传递信息,将ESP的TX引脚连接其他单片机RX引脚,ESP的RX连接其他单片机的TX。

注意,ESP8266是3.3V供电,VCC需要接3.3V。如果其他单片机是5V供电,ESP的RX引脚需要分压之后连接其他单片机的TX,否则进入ESP的5V电压会烧坏芯片。ESP的TX则不用分压。

下图为ESP连接Arduino Nano的接线图,途中,ESP RX引脚,通过1K和2K的电阻分压,其实也可以直接在ESP TX引脚和单片机RX引脚之间连接一个550左右的电阻。

9:参考资料

乐鑫ESP8266烧录固件、升级最新固件、刷MQTT固件

ESP8266 WIFI模块常用AT指令汇总

Arduino安装ESP8266的开发环境

ESP8266 JSON解析

物联网开发实用知识 – 查看网站证书指纹

ESP8266 Deep Sleep with Arduino IDE (NodeMCU)

评论