这个例子是构建一个基于客户端-服务器模型的微型Web。其核心架构包含三个关键角色:
- (1)服务器 (Server):由FireBeetle 2 ESP32-C5开发板担任。它是一个功能强大的嵌入式设备,集成了Wi-Fi无线通信模块和处理器。它的使命是托管一个网站并等待外部设备的访问请求。
- (2)网络接入点 (Access Point):由您的手机创建的个人热点担任。它充当了一个私密的、小范围的无线局域网(WLAN)路由器,为ESP32和您的其他设备(如电脑、另一部手机)提供网络连接和IP地址分配(DHCP服务)。
- (3)客户端 (Client):由任何能够连接到此热点的设备(如笔记本电脑、平板、另一部手机)上的网页浏览器担任。其职责是向服务器发起请求并解析服务器返回的响应内容。
完整的工作流程如下:
- 上电初始化:ESP32开发板通电后,其固件程序开始运行。首先进行自我检查和外设初始化。
代码
void setup() {
Serial.begin(115200); // 初始化串口通信
Serial.println("Starting ESP32-C5 Web Server...");
- 网络连接:ESP32根据程序中预置的手机热点名称(SSID)和密码,以工作站(Station)模式发起连接请求。手机热点对其进行身份验证,验证通过后为其分配一个局域网的IP地址(如 192.168.43.xxx)。至此,ESP32正式接入了由手机热点创建的无线网络。
代码
WiFi.mode(WIFI_STA); // 设置为工作站模式
WiFi.begin(ssid, password); // 连接指定WiFi
// 等待连接完成
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWiFi Connected");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP()); // 打印获取到的IP地址
- Web服务器启动:网络连接成功后,ESP32立即启动一个HTTP服务器。这个服务器持续监听网络上的80端口(HTTP协议的默认端口),像一个时刻待命的服务员,等待客户端的“点餐”请求。
代码
server.on("/", handleRoot); // 注册根路径处理函数
server.onNotFound([]() {
server.send(404, "text/plain", "404: Page Not Found");
});
server.begin(); // 启动HTTP服务器
Serial.println("HTTP Server Started");
- 客户端访问:您用电脑或手机连接到同一个手机热点,然后在浏览器地址栏输入ESP32被分配到的IP地址。
- 请求与响应:
- 浏览器向该IP地址的80端口发送一个 HTTP GET 请求,请求路径通常是根目录(/)。
- ESP32的服务器程序接收到这个请求后,立刻调用预设的处理函数。
- 该处理函数准备一个HTTP响应。这个响应包含一个成功状态码(200 OK),声明内容类型是HTML文本,并将一整个预先编写好的、完整的HTML网页内容作为响应体打包。
- 服务器将这个响应包通过网络发回给您的浏览器。
代码
const char* htmlContent = R"rawliteral(
<!DOCTYPE html>
<html>
<!-- 完整的万圣节主题HTML内容 -->
</html>
)rawliteral";
内容渲染:浏览器接收到响应包后,解析其中的HTML和CSS代码,并将其渲染成您所看到的丰富多彩、带有动画效果的万圣节主题网页。页面上的漂浮幽灵和闪烁南瓜灯都是由浏览器根据收到的CSS动画指令本地渲染的,ESP32只负责发送一次静态代码,无需持续计算动画效果。
完整ESP32C5端的代码如下:
代码
#include <WiFi.h>
#include <WebServer.h>
// 手机热点配置(替换为您的热点SSID和密码)
const char* ssid = "LSTM32F1SCORE"; // 替换为手机热点的SSID
const char* password = "3276865536"; // 替换为手机热点的密码
// 创建Web服务器对象,监听80端口(HTTP协议)
WebServer server(80);
// HTML内容(万圣节主题,保持与原代码一致)
const char* htmlContent = R"rawliteral(
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="探索万圣节相关内容,体验南瓜灯、幽灵和神秘派对的恐怖氛围!">
<meta name="keywords" content="万圣节, 南瓜灯, 幽灵, 恐怖派对, 节日活动">
<meta name="author" content="万圣节爱好者">
<title>万圣节相关内容</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #000;
color: #ff5914;
font-family: Arial, sans-serif;
overflow-x: hidden;
}
.halloween-theme {
background-color: #1a1a1a;
border-radius: 10px;
padding: 15px;
margin: 10px;
}
.halloween-theme:hover {
transform: scale(1.05);
transition: transform 0.3s ease;
}
header {
background: linear-gradient(45deg, #ff5914, #4b0082);
padding: 15px;
text-align: center;
}
header h1 {
font-size: 1.8rem;
color: #fff;
margin: 0;
}
nav {
background-color: #333;
padding: 10px;
text-align: center;
}
nav a {
color: #fff;
text-decoration: none;
padding: 8px 15px;
display: inline-block;
}
nav a:hover {
background-color: #ff5914;
}
.container {
max-width: 800px;
margin: auto;
padding: 10px;
}
.section {
margin-bottom: 20px;
}
.section h2 {
color: #ff5914;
font-size: 1.5rem;
text-align: center;
}
.section p {
color: #fff;
line-height: 1.5;
text-align: justify;
font-size: 0.9rem;
}
.pattern {
font-size: 1.2rem;
color: #ff5914;
text-align: center;
margin: 8px 0;
}
.social-share {
text-align: center;
margin: 15px 0;
}
.social-share a {
color: #fff;
margin: 0 8px;
text-decoration: none;
font-size: 1rem;
}
.social-share a:hover {
color: #ff5914;
}
.ghost {
position: absolute;
font-size: 1.5rem;
color: #fff;
opacity: 0.7;
animation: float 5s ease-in-out infinite;
}
@keyframes float {
0% { transform: translateY(0); }
50% { transform: translateY(-15px); }
100% { transform: translateY(0); }
}
.pumpkin {
font-size: 1.5rem;
color: #ff5914;
text-align: center;
animation: flicker 2s infinite;
}
@keyframes flicker {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
@media (max-width: 600px) {
header h1 {
font-size: 1.4rem;
}
.section h2 {
font-size: 1.2rem;
}
.pattern {
font-size: 1rem;
}
}
</style>
</head>
<body>
<header class="halloween-theme">
<h1>万圣节相关内容 🎃</h1>
<p>感受南瓜灯与幽灵的节日魅力!</p>
</header>
<nav>
<a href="#intro">万圣节简介</a>
<a href="#activities">节日活动</a>
<a href="#symbols">节日符号</a>
</nav>
<div class="container">
<section id="intro" class="section halloween-theme">
<h2>万圣节简介</h2>
<div class="pattern">🦇🦇🦇</div>
<p>万圣节是每年10月31日的传统节日,充满神秘与恐怖氛围。人们装扮成幽灵、巫婆,点亮南瓜灯,享受“不给糖就捣蛋”的乐趣,源于古老凯尔特传统。</p>
</section>
<section id="activities" class="section halloween-theme">
<h2>节日活动</h2>
<div class="pattern">🎃🎃🎃</div>
<p>万圣节活动包括南瓜雕刻、化装舞会和鬼屋探险。孩子们索要糖果,成人参加恐怖派对,尽情狂欢。</p>
</section>
<section id="symbols" class="section halloween-theme">
<h2>节日符号</h2>
<div class="pattern">👻👻👻</div>
<p>南瓜灯、幽灵、蝙蝠和巫婆帽子是万圣节经典符号,橙色、黑色、紫色营造诡异氛围。</p>
<div class="pumpkin">🎃 南瓜灯闪烁 🎃</div>
</section>
<section class="social-share">
<h2>分享万圣节乐趣</h2>
<div class="pattern">🦇🎃👻</div>
<a href="https://facebook.com" target="_blank">Facebook</a>
<a href="https://twitter.com" target="_blank">Twitter</a>
<a href="https://instagram.com" target="_blank">Instagram</a>
</section>
</div>
<div class="ghost" style="top: 20%; left: 10%;">👻</div>
<div class="ghost" style="top: 50%; right: 10%;">👻</div>
<footer>
<p>© 2025 万圣节相关内容</p>
<div class="pattern">🕸️🎃🕸️</div>
</footer>
</body>
</html>
)rawliteral";
void handleRoot() {
// 发送HTTP响应,状态码200,内容类型为text/html
server.send(200, "text/html", htmlContent);
}
void setup() {
// 初始化串口,用于调试
Serial.begin(115200);
Serial.println("Starting ESP32-C5 Web Server...");
// 设置ESP32为STA模式,连接手机热点
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi: ");
Serial.println(ssid);
// 等待连接,最多尝试20秒
int timeout = 20;
while (WiFi.status() != WL_CONNECTED && timeout > 0) {
delay(1000);
Serial.print(".");
timeout--;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi Connected");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP()); // 打印STA模式的IP地址
} else {
Serial.println("\nFailed to connect to WiFi. Check SSID/password or signal strength.");
return; // 连接失败,停止后续操作
}
// 设置Web服务器路由
server.on("/", handleRoot);
server.onNotFound([]() {
server.send(404, "text/plain", "404: Page Not Found");
});
// 启动服务器
server.begin();
Serial.println("HTTP Server Started");
}
void loop() {
// 处理客户端HTTP请求
server.handleClient();
delay(10); // 短暂延时以确保稳定性
}
很有趣的一点是,Ardunio编译器支持显示输入进去的卡通符号。
把代码中的ssid和password替换为自己的手机热点之后,确保笔记本电脑也连接的这个热点,将串口引脚接USB转TTL接电脑,打开串口调试助手,按一下复位按键。

会弹出一个IP地址,将这个IP地址输入浏览器打开就会显示网页:

事实上只要改代码中间html的内容,这个可以显示任何网页,比如可以改为网页按键控制的例子。

评论