【ESP32最全学习笔记(协议篇)——1.ESP32 网络服务器】

关于本教程:

ESP32 基础篇                                

1.ESP32简介                                                                

2.ESP32 Arduino 集成开发环境

3.VS 代码和 PlatformIO

4.ESP32 引脚

5.ESP32 输入输出

6.ESP32 脉宽调制

7.ESP32 模拟输入

8.ESP32 中断定时器

9.ESP32 深度睡眠

ESP32 协议篇

1.ESP32 网络服务器

扫描二维码关注公众号,回复: 15023291 查看本文章

2.ESP32 LoRa

3.ESP32 BLE

4.ESP32 BLE 客户端-服务器

5.ESP32 蓝牙

6.ESP32 MQTT

7.ESP32 ESP-NOW

8.ESP32 Wi-Fi

9.ESP32 WebSocket

10.ESP32 ESP-MESH

11.ESP32 邮箱

12.ESP32 短信

13.ESP32 HTTP 获取 POST

14.HTTP GET Web APIs

15.HTTP POST Web APIs

 ESP32 服务器篇

持续更新,关注博主不迷路!!!

 ESP32 传感器模块篇

持续更新,关注博主不迷路!!!

ESP32 终极实战篇

百余项ESP32实战项目,敬请关注!!!

        学习了ESP32基础篇之后,我们紧接着进入协议篇学习,这一部分我们将结合实例进一步学习ESP32。废话不多说,让我们开始吧!!!

ESP32 网络服务器——Arduino IDE

        在此项目中,您将使用 Arduino IDE 编程环境创建一个带有 ESP32 的独立 Web 服务器,该服务器控制输出(两个 LED)。Web 服务器是移动响应的,可以使用任何设备作为本地网络上的浏览器进行访问。我们将逐步向您展示如何创建 Web 服务器以及代码如何工作。

项目概况

在直接进入项目之前,重要的是概述我们的 Web 服务器将做什么,以便以后更容易遵循这些步骤。

  • 您将构建的 Web 服务器控制连接到 ESP32 的两个 LEDGPIO 26GPIO 27;
  • 您可以在本地网络中的浏览器中输入 ESP32 IP 地址来访问 ESP32 Web 服务器;
  • 通过单击 Web 服务器上的按钮,您可以立即更改每个 LED 的状态。

所需零件

对于本教程,您需要以下部分:

ESP32 开发板
2 个 5 毫米 LED
2x 330 欧姆电阻
面包板
跳线

原理图

从构建电路开始。如下图所示将两个 LED 连接到 ESP32 – 一个 LED 连接到GPIO 26, 另一个到GPIO 27。

注意:我们使用的是带 36 个引脚的 ESP32 DEVKIT DOIT 板。在组装电路之前,请务必检查所用电路板的引出线。

ESP32 Web 服务器代码

我们在这里提供创建 ESP32 网络服务器的代码。将以下代码复制到您的 Arduino IDE,但先不要上传。您需要进行一些更改才能使其适合您。

#include <WiFi.h>

// Replace with your network credentials
const char* ssid1 = "";
const char* password1 = "";

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

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String output26State = "off";
String output27State = "off";

