增加AP配网(信息未保存)

This commit is contained in:
2025-06-23 13:32:33 +08:00
parent b01d768d28
commit 14bcb9f34b
5 changed files with 280 additions and 178 deletions

View File

@ -2,6 +2,7 @@
#include "WiFiControl.h"
#include "LightControl.h"
extern RunTime runtime;
extern DS3502 ds3502;
extern BH1750 bh1750_a, bh1750_b;
@ -34,34 +35,28 @@ void TJC_Show::init() {
goToPage("start"); // 跳转到开机页面
}
void TJC_Show::showQR() {
char addr[64];
IPAddress ip;
#if SELECTED_WIFI_MODE == WIFI_MODE_STA
ip = WiFi.localIP();
snprintf(addr, sizeof(addr), "wifi.t0.txt=\"STA:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
sendCommand(addr);
#elif SELECTED_WIFI_MODE == WIFI_MODE_AP
if (WiFi.getMode() == WIFI_AP) { // AP模式
ip = WiFi.softAPIP();
snprintf(addr, sizeof(addr), "wifi.t0.txt=\"AP:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
sendCommand(addr);
#endif
Serial.printf("wifi.t0.txt=\"AP:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
} else if (WiFi.getMode() == WIFI_STA) { // STA模式
ip = WiFi.localIP();
snprintf(addr, sizeof(addr), "wifi.t0.txt=\"STA:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
sendCommand(addr);
Serial.printf("wifi.t0.txt=\"STA:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
}
snprintf(addr, sizeof(addr), "wifi.qr0.txt=\"http://%d.%d.%d.%d/\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
sendCommand(addr);
// if (SELECTED_WIFI_MODE == WIFI_MODE_STA){
// snprintf(addr, sizeof(addr), "t15.txt=\"STA:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
// sendCommand(addr);
// }
// if(SELECTED_WIFI_MODE == WIFI_MODE_AP){
// snprintf(addr, sizeof(addr), "t15.txt=\"AP:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
// sendCommand(addr);
// }
}
void TJC_Show::showInfo() {
char str[256];
@ -119,19 +114,23 @@ void TJC_Show::showInfo() {
sendCommand(str);
// === wifi 页面信息 ===
char addr[64];
IPAddress ip;
#if SELECTED_WIFI_MODE == WIFI_MODE_STA
ip = WiFi.localIP();
#elif SELECTED_WIFI_MODE == WIFI_MODE_AP
ip = WiFi.softAPIP();
#endif
snprintf(str, sizeof(str),
"wifi.t0.txt=\"STA:%d.%d.%d.%d\"\xff\xff\xff"
"wifi.qr0.txt=\"http://%d.%d.%d.%d/\"\xff\xff\xff",
ip[0], ip[1], ip[2], ip[3],
ip[0], ip[1], ip[2], ip[3]);
sendCommand(str);
if (WiFi.getMode() == WIFI_AP) { // AP模式
ip = WiFi.softAPIP();
snprintf(addr, sizeof(addr), "wifi.t0.txt=\"AP:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
sendCommand(addr);
//Serial.printf("wifi.t0.txt=\"AP:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
} else if (WiFi.getMode() == WIFI_STA) { // STA模式
ip = WiFi.localIP();
snprintf(addr, sizeof(addr), "wifi.t0.txt=\"STA:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
sendCommand(addr);
//Serial.printf("wifi.t0.txt=\"STA:%d.%d.%d.%d\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
}
snprintf(addr, sizeof(addr), "wifi.qr0.txt=\"http://%d.%d.%d.%d/\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]);
sendCommand(addr);
}
// void TJC_Show::processSerial() {
// #define FRAME_LENGTH 10

View File

@ -1,71 +1,84 @@
#include "WiFiControl.h"
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
const char* STA_SSIDS[STA_WIFI_COUNT] = {"SERVIRST-CT", "IRIS"};
const char* STA_PASSWORDS[STA_WIFI_COUNT] = {"servirst8888", "irishk*******"};
// AP 模式下的 SSID 和密码
const char* AP_SSID = "LampController_AP";
const char* AP_PASSWORD = "12345678";
// 存储从手机接收到的 WiFi 凭证
char user_ssid[64] = "";
char user_pass[64] = "";
//extern AsyncWebServer server(80); // 创建 Web 服务器实例
// 简单的 HTML 表单页面
const char html_form[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>WiFi Configuration</title>
<style>
body { font-family: Arial; margin: 30px; background-color: #f2f2f2; }
h2 { color: #333; }
input[type=text], input[type=password] {
width: 100%; padding: 12px 20px; margin: 8px 0; display: inline-block; border: 1px solid #ccc; box-sizing: border-box;
}
button { background-color: #4CAF50; color: white; padding: 14px 20px; margin: 8px 0; border: none; cursor: pointer; width: 100%; }
button:hover { opacity: 0.8; }
.container { background-color: #fff; padding: 20px; border-radius: 8px; max-width: 400px; margin: auto; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
</style>
</head>
<body>
<div class="container">
<h2>Connect to WiFi</h2>
<form action="/connect" method="POST">
<label for="ssid"><b>SSID</b></label>
<input type="text" placeholder="Enter WiFi Name" name="ssid" required>
<label for="password"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password" required>
<button type="submit">Save and Connect</button>
</form>
</div>
</body>
</html>
)rawliteral";
void WiFi_Init()
{
#if SELECTED_WIFI_MODE == WIFI_MODE_STA
if (!connectToKnownNetworks()) {
switchToAPMode();
}
#else
switchToAPMode();
#endif
}
bool connectToKnownNetworks()
{
Serial.println("Scanning nearby networks...");
int numNetworks = WiFi.scanNetworks();
if (numNetworks == 0) {
Serial.println("No networks found.");
return false;
}
Serial.print("Found ");
Serial.print(numNetworks);
Serial.println(" networks.");
for (int i = 0; i < numNetworks; ++i) {
String scannedSSID = WiFi.SSID(i);
for (int j = 0; j < STA_WIFI_COUNT; ++j) {
if (scannedSSID == STA_SSIDS[j]) {
Serial.print("Found known network: ");
Serial.println(scannedSSID);
WiFi.begin(STA_SSIDS[j], STA_PASSWORDS[j]);
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
return true;
} else {
Serial.println("Failed to connect.");
}
}
}
}
Serial.println("Could not connect to any known network.");
return false;
}
void switchToAPMode()
{
SELECTED_WIFI_MODE == WIFI_MODE_AP;
Serial.println("Switching to AP mode.");
// 默认启动时设置为 AP 模式
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID, AP_PASSWORD);
Serial.println("AP Mode started");
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
}
void connectToWiFi()
{
WiFi.mode(WIFI_STA); // 切换为 Station 模式
WiFi.begin(user_ssid, user_pass);
Serial.println("Connecting to WiFi...");
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("Failed to connect to WiFi.");
WiFi_Init(); // 连接失败返回 AP 模式
}
}

View File

@ -1,51 +1,10 @@
// #include <WiFi.h>
// #define WIFI_MODE_STA 1
// #define WIFI_MODE_AP 2
// // 选择WiFi模式取消注释需要的模式
// #define SELECTED_WIFI_MODE WIFI_MODE_STA
// //#define SELECTED_WIFI_MODE WIFI_MODE_AP
// // STA模式下的SSID和密码
// // #define STA_SSID "SERVIRST-CT"
// // #define STA_PASSWORD "servirst8888"
// #define STA_SSID "IRIS"
// #define STA_PASSWORD "irishk*******"
// // AP模式下的SSID和密码
// #define AP_SSID "APSSID"
// #define AP_PASSWORD "APPassword"
// void WiFi_Init(void);
// WiFiControl.h
#ifndef WIFICONTROL_H
#define WIFICONTROL_H
#include <WiFi.h>
#define WIFI_MODE_STA 0
#define WIFI_MODE_AP 1
// 默认选择WiFi模式
#define SELECTED_WIFI_MODE WIFI_MODE_STA
//#define SELECTED_WIFI_MODE WIFI_MODE_AP
// 设置多个 Wi-Fi 账号密码
#define STA_WIFI_COUNT 2
extern const char* STA_SSIDS[STA_WIFI_COUNT];
extern const char* STA_PASSWORDS[STA_WIFI_COUNT];
// AP模式下的SSID和密码
#define AP_SSID "APSSID"
#define AP_PASSWORD "APPassword"
void WiFi_Init(void);
bool connectToKnownNetworks(void);
void switchToAPMode(void);
#include <Arduino.h>
void WiFi_Init();
void connectToWiFi();
void setupWebServer();
#endif

View File

@ -18,7 +18,9 @@
#include <ArduinoJson.h>
// #include <esp_task_wdt.h>
// 全局变量用于存储 WiFi 凭据
extern char user_ssid[64]; // 存储 SSID
extern char user_pass[64]; // 存储密码
// Ticker 用于定时检查电流状态
Ticker currentCheckTicker;
@ -166,9 +168,41 @@ void WebServer_Init(void) {
request->send_P(200, "text/html", index_html);
});
// /*************************** AP配网 ***************** */
server.on("/config", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", config_html);
});
server.on("/saveWiFi", HTTP_POST, [](AsyncWebServerRequest *request){
if (request->hasParam("ssid", true) && request->hasParam("password", true)) {
// 获取 SSID 和密码
String ssid = request->getParam("ssid", true)->value();
String password = request->getParam("password", true)->value();
// 存储到全局变量
ssid.toCharArray(user_ssid, sizeof(user_ssid));
password.toCharArray(user_pass, sizeof(user_pass));
Serial.println("Received WiFi credentials:");
Serial.print("SSID: ");
Serial.println(user_ssid);
Serial.print("Password: ");
Serial.println(user_pass);
connectToWiFi(); // 连接目标 WiFi
}
// 返回确认页面
String response = "<!DOCTYPE html><html><body><h2>Configuration Received</h2><p>Please wait while the device connects to WiFi...</p></body></html>";
request->send(200, "text/html", response);
});
// 合并数据接口
server.on("/data", HTTP_GET, [](AsyncWebServerRequest *request){
StaticJsonDocument<256> doc;
//StaticJsonDocument<256> doc;
JsonDocument doc;
doc["temperature"] = sensorData.temperature;
doc["humidity"] = sensorData.humidity;
doc["lightA"] = sensorData.lightA;

View File

@ -10,47 +10,38 @@
// <title>ESP32 Data Display</title>
// <meta charset="UTF-8">
// <script>
// async function fetchData()
// {
// const durationResponse = await fetch('/duration');
// const durationText = await durationResponse.text();
// document.getElementById('activeDuration').innerText = durationText;
// async function fetchData() {
// const response = await fetch('/data');
// if (!response.ok) {
// alert('数据获取失败');
// return;
// }
// const tempResponse = await fetch('/temperature');
// const tempText = await tempResponse.text();
// document.getElementById('temperature').innerText = tempText;
// const data = await response.json();
// const lightAResponse = await fetch('/lightA');
// const lightAText = await lightAResponse.text();
// document.getElementById('lightA').innerText = lightAText;
// document.getElementById('activeDuration').innerText = data.duration;
// document.getElementById('temperature').innerText = data.temperature;
// document.getElementById('humidity').innerText = data.humidity;
// document.getElementById('lightA').innerText = data.lightA;
// document.getElementById('lightB').innerText = data.lightB;
// document.getElementById('wiper').innerText = data.wiper;
// document.getElementById('busVoltage').innerText = data.busVoltage;
// document.getElementById('shuntVoltage').innerText = data.shuntVoltage;
// document.getElementById('current').innerText = data.current;
// document.getElementById('power').innerText = data.power;
// const lightBResponse = await fetch('/lightB');
// const lightBText = await lightBResponse.text();
// document.getElementById('lightB').innerText = lightBText;
// // 获取灯光状态
// const statusResponse = await fetch('/lightStatus');
// const statusText = await statusResponse.text();
// document.getElementById('lightStatus').innerText = statusText === 'on' ? '开启' : '关闭';
// const wiperResponse = await fetch('/wiper');
// const wiperText = await wiperResponse.text();
// document.getElementById('wiper').innerText = wiperText;
// const busResponse = await fetch('/busVoltage');
// const busText = await busResponse.text();
// document.getElementById('busVoltage').innerText = busText;
// const shuntResponse = await fetch('/shuntVoltage');
// const shuntText = await shuntResponse.text();
// document.getElementById('shuntVoltage').innerText = shuntText;
// const currentResponse = await fetch('/current');
// const currentText = await currentResponse.text();
// document.getElementById('current').innerText = currentText;
// const powerResponse = await fetch('/power');
// const powerText = await powerResponse.text();
// document.getElementById('power').innerText = powerText;
// // 获取自动调节状态
// const autoAdjustStatusResponse = await fetch('/autoAdjustStatus');
// const autoAdjustStatusText = await autoAdjustStatusResponse.text();
// document.getElementById('autoAdjustStatus').innerText = autoAdjustStatusText === 'enabled' ? '开启' : '关闭';
// }
// async function setWiper()
// {
// async function setWiper() {
// const wiperValue = document.getElementById('wiperValue').value;
// const response = await fetch('/setWiper', {
// method: 'POST',
@ -64,8 +55,7 @@
// }
// }
// async function resetDuration()
// {
// async function resetDuration() {
// const response = await fetch('/resetDuration', { method: 'POST' });
// if (response.ok) {
// alert('累计使用时长已清空');
@ -74,31 +64,97 @@
// }
// }
// setInterval(fetchData, 1000);
// async function turnOnLight() {
// const response = await fetch('/LightOpen', { method: 'POST' });
// if (response.ok) {
// updateLightStatus("开启");
// } else {
// alert('打开失败');
// }
// }
// async function turnOffLight() {
// const response = await fetch('/LightClose', { method: 'POST' });
// if (response.ok) {
// updateLightStatus("关闭");
// } else {
// alert('关闭失败');
// }
// }
// function updateLightStatus(status) {
// document.getElementById('lightStatus').innerText = status;
// }
// async function enableAutoAdjust() {
// const targetLux = document.getElementById('targetLux').value;
// if (!targetLux || isNaN(targetLux) || parseInt(targetLux) <= 0) {
// alert('请输入有效的正整数作为目标照度');
// return;
// }
// // 发送请求给 ESP32 开启自动调节并设置目标照度
// const response = await fetch('/startAutoAdjust', {
// method: 'POST',
// headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
// body: 'target=' + encodeURIComponent(targetLux)
// });
// if (response.ok) {
// alert('已开启自动调节');
// } else {
// alert('开启失败');
// }
// }
// async function disableAutoAdjust() {
// const response = await fetch('/stopAutoAdjust', { method: 'POST' });
// if (response.ok) {
// alert('已关闭自动调节');
// } else {
// alert('关闭失败');
// }
// }
// setInterval(fetchData, 1000); // 每秒刷新一次数据
// </script>
// </head>
// <body onload="fetchData()">
// <h1>实时数据显示</h1>
// <p>累计使用时长: <span id="activeDuration">加载中...</span></p>
// <button onclick="resetDuration()">清空累计时长</button>
// <p>温度: <span id="temperature">加载中...</span> °C</p>
// <p>湿度: <span id="humidity">加载中...</span> %RH</p>
// <p>光照强度A: <span id="lightA">加载中...</span> lx</p>
// <p>光照强度B: <span id="lightB">加载中...</span> lx</p>
// <p>电位器Wiper值: <span id="wiper">加载中...</span></p>
// <p>总线电压: <span id="busVoltage">加载中...</span> V</p>
// <p>分流电压: <span id="shuntVoltage">加载中...</span> mV</p>
// <p>电流: <span id="current">加载中...</span> mA</p>
// <p>功率: <span id="power">加载中...</span> mW</p>
// <p>电流: <span id="current">加载中...</span> A</p>
// <p>功率: <span id="power">加载中...</span> W</p>
// <h2>设置Wiper值</h2>
// <input type="number" id="wiperValue" placeholder="输入Wiper值" />
// <input type="range" id="wiperValue" min="0" max="127" step="1" value="2" />
// <button onclick="setWiper()">设置</button>
// <h2>灯光控制</h2>
// <p>灯光状态: <span id="lightStatus">加载中...</span></p>
// <button onclick="turnOnLight()">开灯</button>
// <button onclick="turnOffLight()">关灯</button>
// <h2>自动调节</h2>
// <p>状态: <span id="autoAdjustStatus">加载中...</span></p>
// <p>目标照度: <input type="number" id="targetLux" min="0" max="100000" step="1" value="2000" /> lux</p>
// <button onclick="enableAutoAdjust()">开启</button>
// <button onclick="disableAutoAdjust()">关闭</button>
// </body>
// </html>
// )rawliteral"; // 添加分号
// )rawliteral";
// #endif // WEBPAGES_H
#ifndef WEBPAGES_H
#define WEBPAGES_H
@ -254,4 +310,45 @@ const char index_html[] PROGMEM = R"rawliteral(
</html>
)rawliteral";
// 新增 config_html 页面
const char config_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>ESP32 WiFi Setup</title>
<meta charset="UTF-8">
<script>
async function saveWiFiSettings() {
const ssid = document.getElementById("ssid").value;
const password = document.getElementById("password").value;
const response = await fetch("/saveWiFi", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "ssid=" + encodeURIComponent(ssid) + "&password=" + encodeURIComponent(password)
});
if (response.ok) {
alert("WiFi 设置保存成功!");
} else {
alert("保存失败,请重试。");
}
}
</script>
</head>
<body>
<h1>WiFi </h1>
<form onsubmit="event.preventDefault(); saveWiFiSettings();">
<label for="ssid">SSID:</label><br/>
<input type="text" id="ssid" name="ssid"><br/><br/>
<label for="password">:</label><br/>
<input type="password" id="password" name="password"><br/><br/>
<input type="submit" value="保存">
</form>
</body>
</html>
)rawliteral";
#endif // WEBPAGES_H