ESP8266-Arduino网络编程实例-异步Web服务器

异步Web服务器

在本文中,将使用ESPAsyncWebServer库构建一个简单的异步Web服务器。Web服务器提供3路LED控制逻辑。

在这里插入图片描述

1、硬件准备

  • ESP8266 NodeMCU开发板一块
  • 3个LED
  • 3个470欧姆电阻
  • 连接线若干
  • 面包板一个
  • 数据线一条

硬件接线图如下:

在这里插入图片描述

2、软件准备

  • Arduino IDE或VSCode + PlatformIO

在前面的文章中,对如何搭建ESP8266开发环境做了详细的介绍,请参考:

ESP8266 NodeMCU的引脚介绍在前面的文章中做了详细的介绍,请参考:

3、代码实现

本次使用到的开源库下载地址如下:

第一步,导入依赖头文件

1
2
3
4
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

第二步,定义WiFi连接信息

1
2
3
const char\* ssid = "\*\*\*\*\*";
const char\* ssid_pwd= "\*\*\*\*\*";

第三步,定义Web服务器请求参数

1
2
3
const char\* PARAM_INPUT_1 = "output";
const char\* PARAM_INPUT_2 = "state";

第四步,创建Web服务器对象

1
2
AsyncWebServer server(80);

第五步,定义HTML页面

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
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 3.0rem;}
p {font-size: 3.0rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 6px}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 3px}
input:checked+.slider {background-color: #b30000}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>
</head>
<body>
<h2>ESP Web Server</h2>
%BUTTONPLACEHOLDER%
<script>function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
else { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
xhr.send();
}
</script>
</body>
</html>
)rawliteral";

第六步,定义HTML页面处理函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 根据LED引脚状态更新按键状态
String processor(const String& var){
//Serial.println(var);
if(var == "BUTTONPLACEHOLDER"){
String buttons = "";
buttons += "<h4>Output - GPIO 5</h4><label class=\"switch\"><input type=\"checkbox\" οnchange=\"toggleCheckbox(this)\" id=\"5\" " + outputState(5) + "><span class=\"slider\"></span></label>";
buttons += "<h4>Output - GPIO 4</h4><label class=\"switch\"><input type=\"checkbox\" οnchange=\"toggleCheckbox(this)\" id=\"4\" " + outputState(4) + "><span class=\"slider\"></span></label>";
buttons += "<h4>Output - GPIO 2</h4><label class=\"switch\"><input type=\"checkbox\" οnchange=\"toggleCheckbox(this)\" id=\"2\" " + outputState(2) + "><span class=\"slider\"></span></label>";
return buttons;
}
return String();
}

// 读取LED引脚状态
String outputState(int output){
if(digitalRead(output)){
return "checked";
}
else {
return "";
}
}

第七步,在setup函数中,初始化设备

1)初始化引脚

1
2
3
4
5
6
7
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
pinMode(2, OUTPUT);
digitalWrite(2, LOW);

2)连接WiFi

1
2
3
4
5
6
7
8
9
WiFi.begin(ssid, ssid_pwd);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}

// 打印本设备地址
Serial.println(WiFi.localIP());

3)定义Web服务器请求路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest \*request) {
String inputMessage1;
String inputMessage2;
// GET input1 value on <ESP\_IP>/update?output=<inputMessage1>&state=<inputMessage2>
if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) {
inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
digitalWrite(inputMessage1.toInt(), inputMessage2.toInt());
}
else {
inputMessage1 = "No message sent";
inputMessage2 = "No message sent";
}
Serial.print("GPIO: ");
Serial.print(inputMessage1);
Serial.print(" - Set to: ");
Serial.println(inputMessage2);
request->send(200, "text/plain", "OK");
});

4)启动Web服务器

1
2
server.begin();

第八步,loop函数不任何逻辑处理

1
2
3
4
void loop() {

}

整个Web服务器请求过程如下:

在这里插入图片描述

运行结果如下:

在这里插入图片描述

文章来源: https://iotsmart.blog.csdn.net/article/details/127331239