// Assign output variables to GPIO pins
const int output26 = 26;
const int output27 = 27;

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0; 
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output26, OUTPUT);
  pinMode(output27, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output26, LOW);
  digitalWrite(output27, LOW);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid1, password1);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    currentTime = millis();
    previousTime = currentTime;
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected() && currentTime - previousTime <= timeoutTime) {  // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            
            // turns the GPIOs on and off
            if (header.indexOf("GET /26/on") >= 0) {
              Serial.println("GPIO 26 on");
              output26State = "on";
              digitalWrite(output26, HIGH);
            } else if (header.indexOf("GET /26/off") >= 0) {
              Serial.println("GPIO 26 off");
              output26State = "off";
              digitalWrite(output26, LOW);
            } else if (header.indexOf("GET /27/on") >= 0) {
              Serial.println("GPIO 27 on");
              output27State = "on";
              digitalWrite(output27, HIGH);
            } else if (header.indexOf("GET /27/off") >= 0) {
              Serial.println("GPIO 27 off");
              output27State = "off";
              digitalWrite(output27, LOW);
            }
            
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #555555;}</style></head>");
            
            // Web Page Heading
            client.println("<body><h1>ESP32 Web Server</h1>");
            
            // Display current state, and ON/OFF buttons for GPIO 26  
            client.println("<p>GPIO 26 - State " + output26State + "</p>");
            // If the output26State is off, it displays the ON button       
            if (output26State=="off") {
              client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
            } 
               
            // Display current state, and ON/OFF buttons for GPIO 27  
            client.println("<p>GPIO 27 - State " + output27State + "</p>");
            // If the output27State is off, it displays the ON button       
            if (output27State=="off") {
              client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
            client.println("</body></html>");
            
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

设置您的WiFi网络

您需要使用您的网络修改以下行:SSID 和密码。该代码对您应该在何处进行更改进行了很好的注释。

// Replace with your network credentials
const char* ssid1     = "";
const char* password1 = "";

上传代码

现在,您可以上传代码,Web 服务器将立即运行。按照以下步骤将代码上传到 ESP32:

1)将 ESP32 开发板插入电脑;

2) 在 Arduino IDE 的工具>开发板中选择您的开发板 (在我们的例子中,我们使用的是 ESP32 DEVKIT DOIT 开发板);

3) 在工具端口中选择 COM 端口 。

4) 按Arduino IDE 中的上传按钮,等待几秒钟,同时代码编译并上传到您的电路板。

5) 等待“上传完成”消息。

查找 ESP IP 地址

上传代码后,以115200的波特率打开Serial Monitor。

按下 ESP32 EN 按钮(重置)。ESP32 连接 Wi-Fi,并在串口监视器上输出 ESP IP 地址。复制该 IP 地址,因为您需要它来访问 ESP32 网络服务器。

访问网络服务器

要访问 Web 服务器,请打开浏览器,粘贴 ESP32 IP 地址,您将看到以下页面。在我们的例子中是192.168.1.135

如果你看一下串行监视器,你可以看到后台发生了什么。ESP 收到来自新客户端(在本例中为您的浏览器)的 HTTP 请求。

测试网络服务器

现在您可以测试您的网络服务器是否正常工作。单击按钮以控制 LED。

同时,你可以看一下Serial Monitor,看看后台发生了什么。例如,当您单击按钮以打开GPIO 26ON,ESP32 在/26/on URL上收到请求。

当 ESP32 收到该请求时,它会打开连接到GPIO 26ON 并在网页上更新其状态。

该按钮用于GPIO 27以类似的方式工作。测试它是否正常工作。

代码如何运作

在本节中,将仔细查看代码以了解其工作原理。

您需要做的第一件事是包含 WiFi 库。

#include <WiFi.h>

如前所述,您需要在双引号内的以下行中插入您的 ssid 和密码。

const char* ssid1 = "";
const char* password1 = "";

然后,将 Web 服务器设置为端口 80。

WiFiServer server(80);

以下行创建一个变量来存储 HTTP 请求的标头:

String header;

接下来,您创建辅助变量来存储输出的当前状态。如果要添加更多输出并保存其状态,则需要创建更多变量。

String output26State = "off";
String output27State = "off";

您还需要为每个输出分配一个 GPIO。这里我们使用GPIO 26GPIO 27. 您可以使用任何其他合适的 GPIO。

const int output26 = 26;
const int output27 = 27;

setup()

现在,让我们进入setup(). 首先,我们以 115200 的波特率启动串行通信以进行调试。

Serial.begin(115200);

您还可以将 GPIO 定义为输出并将它们设置为低电平。

// Initialize the output variables as outputs
pinMode(output26, OUTPUT);
pinMode(output27, OUTPUT);

// Set outputs to LOW
digitalWrite(output26, LOW);
digitalWrite(output27, LOW);

以下几行开始 Wi-Fi 连接WiFi.begin(ssid, password), 等待连接成功并在串行监视器中打印 ESP IP 地址。

// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();

loop()

在里面loop()我们对新客户端与 Web 服务器建立连接时发生的情况进行编程。

ESP32 始终通过以下行侦听传入的客户端:

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

 当收到来自客户端的请求时,我们将保存传入的数据。只要客户端保持连接,后面的 while 循环就会运行。我们不建议更改代码的以下部分,除非您确切地知道自己在做什么。

