09_ESP32 网页服务器

09_ESP32 网页服务器

ESP32 内置了 Wi-Fi 功能,能够作为网页服务器(Web Server)向网络中的其他设备提供服务。通过在 ESP32 上运行网页服务器,可以创建基于浏览器的用户界面,用于监控传感器数据或控制设备状态,是实现物联网(IoT)应用的基础功能之一。

WebServer 库简介

Arduino-ESP32 核心库内置了 WebServer.h,它提供了一套简洁的 API 来快速构建 Web Server。通过注册路由(URL 路径)及回调函数,实现请求分发与应答。适用于绝大多数典型 IOT 项目的本地网页交互。本教程将使用此库。

  • 简洁易用,适合入门和资源受限场景。
  • 需在主循环 (loop() ) 中定期调用 server.handleClient() 以处理客户端请求。
  • 对大流量/高并发等复杂场景建议选用异步库(如 ESPAsyncWebServer)。

示例 1:基础网页服务 (STA 模式)

在 STA 模式下创建一个基础的网页服务器,用于显示一个包含"Hello World!"的静态页面。

// 引入 WiFi 库,让 ESP32 连接 WiFi
#include <WiFi.h>
// 引入 Web 服务器库,让 ESP32 变成网站服务器
#include <WebServer.h>

// ==================== WiFi 配置(改成你自己的) ====================
const char *ssid = "123";              // WiFi 名称
const char *password = "feilimao123";  // WiFi 密码

// 创建一个服务器对象,使用 80 端口(网页默认端口)
WebServer server(80);

// ==================== 初始化函数,只运行一次 ====================
void setup() {
  // 初始化串口,用于查看日志
  Serial.begin(115200);
  delay(10);

  // 串口打印:正在连接哪个 WiFi
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // 开始连接 WiFi
  WiFi.begin(ssid, password);

  // 等待 WiFi 连接成功,没连上就一直打印点
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // WiFi 连接成功!
  Serial.println();
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());  // 打印 ESP32 的 IP 地址

  // ==================== 配置网页服务器 ====================
  // 当访问网站根目录 / 时,调用 handleRoot 函数
  server.on("/", handleRoot);
  
  // 启动服务器
  server.begin();
  Serial.println("Web server started");
}

// ==================== 循环函数,不断处理网页请求 ====================
void loop() {
  // 处理来自浏览器的访问请求(必须写)
  server.handleClient();
}

// ==================== 处理网页根目录访问 ====================
void handleRoot() {
  // 给浏览器返回网页:状态码200=成功,格式是HTML,内容是 generateHTML()
  server.send(200, "text/html", generateHTML());
}

// ==================== 生成要显示的网页内容 ====================
String generateHTML() {
  // 拼接一个 HTML 网页
  String htmlContent = "<!DOCTYPE html> <html>\n";
  htmlContent += "<head><meta charset=\"utf-8\" name=\"viewport\" content=\"width=device-width\">\n";
  htmlContent += "<title>ESP32S3 Test</title>\n";   // 网页标题
  htmlContent += "</head><body>\n";
  htmlContent += "<h1>Hello World!</h1>\n";         // 大标题
  htmlContent += "<p>Hello from ESP32</p>\n";       // 普通文字
  htmlContent += "</body>\n";
  htmlContent += "</html>\n";
  return htmlContent;                               // 返回拼接好的网页
}
  • #include <WebServer.h>:引入 Web Server 库,用以在 ESP32 上创建 HTTP 服务器。
  • WebServer server(80);:创建一个服务器对象,监听标准的 HTTP 端口 80。80 是 HTTP 协议的默认端口。
  • server.on("/", handleRoot);:注册路由处理函数。当客户端访问根路径"/"时,调用 handleRoot() 函数。
  • server.begin();:启动服务器,开始监听客户端的连接请求。
  • server.handleClient();:在 loop() 中持续调用,处理传入的客户端请求。
  • handleRoot():这是一个自定义的回调函数,用于处理特定路径的请求。
  • server.send(statusCode, contentType, content);:向客户端发送一个 HTTP 响应。向客户端浏览器返回包含 "Hello World" 的简单 HTML 页面。
    • 200:HTTP 状态码,200 OK 表示请求成功。
    • "text/html":MIME 类型,告知浏览器响应内容是 HTML 文本。
    • generateHTML():函数返回的字符串,即网页的实际内容。
  • generateHTML():一个辅助函数,将 HTML 代码拼接成一个 String 对象,返回包含完整 HTML 结构的字符串。

将代码中的 ssidpassword 修改为目标 Wi-Fi 网络的名称和密码后上传。串口监视器将显示连接过程和获取到的 IP 地址。在同一局域网的设备上打开浏览器,输入显示的 IP 地址,即可看到"Hello World!"页面。

示例 2:通过网页控制 LED (STA 模式)

在 STA 模式下,开启网页服务器。同局域网下的设备,通过网页控制 ESP32 连接的 LED 状态。

