[C++] 纯文本查看 复制代码
#include <WiFi.h>
#include <WebServer.h>
#include <EEPROM.h>
// 设置热点的SSID和密码
const char *ssid = "ESP32_配网热点";
const char *password = "123456789";
// 设置静态IP地址
IPAddress local_IP(192, 168, 9, 1);
IPAddress gateway(192, 168, 9, 1);
IPAddress subnet(255, 255, 255, 0);
// 创建Web服务器对象,监听端口80
WebServer server(80);
// 保存填写的账号和密码
String savedSSID = "";
String savedPassword = "";
// EEPROM地址定义
#define EEPROM_SIZE 64
#define SSID_ADDR 0
#define PASSWORD_ADDR 32
// BOOT按钮引脚定义
const int bootPin = 0; // Boot按钮引脚 长按3秒进入配网模式
const int io2Pin = 2; // 用于配网模式的led灯显示 我的板子上IO2有一个LED灯,所以用这个引脚
unsigned long bootPressTime = 0;
bool bootPressed = false;
bool inAPMode = false; // 是否在配网模式下
// 从EEPROM读取WiFi信息
void readWiFiInfo() {
char ssid[32];
char password[32];
EEPROM.begin(EEPROM_SIZE);
EEPROM.get(SSID_ADDR, ssid);
EEPROM.get(PASSWORD_ADDR, password);
ssid[31] = '\0'; // 确保字符串以null结尾
password[31] = '\0'; // 确保字符串以null结尾
savedSSID = String(ssid);
savedPassword = String(password);
EEPROM.end();
}
// 保存WiFi信息到EEPROM
void saveWiFiInfo(const String& ssid, const String& password) {
// 开始EEPROM操作
EEPROM.begin(EEPROM_SIZE);
// 创建字符数组来存储SSID和密码
char ssidArr[32];
char passwordArr[32];
// 将SSID和密码转换为字符数组
ssid.toCharArray(ssidArr, 32);
password.toCharArray(passwordArr, 32);
// 将SSID和密码写入EEPROM的指定地址
EEPROM.put(SSID_ADDR, ssidArr);
EEPROM.put(PASSWORD_ADDR, passwordArr);
// 提交更改,确保数据写入EEPROM
EEPROM.commit();
// 结束EEPROM操作
EEPROM.end();
}
// 处理配网请求
void handleConfig() {
String ssid = server.arg("ssid");
String password = server.arg("password");
if (ssid.length() > 0 && password.length() > 0) {
WiFi.disconnect(true); // 断开当前WiFi连接
WiFi.softAPdisconnect(true); // 关闭热点
WiFi.begin(ssid.c_str(), password.c_str());
// 等待连接,超时时间为15秒
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 15000) {
delay(1000);
}
if (WiFi.status() == WL_CONNECTED) {
// 保存WiFi信息到EEPROM
saveWiFiInfo(ssid, password);
digitalWrite(io2Pin, LOW); // WiFi正常连接后设置熄灭蓝色led灯
inAPMode = false; // 退出配网模式
} else {
// 重新启动热点
WiFi.softAP(::ssid, ::password);
WiFi.softAPConfig(local_IP, gateway, subnet);
digitalWrite(io2Pin, HIGH); // 进入配网模式时设置点亮蓝色led灯
inAPMode = true; // 进入配网模式
}
}
}
// 处理配网页面请求
void handleConfigPage() {
server.send(200, "text/html",
"<!DOCTYPE html>"
"<html>"
"<head>"
"<meta charset=\"UTF-8\">"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
"<title>WiFi 配网</title>"
"<style>"
"body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }"
"form { display: inline-block; text-align: left; max-width: 300px; }"
"label { display: block; margin-top: 10px; }"
"input[type='text'], input[type='password'] { width: 100%; padding: 8px; margin-top: 5px; }"
"input[type='submit'] { width: 100%; padding: 10px; margin-top: 20px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }"
"input[type='submit']:hover { background-color: #45a049; }"
"</style>"
"</head>"
"<body>"
"<h1>WiFi 配网</h1>"
"<form action=\"/config\" method=\"POST\">"
"<label for=\"ssid\">SSID:</label>"
"<input type=\"text\" id=\"ssid\" name=\"ssid\" required><br>"
"<label for=\"password\">密码:</label>"
"<input type=\"password\" id=\"password\" name=\"password\" required><br>"
"<input type=\"submit\" value=\"提交\">"
"</form>"
"</body>"
"</html>"
);
}
void startAPMode() {
// 启动热点
WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_IP, gateway, subnet);
// 设置处理根路径的请求
server.on("/", HTTP_GET, handleConfigPage);
// 设置处理配网页面和配网请求
server.on("/config", HTTP_POST, handleConfig);
// 启动Web服务器
server.begin();
digitalWrite(io2Pin, HIGH); // 进入配网模式时设置点亮蓝色led灯
inAPMode = true; // 进入配网模式
}
void setup() {
// 设置BOOT按钮和IO2引脚模式
pinMode(bootPin, INPUT_PULLUP);
pinMode(io2Pin, OUTPUT);
// 读取保存的WiFi信息
readWiFiInfo();
if (savedSSID.length() > 0 && savedPassword.length() > 0) {
// 尝试连接保存的WiFi
WiFi.begin(savedSSID.c_str(), savedPassword.c_str());
// 等待连接,超时时间为15秒
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 15000) {
delay(1000);
}
if (WiFi.status() == WL_CONNECTED) {
digitalWrite(io2Pin, LOW); // WiFi正常连接后设置熄灭蓝色led灯
} else {
startAPMode();
}
} else {
startAPMode();
}
}
void loop() {
// 处理客户Duan请求
server.handleClient();
// 检查WiFi连接状态,如果断开则尝试重连
if (!inAPMode && WiFi.status() != WL_CONNECTED && savedSSID.length() > 0 && savedPassword.length() > 0) {
WiFi.begin(savedSSID.c_str(), savedPassword.c_str());
// 等待连接,超时时间为15秒
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 15000) {
delay(1000);
}
if (WiFi.status() == WL_CONNECTED) {
digitalWrite(io2Pin, LOW); // WiFi正常连接后设置熄灭蓝色led灯
}
}
// 检查BOOT按钮状态
if (digitalRead(bootPin) == LOW) {
if (!bootPressed) {
bootPressed = true;
bootPressTime = millis();
} else if (millis() - bootPressTime >= 3000) {
// 按下BOOT按钮超过3秒,启动热点进行配网
startAPMode();
bootPressed = false;
}
} else {
bootPressed = false;
}
}