if (client) { // If a new client connects,
  Serial.println("New Client."); // print a message out in the serial port
  String currentLine = ""; // make a String to hold incoming data from the client
  while (client.connected()) { // loop while the client's connected
    if (client.available()) { // if there's bytes to read from the client,
      char c = client.read(); // read a byte, then
      Serial.write(c); // print it out the serial monitor
      header += c;
      if (c == '\n') { // if the byte is a newline character
      // if the current line is blank, you got two newline characters in a row.
      / that's the end of the client HTTP request, so send a response:
        if (currentLine.length() == 0) {
        // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
        // and a content-type so the client knows what's coming, then a blank line:
          client.println("HTTP/1.1 200 OK");
          client.println("Content-type:text/html");
          client.println("Connection: close");
          client.println();

 if 和 else 语句的下一部分检查在您的网页中按下了哪个按钮,并相应地控制输出。正如我们之前所见,我们根据按下的按钮向不同的 URL 发出请求。

// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
  Serial.println("GPIO 26 on");
  output26State = "on";
  digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
  Serial.println("GPIO 26 off");
  output26State = "off";
  digitalWrite(output26, LOW);
} else if (header.indexOf("GET /27/on") >= 0) {
  Serial.println("GPIO 27 on");
  output27State = "on";
  digitalWrite(output27, HIGH);
} else if (header.indexOf("GET /27/off") >= 0) {
  Serial.println("GPIO 27 off");
  output27State = "off";
  digitalWrite(output27, LOW);
}

例如,如果您按下 GPIO 26 ON 按钮,ESP32 会收到一个关于/26/ON URL 的请求(我们可以在串行监视器的 HTTP 标头上看到该信息)。因此,我们可以检查标头是否包含表达式GET /26/on。如果它包含,我们改变output26State变量为 ON,ESP32 打开 LED。

这对其他按钮的作用类似。所以,如果你想添加更多输出,你应该修改这部分代码以包含它们。

显示 HTML 网页

您需要做的下一件事是创建网页。ESP32 将使用一些 HTML 代码向您的浏览器发送响应以构建网页。

使用此表达式将网页发送到客户端client.println(). 您应该输入要作为参数发送给客户端的内容。

我们应该发送的第一件事始终是以下行,这表明我们正在发送 HTML。

<!DOCTYPE HTML><html>

下面是用来防止对图标的请求。– 你不需要担心这条线。

client.println("<link rel=\"icon\" href=\"data:,\">");

网页样式

接下来,我们有一些 CSS 文本来设置按钮和网页外观的样式。我们选择 Helvetica 字体,将要显示的内容定义为块并居中对齐。

client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");

我们使用 #4CAF50 颜色为按钮设置样式,无边框,白色文本,并使用此填充:16px 40px。我们还将 text-decoration 设置为 none,将字体大小、边距和光标定义为指针。

client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");

 我们还定义了第二个按钮的样式,具有我们之前定义的按钮的所有属性,但颜色不同。这将是关闭按钮的样式。

client.println(".button2 {background-color: #555555;}</style></head>");

设置网页第一标题

在下一行中,您可以设置网页的第一个标题。这里我们有“ ESP32 Web Server ”,但你可以将这个文本更改为你喜欢的任何内容。

// Web Page Heading
client.println("<h1>ESP32 Web Server</h1>");

显示按钮和相应的状态

然后,你写一个段落来显示GPIO 26当前状态。如您所见,我们使用output26State变量,以便在该变量更改时立即更新状态。

client.println("<p>GPIO 26 - State " + output26State + "</p>");

 然后,我们根据 GPIO 的当前状态显示开或关按钮。如果 GPIO 的当前状态为关闭,我们显示 ON 按钮,如果不是,我们显示 OFF 按钮。

if (output26State=="off") {
  client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
} else {
  client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
}

我们使用相同的程序GPIO 27.

关闭连接

最后,当响应结束时,我们清除header变量,并停止与客户端的连接client.stop().

// Clear the header variable
header = "";
// Close the connection
client.stop();

总结

        在本教程中,我们向您展示了如何使用 ESP32 构建网络服务器。我们已经向您展示了一个控制两个 LED 的简单示例,但我们的想法是用继电器或您想要控制的任何其他输出替换这些 LED。

猜你喜欢

转载自blog.csdn.net/m0_46509684/article/details/129336485
今日推荐