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 的当前状态,并根据状态显示相应的打开或关闭按钮。

总结

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

相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax