在本教程中,我将展示如何构建一个简单的ESP8266 Web服务器。ESP8266 NodeMCU单机Web Server支持本地网络中任何有浏览器的设备(手机、笔记本电脑、平板电脑)访问。为了演示ESP8266 web服务器的工作原理,我们将创建一个控制两个led的web页面。
什么是Web服务器?
Web服务器是硬件和软件的结合,它负责维护、获取和向Web客户端提供Web页面。网页上的资料可以是HTML文件、图像、视频、应用程序等形式的文本。
你的笔记本电脑和手机中的Web浏览器就是Web客户端。如果你观察了Web服务器和Web客户端的术语,那么是的,这种类型的通信被称为客户-服务器模型。
客户端和服务器之间的通信是使用一种特殊的协议,称为HTTP或超文本传输协议。在这种通信类型中,Web客户端使用HTTP向服务器发出信息请求。Web服务器总是在等待(监听)请求,它会用适当的网页响应客户机的请求。
如果未找到所请求的页面,则服务器将以HTTP 404 Error响应。
对ESP8266 Web服务器的要求
通过对Web服务器的简要介绍,我们现在将了解一个独立的ESP8266 Web服务器的要求是什么。ESP8266 Web服务器必须包含HTML文本格式的Web页面。
当客户端(比如手机中的web浏览器)通过HTTP发送对该网页的请求时,ESP8266中的web服务器必须响应该网页。此外,当客户端执行任何操作时,如单击按钮,服务器应该响应适当的操作(如打开/关闭LED)。
ESP8266的Wi-Fi运行模式
在继续为ESP8266创建Web服务器之前,我们将了解一下Wi-Fi在ESP8266中的不同运行模式。如果你还记得ESP8266如何连接WiFi在教程中,我已经讨论过这些模式。但是对于这个web服务器教程,我们将再次修改它们。
ESP8266 Wi-Fi模块主要有三种WiFi工作模式。它们是:
- 站模式(STA)
- 软接入点模式(AP)
- 站+软AP模式
在工作站模式下,ESP8266模块连接到现有的WiFi网络,这是通过无线路由器设置的,就像我们的手机和笔记本电脑一样。
ESP8266 Wi-Fi模块通过路由器的“SSID”和“Password”连接到路由器的Wi-Fi网络,路由器为ESP8266分配本地IP地址。
进入接入点模式,ESP8266模块创建自己的WiFi网络,就像一个无线路由器,这样其他工作站,如手机,笔记本电脑,甚至其他ESP8266模块(在STA模式)都可以连接到该网络。
由于ESP8266没有有线以太网连接到互联网,因此这种AP模式被称为软AP模式。在AP模式下配置ESP8266时,必须为网络设置SSID和密码,以便其他设备可以使用这些凭据连接到该网络。
“工作站+软AP”是“工作站模式”和“软AP模式”的组合。在这种情况下,ESP8266既是站也是接入点。
创建Web服务器使用哪种模式?
ESP8266 Wi-Fi Module可以配置为站模式,也可以配置为接入点模式,创建web服务器。不同的是,在station模式下,所有设备(手机、笔记本电脑、ESP8266等)都连接到无线路由器的WiFi网络中,所有设备(包括ESP8266的Web Server)的IP地址由路由器分配。
通过该IP地址,客户端可以访问Web页面。此外,客户端不会失去路由器的互联网连接。
但是如果我们在AP模式下为ESP8266创建Web服务器,那么客户端必须使用自己的SSID和密码连接到ESP8266提供的网络才能访问Web页面。由于是软AP模式,客户端不具有internet连接。
在“站点模式”和“软AP模式”下创建ESP8266 Web服务器,除了ESP8266本身的配置外,其他配置基本相同。
在本教程中,我将向您展示如何在配置为站模式(STA)的ESP8266上创建Web服务器。
NodeMCU ESP8266 Web服务器
除了在ESP8266上创建web服务器和在客户端上访问它,我们还将看到server如何通过控制连接到ESP8266 NodeMCU板GPIO管脚的两个led灯来响应客户端的不同请求。
为了演示这一点,我将两个5mm led通过各自的限流电阻连接到ESP8266的GPIO4和GPIO5 (220Ω)。在NodeMCU上,GPIO4的标记为D2, GPIO5的标记为D1。
代码
接下来是重要而有趣的内容,ESP8266上Web服务器的实际代码。它只是一个HTML代码与一些文本,几个按钮和一些样式。
下面的代码块显示了ESP8266 Web服务器的完整代码。我将在下一节中解释这些代码。
修改和上传代码
在上述代码的第6行和第7行中,您必须根据您的Wi-Fi网络设置进行修改。这是Wi-Fi网络的SSID和密码。
const char* ssid = "ESP8266-WiFi";/*添加你的路由器的SSID */ const char* password = "12345678";/*添加密码*/
在进行必要的修改后,根据电路图进行必要的连接,将NodeMCU连接到计算机上,选择正确的COM口并上传代码。
如果你是ESP8266和NodeMCU的新手,那么NodeMCU入门教程将帮助你配置Arduino IDE。
打开串行监视器,ESP8266 NodeMCU会打印一些重要的信息,如Wi-Fi连接的进度、IP地址和Web服务器的URL(即ESP8266的IP地址)。
所以,在我的例子中,ESP8266的IP地址是192.168.1.6。
通过客户端访问ESP8266 Web服务器
在笔记本电脑或手机上打开Web浏览器,输入IP地址。关键时刻到了。如果一切顺利,那么您应该能够看到ESP8266 web服务器托管的一个简单的web页面。
以下为笔记本电脑上的Chrome Web浏览器访问ESP8266的Web服务器的截图。
从图片中可以看到,网页显示了一个主标题文本,后面是连接到GPIO4的LED的状态。接下来是一个按钮,可以用来打开或关闭LED。GPIO5也是如此(状态后面跟着按钮)。
现在,如果我点击第一个按钮,连接到GPIO4的LED会打开,在网页上更新状态,按钮的文字和颜色也会改变。
如果您查看串行监视器,每次客户机试图连接(或发送请求)时,串行监视器上都会打印一些关键信息。我将在下一节中解释这些信息(这实际上是来自客户机的请求的一部分)。
接下来,我在手机上尝试了同样的事情。它的工作原理。
注意:所有的客户端,如手机、笔记本电脑等,必须与ESP8266模块连接到同一个网络。
ESP8266 NodeMCU Web服务器是如何工作的?
现在让我们通过分析代码来理解ESP8266 Web服务器是如何工作的。我将解释代码的所有重要部分,并将简单的内容(如打开LED)留给您去探索。
初始设置
首先,您只需要包含一个与ESP8266WiFi Library相关的头文件。
# include < ESP8266WiFi.h >
接下来,分配GPIO引脚来连接两个led。我使用GPIO4和GPIO5。
#define gpio4LEDPin 4 #define gpio5LEDPin 5
正如我前面提到的,在这里添加Wi-Fi网络的SSID和密码。
const char* ssid = "ENTER_YOUR_SSID";const char* password = "ENTER_YOUR_PASSWORD";
因为我们想要创建一个HTTP服务器,所以我们必须设置端口号为80的Web服务器(这是HTTP服务器的默认端口)。
WiFiServer espServer (80);
接下来,在setup()函数中,开始波特率为115200的串行通信,并将GPIO管脚配置为OUTPUT。还要将GPIO引脚初始化为LOW。
Serial.begin (115200);pinMode (gpio4LEDPin、输出);pinMode (gpio5LEDPin、输出);digitalWrite (gpio4LEDPin、低);digitalWrite (gpio5LEDPin、低);
WiFi.mode (WIFI_STA);WiFi。开始(ssid、密码);while(WiFi.status() != WL_CONNECTED){串行。打印("*");延迟(500);}
系列。println("正在启动ESP8266 Web服务器…");espServer.begin ();系列。println("ESP8266 Web服务器已启动");并同时(“\ n”);系列。打印(" ESP8266 Web服务器的URL是:");并同时(“http://”);以WiFi.localIP ());
这样就完成了Web服务器的初始设置。
等待客户端并响应
接下来,在loop()函数中,服务器检查是否有客户端需要它的服务。如果没有客户端,请重新检查。如果有来自客户端的请求,则继续处理请求响应。
WiFiClient客户端= espServer.available();如果客户机(!){返回;}
当客户端在浏览器中输入ESP8266的IP地址时,服务器返回一个简单的网页。这是第一个请求-响应,因此不会有任何GPIO操作。来自客户端的请求是HTTP GET Method的形式。
您可以在下图中看到来自服务器的第一个请求的串行监视器输出,即客户机在其浏览器中输入IP地址。请求是“GET / HTTP/1.1”。最后的“1.1”是HTTP的版本。
如果客户端能够正常打开网页,则说明web服务器工作正常,说明客户端与服务器之间的HTTP通信成功。现在,根据LED的状态,按钮执行两个动作。如果LED是OFF,我们点击按钮,客户端发送一个请求来打开LED,反之亦然。
为了区分这两个请求,我们为同一个按钮单击使用了两个url,该url根据LED的状态发送到服务器。因此,对于这两个led,我们总共有四个url。它们是:
- / GPIO4ON
- / GPIO4OFF
- / GPIO5ON
- / GPIO5OFF
使用这些url,客户端发送请求,请求的格式如下:
- GET / GPIO4ON HTTP / 1.1
- GET / GPIO4OFF HTTP / 1.1
- GET / GPIO5ON HTTP / 1.1
- GET / GPIO5OFF HTTP / 1.1
下一段代码解析来自客户端的请求并执行必要的操作,例如,使GPIO4或GPIO5变为LOW或HIGH。
if (request.indexOf("/GPIO4ON") != -1){串行;println(“GPIO4 LED is ON”);digitalWrite (gpio4LEDPin、高);gpio4Value =高;} if (request.indexOf("/GPIO4OFF") != -1){串行;println("GPIO4 LED is OFF");digitalWrite (gpio4LEDPin、低);gpio4Value =低;} if (request.indexOf("/GPIO5ON") != -1){串行;println("GPIO5 LED is ON");digitalWrite (gpio5LEDPin、高);gpio5Value =高;} if (request.indexOf("/GPIO5OFF") != -1){串行;println("GPIO5 LED is OFF"); digitalWrite(gpio5LEDPin, LOW); gpio5Value = LOW; }
实际的Web页面
代码中最后也是最有趣的部分是针对实际网页本身的。正如我之前提到的,网页被设计成带有一些信息和几个按钮(CSS样式)的HTML文本。
在前几行代码中,我们基本上配置了Server的类型以及该服务器承载的文档类型。
client.println(“HTTP / 1.1 200 OK”);客户端。println (" content - type: text / html ");client.println ();client.println(“< !DOCTYPE HTML >”);
接下来的两行需要使网页在任何浏览器(移动,笔记本电脑)上访问,也防止favicon的请求。
客户端。Println ("");客户端。println(“< link rel = \”图标\ " href = \”数据:\“>”);
现在是代码的按钮样式部分。接下来的几行是按钮和整个网页的CSS样式,如字体,字体大小,按钮的颜色等。这一部分不是必须的,但它使网页更吸引人。
client.println(“<时尚>”);客户端。println("html {font-family: Courier New;显示:inline-block;保证金:0 px汽车;text-align:中心;}”);client.println(”。按钮{边界:没有;颜色:白色;填充:10 px 20 px; text-align: center;"); client.println("text-decoration: none; font-size: 25px; margin: 2px; cursor: pointer;}"); client.println(".button1 {background-color: #13B3F0;}"); client.println(".button2 {background-color: #3342FF;}"); client.println("");
接下来是实际网页主体的代码。首先,它包含一个简单的头文件,上面写着“ESP8266 Web服务器”。接下来是一个文本,表明连接到GPIO4的LED的状态。接下来是GPIO4按钮,上面有一个交互式文本。
LED状态文本和按钮也重复用于GPIO5。
身体client.println(“< >”);客户端。println(“< h2 > ESP8266 Web服务器< / h2 > ");如果(gpio4Value == LOW){客户端。println("GPIO4 LED Status: OFF
");客户端。打印(“< p > < a href = \ " / GPIO4ON \ " > <按钮类= \”按钮button1 \ " >点击打开按钮< / > < / > < / p > ");} else{客户端。println("GPIO4 LED Status: ON
");客户端。print(""); } if(gpio5Value == LOW) { client.println("GPIO5 LED Status: OFF
"); client.print(""); } else { client.println("GPIO5 LED Status: ON
"); client.print(""); } client.println("
6的反应
很好,它工作!谢谢
谢谢你!
是否有可能将完整的代码作为一个软件?
致以最亲切的问候
我们正在对网站的设计进行一些修改。代码部分将尽快更新。
你好。当使用ESP作为AP时,是否可以提供完整的代码?我已经按照建议做了更改,但是串行监视器仍然停留在“连接到WSP8266 WiFI ************”
这是一篇好文章。我喜欢读它。
请分享ESP8266的程序(实验:控制led)
工作模式为(AP+STA)。
问候
Prof.K.R.Rao
不错的文章