概述
想法很简单:用手机控制一颗 LED。不搞蓝牙、不装 App——就用 ESP32 自己跑一个网页,家里 WiFi 下的任何设备打开浏览器就能用。页面上放个滑块,拖动的时候 LED 亮度跟着实时变化。做下来发现这其实是个挺好的小练习,把 WiFi、HTTP 和 PWM 这三样 IoT 项目里必现的东西串在了一起。
系统架构
ESP32 同时充当 WiFi 客户端和 Web 服务器。
硬件
- ESP32-WROOM-32 开发板
- 内置 LED(GPIO 2)
- USB 数据线
先用板载 LED 试试手。不用面包板、不用外接元件——一块开发板加一根 USB 线就够。板载 LED 接在 GPIO 2 上,已经串好了限流电阻,直接写代码就能亮,省心。
软件
开发环境:Arduino IDE,需安装 ESP32 Arduino 核心支持包。
用到的库:
#include <WiFi.h>
#include <WebServer.h>
两个库都是 ESP32 Arduino Core 自带的,不用额外装任何东西。WiFi.h 管网络连接,WebServer.h 提供一个轻量级的 HTTP 服务器,做这种小项目刚刚好。
实现过程
WiFi 网页服务器
ESP32 连接到本地 WiFi 后,会提供一个控制页面。 同一网络下的设备可以通过分配的 IP 地址(例如 http://192.168.x.x/)访问该页面。
这是 ESP32 让我最喜欢的一点——几行代码就能起一个 Web 服务器,然后局域网里任何设备都能访问到它。不用配路由器、不用端口转发,就是一个本地 IP 地址,直接打开就行。
PWM 亮度控制
亮度控制采用 8 位分辨率的 PWM(0–255 对应 0%–100%)。 网页上的滑块会发送 HTTP 请求来改变占空比:
浏览器 → /set?value=亮度值 → ESP32 PWM 输出
选 8 位分辨率是因为它跟 ledcWrite 的取值范围刚好对上,滑块的 min/max 也能直接设成 0 和 255。网页端用 fetch() 在滑块每次移动时发一个 GET 请求到 /set?value=128,ESP32 收到后把数值解析出来写到 PWM 通道。5000 Hz 的频率下人眼完全看不到闪烁,很顺滑。
测试步骤
将程序上传到 ESP32。
打开串口监视器,记下连接后显示的 IP 地址。
在浏览器中访问该 IP 地址。
拖动滑块,观察 LED 的亮度变化。
结果
ESP32 成功连接网络、提供网页界面、接收 HTTP 亮度值并通过 PWM 驱动 LED。整个链路——硬件、网络、界面、物理输出——按预期工作,为更多交互式物联网项目奠定了基础。
这属于那种投入产出比特别舒服的小项目。大概 160 行代码就搞出一个能用的网页调光灯。WiFi + Web 服务器 + PWM 这个模式也很容易扩展——换成舵机就是角度控制,换成 MOSFET 就能驱动大功率灯带了。
完整代码
#include <WiFi.h>
#include <WebServer.h>
// 请替换为你自己的 WiFi 名称和密码
const char* ssid = "YOUR_WIFI_USERNAME_HERE";
const char* password = "YOUR_WIFI_PASSWORD_HERE";
WebServer server(80);
// LED 引脚
#define LED_PIN 2
// PWM 设置
#define PWM_CHANNEL 0
#define PWM_FREQ 5000
#define PWM_RESOLUTION 8 // 8 位分辨率 = 0–255
void setup() {
Serial.begin(115200);
// 配置 PWM
ledcAttach(LED_PIN, PWM_FREQ, PWM_RESOLUTION);
// 初始亮度 50%
ledcWrite(PWM_CHANNEL, 128);
// 连接 WiFi
WiFi.begin(ssid, password);
Serial.print("正在连接 WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi 已连接");
Serial.print("IP 地址:");
Serial.println(WiFi.localIP());
// 主页
server.on("/", []() {
String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ESP32 LED 控制</title>
<style>
body { text-align: center; font-family: Arial; }
input { width: 80%; }
</style>
</head>
<body>
<h1>ESP32 LED 控制</h1>
<h2>亮度调节</h2>
<input type="range" min="0" max="255" value="128" id="brightness"
oninput="changeBrightness(this.value)">
<p>当前亮度:<span id="value">128</span></p>
<script>
function changeBrightness(value) {
document.getElementById("value").innerHTML = value;
fetch("/set?value=" + value);
}
</script>
</body>
</html>
)rawliteral";
server.send(200, "text/html;charset=utf-8", html);
});
// 接收网页亮度数据
server.on("/set", []() {
if (server.hasArg("value")) {
int brightness = server.arg("value").toInt();
// 输出 PWM 信号
ledcWrite(LED_PIN, brightness);
Serial.print("亮度:");
Serial.println(brightness);
}
server.send(200, "text/plain", "OK");
});
server.begin();
Serial.println("Web 服务器已启动");
}
void loop() {
server.handleClient();
}