// 引入WiFi库,用于连接WiFi
#include <WiFi.h>
// 引入网页服务器库,用于搭建网页
#include <WebServer.h>

// ==================== 硬件定义 ====================
// 定义LED控制引脚,这里使用GPIO7
const int ledPin = 7;

// ==================== WiFi配置 ====================
const char *ssid = "123";               // WiFi名称
const char *password = "feilimao123";   // WiFi密码

// 创建网页服务器对象,使用80端口(网页默认端口)
WebServer server(80);

// ==================== 初始化函数,只运行一次 ====================
void setup() {
  // 设置LED引脚为输出模式
  pinMode(ledPin, OUTPUT);
  // 初始化串口,用于打印调试信息
  Serial.begin(115200);

  // 串口打印正在连接的WiFi名称
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // 开始连接WiFi
  WiFi.begin(ssid, password);

  // 等待WiFi连接成功,未连接时一直打印点
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // WiFi连接成功提示
  Serial.println();
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());  // 打印ESP32的IP地址

  // ==================== 配置网页访问路径(路由) ====================
  server.on("/", handleRoot);          // 访问根目录时,调用handleRoot函数
  server.on("/ledon", handleLedOn);    // 访问/ledon时,开灯
  server.on("/ledoff", handleLedOff);  // 访问/ledoff时,关灯

  // 启动网页服务器
  server.begin();
}

// ==================== 循环函数,持续处理网页请求 ====================
void loop() {
  server.handleClient();  // 处理浏览器的访问请求(必须写)
}

// ==================== 处理根目录访问 ====================
void handleRoot() {
  // 读取当前LED状态,并生成对应网页返回给浏览器
  server.send(200, "text/html", generateHTML(digitalRead(ledPin)));
}

// ==================== 处理LED开灯请求 ====================
void handleLedOn() {
  digitalWrite(ledPin, HIGH);  // 输出高电平,点亮LED
  // 发送状态为ON的网页
  server.send(200, "text/html", generateHTML(true));
}

// ==================== 处理LED关灯请求 ====================
void handleLedOff() {
  digitalWrite(ledPin, LOW);   // 输出低电平,熄灭LED
  // 发送状态为OFF的网页
  server.send(200, "text/html", generateHTML(false));
}

// ==================== 生成动态网页内容 ====================
// 根据LED状态,生成不同的网页
String generateHTML(bool ledState) {
  String htmlContent = "<!DOCTYPE html> <html>\n";
  htmlContent += "<head><meta charset=\"utf-8\" name=\"viewport\" content=\"width=device-width\">\n";
  htmlContent += "<title>ESP32S3 Test</title>\n";     // 网页标题
  htmlContent += "</head><body>\n";

  htmlContent += "<h1>Hello World!</h1>\n";           // 网页大标题

  // 根据LED状态显示不同内容
  if (ledState) {
    htmlContent += "<p>LED Status: ON</p>";                       // 显示LED状态:ON
    htmlContent += "<a href=\"/ledoff\">Turn off the LED</a>\n";  // 显示关灯按钮
  } else {
    htmlContent += "<p>LED Status: OFF</p>";                      // 显示LED状态:OFF
    htmlContent += "<a href=\"/ledon\">Turn on the LED</a>\n";    // 显示开灯按钮
  }

  htmlContent += "</body>\n";
  htmlContent += "</html>\n";
  return htmlContent;  // 返回生成好的网页
}

  • 新增路由

    • server.on("/ledon", handleLedOn);

      /ledon 路径的请求绑定到 handleLedOn 函数。当浏览器访问 http://<IP 地址>/ledon 时,服务器将调用 handleLedOn 函数。

    • server.on("/ledoff", handleLedOff);

      同理,将 /ledoff 路径绑定到 handleLedOff 函数。当浏览器访问 http://<IP 地址>/ledoff 时,服务器将调用 handleLedOff 函数。

  • LED 控制

    • 使用 HTML 的 <a> 标签创建链接按钮,点击时会向相应的路径发送 GET 请求,实现 LED 的控制。

      当用户点击 "Turn on the LED" 链接时,浏览器会向服务器的 /ledon 路径发起一个 HTTP GET 请求。

      服务器收到后,server.handleClient() 会匹配到 server.on("/ledon", handleLedOn); ,进而执行 handleLedOn 函数。

    • handleLedOnhandleLedOff 函数中,首先通过 digitalWrite() 控制 LED 状态。执行硬件操作后,它们会再次调用 generateHTML() 生成新的页面并发送给客户端,以更新页面状态。

  • 动态 HTML

    • generateHTML(bool ledState) 函数现在接受一个布尔参数,代表 LED 的当前状态。
    • 函数内部使用 if-else 语句,根据 ledState 的值,动态地生成不同的 HTML 内容。
      • 如果灯是亮的,就显示 "Turn off the LED" 按钮用于关闭 LED;
      • 如果灯是灭的,就显示 "Turn on the LED" 按钮用于打开 LED。

