ESP32教程(基于Arduino IDE)6 - Web Server②控制输出

前言

本节学习怎么用 ESP32 搭建一个简单的 Web 服务器,用它来控制输出。有了这个 Web 服务器,不管是手机、平板,还是电脑之类的,只要这个设备有浏览器,那在本地网络里,就能访问这个服务器,进而控制那些连在 ESP32 的 GPIO 引脚上的设备。

项目介绍

1. 功能描述

  • 我们要构建的 Web 服务器将控制两个连接到 ESP32 GPIO 26 和 27 的 LED。(可以更具自己开发板自行更改IO口)
  • 在本地网络中,通过在浏览器中输入 ESP32 的 IP 地址来访问 Web 服务器。
  • 点击 Web 服务器上的按钮,可以立即改变每个 LED 的状态。

二、构建 Web 服务器

※注意:下述代码中需要输入自己的WiFi及密码信息后再编译上传

const char* ssid = "";	//你的WiFi名
const char* password = "";	//你的WiFi密码

完整代码如下

#include <WiFi.h>

const char* ssid = "";	//你的WiFi名
const char* password = "";	//你的WiFi密码

WiFiServer server(80);	// 设置Web服务器端口号为80

String header;	// 用于存储HTTP请求的变量

// 用于存储当前输出状态的辅助变量
String output26State = "off";
String output27State = "off";

// 将输出变量分配给GPIO引脚
const int output26 = 26;
const int output27 = 27;

// 初始化函数,在设备启动时执行一次
void setup() {
    Serial.begin(115200); // 初始化串口通信,波特率为115200
    
    // 将output26和output27引脚初始化为输出模式
    pinMode(output26, OUTPUT);
    pinMode(output27, OUTPUT);

    // 将output26和output27引脚输出设置为低电平(关闭状态)
    digitalWrite(output26, LOW);
    digitalWrite(output27, LOW);

    // 连接到WiFi网络,串口打印正在连接的信息
    Serial.print("正在连接到 ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    // 等待直到WiFi连接成功
    while (WiFi.status()!= WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }
    Serial.println("");
    Serial.println("连接成功.");

    // 打印本地IP地址并启动Web服务器
    Serial.println("IP地址: ");
    Serial.println(WiFi.localIP());
    server.begin();
}

// 主循环函数
void loop() {
    // 检查是否有客户端连接到服务器
    WiFiClient client = server.available();
    if (client) {
        Serial.println("有新客户端");
        String currentLine = "";
        // 当客户端连接时,持续处理通信
        while (client.connected()) {
            if (client.available()) {
                char c = client.read();
                Serial.write(c);
                header += c;
                if (c == '
') {
                    // 如果当前行为空行,表示请求头结束
                    if (currentLine.length() == 0) {
                        // 向客户端发送HTTP响应头,状态码200表示成功
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content - type:text/html");
                        client.println("Connection: close");
                        client.println();

                        // 根据请求头信息控制GPIO引脚的开关
                        if (header.indexOf("GET /26/on") >= 0) {
                            Serial.println("GPIO 26 开启");
                            output26State = "on";
                            digitalWrite(output26, HIGH);
                        } else if (header.indexOf("GET /26/off") >= 0) {
                            Serial.println("GPIO 26 关闭");
                            output26State = "off";
                            digitalWrite(output26, LOW);
                        } else if (header.indexOf("GET /27/on") >= 0) {
                            Serial.println("GPIO 27 开启");
                            output27State = "on";
                            digitalWrite(output27, HIGH);
                        } else if (header.indexOf("GET /27/off") >= 0) {
                            Serial.println("GPIO 27 关闭");
                            output27State = "off";
                            digitalWrite(output27, LOW);
                        }

                        // 向客户端发送HTML网页内容
                        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:,">");
                        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>");

                        // 网页标题
                        client.println("<body><h1>ESP32 Web Server</h1>");

                        // 显示GPIO 26的当前状态和控制按钮
                        client.println("<p>GPIO 26 - State " + output26State + "</p>");
                        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="button2">OFF</button></a></p>");
                        }

                        // 显示GPIO 27的当前状态和控制按钮
                        client.println("<p>GPIO 27 - State " + output27State + "</p>");
                        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="button2">OFF</button></a></p>");
                        }

                        client.println("</body></html>");
                        client.println();
                        break;
                    } else {
                        currentLine = "";
                    }
                } else if (c!= '
') {
                    currentLine += c;
                }
            }
        }
        // 清空请求头变量
        header = "";
        client.stop();
        Serial.println("客户端断开连接");
        Serial.println("");
    }
}

查找IP地址

上传代码后,打开串口监视器,将波特率设置为115200,否则串口会出现乱码。ESP32 会连接到 Wi-Fi 并在串口打印 IP 地址。复制该 IP 地址,在网页浏览器地址栏中输入,用于访问 Web 服务器。

如果串口监视器没有显示任何内容,按下 ESP32 的 "EN" 键进行复位后会重新打印相关信息。

访问 Web 服务器

在浏览器中输入IP地址后可以看到以下画面。有2个控制GPIO的按钮,通过按钮可以开关连在GPIO26,27上的LED。

同时,你可以在串口监视器中看到相关信息,如 ESP 接收到来自新客户端(浏览器)的 HTTP 请求以及 HTTP 头字段等信息。

点击按钮来打开 GPIO 26。你可以在串口监视器中看到 ESP 接收到了对 / 26/on URL 的请求,并且相应的 LED 会亮起。

四、工作原理

1. 代码结构

  • 首先包含WiFi.h库,用于创建 Web 服务器。
  • 设置网络 SSID 和密码
  • 设置 Web 服务器端口为 80,并创建变量来存储 HTTP 请求头、输出状态等信息。
  • 在setup函数中,初始化串口通信,设置 GPIO 引脚为输出模式并初始化为低电平,连接 Wi-Fi 并获取 IP 地址,启动 Web服务器。
  • 在loop函数中,监听客户端连接,接收并处理客户端请求,根据请求内容控制 GPIO 输出,并发送 HTML 页面给客户端。

2. HTTP 请求处理

  • 当客户端连接时,接收并保存请求数据。当接收到完整的请求(通过判断换行符和请求头是否完整),检查请求中是否包含特定的 URL(如 / 26/on、/26/off、/27/on、/27/off 等),根据不同的 URL 来改变相应 GPIO 的输出状态,并更新输出状态变量。

3. HTML 页面显示

  • 构建并发送 HTML 页面给客户端。页面包括一些基本的 HTML 标签和 CSS 样式,用于设置页面的布局和按钮的外观。例如,设置页面标题为 "ESP32 Web Server",显示每个 GPIO 的当前状态,并根据状态显示相应的打开或关闭按钮。

总结

可以根据自己的需求修改代码,添加更多的输出设备或修改网页的样式。

相关推荐
烂蜻蜓38 分钟前
深入理解 Uniapp 中的 px 与 rpx
前端·css·vue.js·uni-app·html
木亦Sam1 小时前
响应式网页设计中媒体查询的进阶运用
前端·响应式设计
diemeng11191 小时前
2024系统编程语言风云变幻:Rust持续领跑,Zig与Ada异军突起
开发语言·前端·后端·rust
烂蜻蜓1 小时前
Uniapp 中布局魔法:display 属性
前端·javascript·css·vue.js·uni-app·html
java1234_小锋1 小时前
一周学会Flask3 Python Web开发-redirect重定向
前端·python·flask·flask3
琑952 小时前
nextjs项目搭建——头部导航
开发语言·前端·javascript
Distance失落心2 小时前
idea任意版本的安装
java·ide·java-ee·eclipse·intellij-idea
light多学一点2 小时前
视频的分片上传
前端
优人ovo2 小时前
3分钟idea接入deepseek
java·ide·intellij-idea
Gazer_S2 小时前
【Windows系统node_modules删除失败(EPERM)问题解析与应对方案】
前端·javascript·windows