风筝
发表于: 2020-11-23 21:26:20 | 显示全部楼层

我们在学习一款WiFi开发板时,搭建Web服务器是其中一项最有趣的项目。在学习如何使用ESP32制作项目的过程中,我们将研究如何使用ESP32微控制器构建一个简单的Web服务器。

Official-DOIT-ESP32-Development-Board-WiFi-Bluetooth-Ultra-Low-Power-Consumption.jpg


实际上Web服务器(Web Server)上是一种存储、处理网页并将网页交付给Web客户端的设备,可以是便携式计算机上的浏览器或智能手机上的移动应用程序。客户端和服务器之间的通信使用超文本传输​​协议(HTTP)的特殊协议进行。客户端使用URL来请求特定页面,服务器使用该页面的内容或错误消息(如果该页面不可用)进行响应。


在本篇文章中,URL并没有用于响应特定页面,而是用于控制连接到ESP开发板的LED灯状态,所做的更改将在网页上更新。例如,如果在浏览器中输入了类似于“ http://192.168.1.1/ledon”之类的URL,则Web服务器将LED点亮为“ ON”,然后将网页上LED的状态更新为“ ON”。当需要OFF时,同样如此。通过本文,您将知道如何在ESP32上设置网络服务器,并通过客户端(网页)连接到该服务器以控制其GPIO引脚。


所需的组件

●     ESP32开发板

●     220欧电阻

●     LED灯

●     面包板

●     连接跳线


原理图

本文的原理图非常简单。如前所述,我们将切换LED来演示使用NodeMCU Web服务器可以实现的功能,尽管本文使用的是LED灯,您也可以决定使用一些更有用的组件(例如继电器),从而可以远程控制家中的设备。如下图所示连接组件。

ESP32-ledserver.jpg


绿色和红色LED的正极分别连接到ESP32的GPIO引脚26和27,而其负极通过220欧姆电阻接地,以限制流过LED的电流。完成原理图后,我们现在可以转到项目代码。


代码

由于其多功能性、强大的支持和受欢迎度,我们将使用Arduino IDE来为今天的项目开发草图代码。为此,您需要在Arduino IDE上安装ESP32开发板支持文件。

本文的草图非常简单。该算法包括将ESP32连接到访问点并生成IP地址,通过该IP地址,连接到ESP的设备可以访问Web服务器。与服务器连接的客户端(在连接的设备上运行的网页)提供一个网页,该网页有一个用于控制LED的按钮,并且在按钮背后添加了处理单击它们时发生的操作。

为了减少需要编写的代码量,我们将使用ESP32 WiFi库。该库包含的功能使得将ESP32设置为Web服务器变得容易。该库以及其他库与ESP32板文件打包在一起,并在Arduino IDE上安装ESP32板文件时自动安装。


以下对代码进行简要说明,我们首先包括项目所需的库,在本例中为WiFi.h库。

  1. #include <WiFi.h>
复制代码

接下来,添加ESP32将连接到的WiFi接入点的凭据。确保用户名和密码在双引号之间。我们还指定系统将通过其进行通信的端口,并创建一个变量来保存请求。

  1. // Replace with your network credentials
  2. const char* ssid     = "Enter_SSID_here";
  3. const char* password = "Enter_Password_here";

  4. // Set web server port number to 80
  5. WiFiServer server(80);

  6. // Variable to store the HTTP request
  7. String header;
复制代码

接下来,我们声明ESP32的红色和绿色LED所连接的引脚,并创建变量保存LED的状态。

  1. int greenled = 26;
  2. int redled = 27;

  3. String greenstate = "off";// state of green LED
  4. String redstate = "off";// state of red LED
复制代码

完成此操作后,我们转到void setup()函数,首先初始化串口监视器,然后使用pinModes将LED连接到的引脚设置为输出。然后,我们将引脚设置为“LOW”。

  1. void setup() {
  2.   Serial.begin(115200);
  3. // Set the pinmode of the pins to which the LEDs are connected and turn them low to prevent flunctuations
  4.   pinMode(greenled, OUTPUT);
  5.   pinMode(redled, OUTPUT);
  6.   digitalWrite(greenled, LOW);
  7.   digitalWrite(redled, LOW);
复制代码

接下来,我们使用凭据作为WiFi.begin()函数的参数连接到访问点,然后使用WiFi.status()函数检查连接是否成功。

  1. WiFi.begin(ssid, password);
  2. Serial.print("Connecting to ");
  3. Serial.println(ssid);
  4. while (WiFi.status() != WL_CONNECTED) {
  5.   delay(500);
  6.   Serial.print(".");
  7. }
复制代码

如果连接成功,则会在串口监视器上打印文本,并且还会显示Web服务器的IP地址。该IP地址是服务器的网址,这是我们需要在同一网络上的任何Web浏览器中输入以访问服务器的地址。

  1. Serial.println("");
  2. Serial.println("WiFi connected.");
  3. Serial.println("IP address: ");
  4. Serial.println(WiFi.localIP());// this will display the Ip address of the Pi which should be entered into your browser
复制代码

完成此操作后,我们使用server.begin()函数启动服务器,然后进入void loop()函数。

  1. server.begin();
复制代码

void loop()函数是完成大部分工作的地方。我们首先使用server.available()函数来侦听客户端的传入连接。当客户端可用且已连接时,我们读取客户端请求并发送header作为响应。

  1. WiFiClient client = server.available();   // Listen for incoming clients

  2.   if (client) {                             // If a new client connects,
  3.     String currentLine = "";                // make a String to hold incoming data from the client
  4.     while (client.connected()) {            // loop while the client's connected
  5.       if (client.available()) {             // if there's bytes to read from the client,
  6.         char c = client.read();             // read a byte, then
  7.         Serial.write(c);                    // print it out the serial monitor
  8.         header += c;
  9.         if (c == '\n') {                    // if the byte is a newline character
  10.           // if the current line is blank, you got two newline characters in a row.
  11.           // that's the end of the client HTTP request, so send a response:
  12.           if (currentLine.length() == 0) {
  13.             // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
  14.             // and a content-type so the client knows what's coming, then a blank line:
  15.             client.println("HTTP/1.1 200 OK");
  16.             client.println("Content-type:text/html");
  17.             client.println("Connection: close");
  18.             client.println();
复制代码

接下来,我们检查客户的请求是否指示按下按钮以改变LED的“ ON / OFF”引脚。如果请求指示“ ON”,则该引脚变为高电平,状态变量相应更新,反之亦然。

  1. // turns the GPIOs on and off
  2.            if (header.indexOf("GET /green/on") >= 0) {
  3.              Serial.println("green on");
  4.              greenstate = "on";
  5.              digitalWrite(greenled, HIGH);
  6.            } else if (header.indexOf("GET /green/off") >= 0) {
  7.              Serial.println("green off");
  8.              greenstate = "off";
  9.              digitalWrite(greenled, LOW);
  10.            } else if (header.indexOf("GET /red/on") >= 0) {
  11.              Serial.println("red on");
  12.              redstate = "on";
  13.              digitalWrite(redled, HIGH);
  14.            } else if (header.indexOf("GET /red/off") >= 0) {
  15.              Serial.println("red off");
  16.              redstate = "off";
  17.              digitalWrite(redled, LOW);
  18.            }
复制代码

接下来,我们创建一个网页,当用户与之交互时,NodeMCU将显示并更新该网页。主要函数是Client.println(),该函数用于将HTML脚本逐行发送到客户端(浏览器)。我们首先使用“ doctype”来表示接下来要打印的文本是HTML线。

  1. client.println("<!DOCTYPE html><html>");
复制代码

接下来,我们添加以下代码行以使网页响应,无论使用哪种浏览器。

  1. client.println("<head><meta name="viewport" content="width=device-width, initial-scale=1">");
复制代码

我们还向客户端添加了一些CSS,以使页面易于使用。您可以对其进行编辑以添加自己的颜色,字体样式等。

  1. client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
  2. client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
  3. client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
  4. client.println(".button2 {background-color: #77878A;}</style></head>");
复制代码

接下来,网页标题与按钮一起发送,这些按钮根据LED的当前状态设置为显示ON或OFF。如果当前状态为ON,则显示为OFF,反之亦然。

  1. client.println("<body><h1>ESP32 Web Server</h1>");

  2. // Display current state, and ON/OFF buttons for green LED
  3. client.println("<p>green - State " + greenstate + "</p>");
  4. // If the green LED is off, it displays the ON button      
  5. if (greenstate == "off") {
  6.   client.println("<p><a href="/green/on"><button class="button">ON</button></a></p>");
  7. } else {
  8.   client.println("<p><a href="/green/off"><button class="button button2">OFF</button></a></p>");
  9. }
  10.    
  11. // Display current state, and ON/OFF buttons for Red LED  
  12. client.println("<p>red - State " + redstate + "</p>");
  13. // If the red LED is off, it displays the ON button      
  14. if (redstate == "off") {
  15.   client.println("<p><a href="/red/on"><button class="button">ON</button></a></p>");
  16. } else {
  17.   client.println("<p><a href="/red/off"><button class="button button2">OFF</button></a></p>");
  18. }
  19. client.println("</body></html>");
复制代码

接下来,我们关闭连接,loop函数再次进行。

  1. // Clear the header variable
  2. header = "";
  3. // Close the connection
  4. client.stop();
  5. Serial.println("Client disconnected.");
  6. Serial.println("");
复制代码

效果演示

将ESP32开发板连接到您的计算机,确保将其选择为Arduino IDE上的开发板类型,然后将代码粘贴到IDE中,进行验证并上传。 上传完成后,打开串口监视器。 您应该看到显示的IP地址,如下图所示。

eeeeeeeeee-1.png


将设备(手机或计算机)连接到与ESP32相同的网络,然后在该设备上打开Web浏览器并在地址栏中输入来自串口监视器的IP地址。 它将打开我们在网络服务器上创建的网页,如下图所示。 单击按钮切换LED。

Screen-Shot.png


如前所述,可以连接继电器或任何其他类型的执行器来代替LED,使该项目用途更广泛。 如果您对本文有任何疑问,请随时在本帖下面进行回复。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 56 | 回复: 109



手机版|

GMT+8, 2024-12-22 01:46 , Processed in 0.043787 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表