上传代码后,打开串口监视器查看 IP 地址。然后在浏览器中访问该 IP 地址,页面会显示当前 LED 状态和控制按钮。点击 "Turn on the LED" 或 "Turn off the LED" 按钮可以控制 LED 的开关状态,页面会实时更新显示当前状态。

示例 3:通过网页控制 LED (AP 模式)

在 AP 模式下,开启网页服务器。其他设备连接 ESP32 创建的 Wi-Fi 热点后,可直接通过网页访问 ESP32 提供的服务器,实现对 LED 状态的控制。

// 引入WiFi库,用于创建WiFi热点
#include <WiFi.h>
// 引入网页服务器库,用于搭建网页控制界面
#include <WebServer.h>

// ==================== 硬件定义 ====================
// 定义LED控制引脚(GPIO7)
const int ledPin = 7;

// ==================== 热点配置 ====================
const char *ssid = "ESP32S3-TEST";  // ESP32发出的热点名称
const char *password = "12345678";  // 热点密码(必须≥8位)

// 创建网页服务器对象,使用80端口(网页默认端口)
WebServer server(80);

// 函数提前声明(防止编译报错)
String generateHTML(bool ledState = false);

// ==================== 初始化函数,只运行一次 ====================
void setup() {
  // 设置LED引脚为输出模式
  pinMode(ledPin, OUTPUT);
  // 初始化串口,用于打印调试信息
  Serial.begin(115200);

  // ==================== 创建WiFi热点 ====================
  Serial.println("Configuring access point...");
  // 如果热点创建失败
  if (!WiFi.softAP(ssid, password)) {
    Serial.println("Soft AP creation failed.");
    while (1);  // 程序卡死,停止运行
  }

  // 获取热点的IP地址
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);  // 打印热点IP(手机连接后访问这个IP)

  // ==================== 配置网页访问路径(路由) ====================
  server.on("/", handleRoot);          // 访问根目录(主页)
  server.on("/ledon", handleLedOn);    // 访问/ledon → 开灯
  server.on("/ledoff", handleLedOff);  // 访问/ledoff → 关灯

  // 启动网页服务器
  server.begin();
}

// ==================== 循环函数,持续处理网页请求 ====================
void loop() {
  server.handleClient();  // 处理浏览器的访问(必须写)
}

// ==================== 处理主页访问 ====================
void handleRoot() {
  // 读取当前LED状态,生成对应网页返回给浏览器
  server.send(200, "text/html", generateHTML(digitalRead(ledPin)));
}

// ==================== 处理开灯请求 ====================
void handleLedOn() {
  digitalWrite(ledPin, HIGH);  // 点亮LED
  // 发送状态为ON的网页
  server.send(200, "text/html", generateHTML(true));
}

// ==================== 处理关灯请求 ====================
void handleLedOff() {
  digitalWrite(ledPin, LOW);  // 熄灭LED
  // 发送状态为OFF的网页
  server.send(200, "text/html", generateHTML(false));
}

// ==================== 生成动态网页 ====================
// 根据LED状态,自动生成不同的网页
String generateHTML(bool ledState) {
  String htmlContent = "<!DOCTYPE html> <html>\n";
  htmlContent += "<head><meta charset=\"utf-8\" name=\"viewport\" content=\"width=device-width\">\n";
  htmlContent += "<title>ESP32S3 Test</title>\n";    // 网页标题
  htmlContent += "</head><body>\n";

  htmlContent += "<h1>Hello World!</h1>\n";          // 网页大标题

  // 根据LED状态显示不同内容
  if (ledState) {
    htmlContent += "<p>LED Status: ON</p>";                       // 显示LED已开启
    htmlContent += "<a href=\"/ledoff\">Turn off the LED</a>\n";  // 显示关灯按钮
  } else {
    htmlContent += "<p>LED Status: OFF</p>";                      // 显示LED已关闭
    htmlContent += "<a href=\"/ledon\">Turn on the LED</a>\n";    // 显示开灯按钮
  }

  htmlContent += "</body>\n";
  htmlContent += "</html>\n";
  return htmlContent;  // 返回生成好的网页
}

  • AP 模式配置:使用 WiFi.softAP(ssid, password) 创建 Wi-Fi 热点,而不是连接到现有网络。
  • WiFi.softAPIP():获取 ESP32 作为热点时的 IP 地址,通常默认为 192.168.4.1。
  • 独立网络:ESP32 创建自己的局域网,其他设备需要先连接到这个热点才能访问网页服务器。
  • 网页服务器逻辑:处理 HTTP 请求的逻辑与 STA 模式下的示例基本一致,主要区别在于网络连接的初始化方式。

上传代码后,ESP32 会创建一个名为"ESP32S3-TEST"的 Wi-Fi 热点。使用电脑或手机连接此热点(密码:12345678),然后在浏览器中访问 192.168.4.1,即可看到 LED 控制页面。点击按钮可以控制 LED 的开关状态。

posted @ 2026-05-20 17:41  Q&25  阅读(12)  评论(0)    收藏  举报