From 1f790a3ec39584eb1c9afea6f196a3dc96e7ed6d Mon Sep 17 00:00:00 2001 From: chenxin Date: Wed, 9 Jul 2025 17:29:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E7=A6=BBhtml=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/config.html | 94 +++++++++ data/data_backup/config1.html | 50 +++++ data/data_backup/index1.html | 146 ++++++++++++++ data/index.html | 264 +++++++++++++++++++++++++ platformio.ini | 1 - src/DHT11.cpp | 240 ----------------------- src/DHT11.h | 110 ----------- src/WebHandlers.cpp | 208 ++++++++++++++++++++ src/WebHandlers.h | 55 ++++++ src/WebServer.cpp | 94 --------- src/WebServer.h | 17 -- src/WiFiControl.cpp | 47 +---- src/WiFiControl.h | 5 +- src/main.cpp | 180 ++--------------- src/mywebserver.cpp | 151 +++++++++++++++ src/mywebserver.h | 25 +++ src/webpages.h | 354 ---------------------------------- 17 files changed, 1020 insertions(+), 1021 deletions(-) create mode 100644 data/config.html create mode 100644 data/data_backup/config1.html create mode 100644 data/data_backup/index1.html create mode 100644 data/index.html delete mode 100644 src/DHT11.cpp delete mode 100644 src/DHT11.h create mode 100644 src/WebHandlers.cpp create mode 100644 src/WebHandlers.h delete mode 100644 src/WebServer.cpp delete mode 100644 src/WebServer.h create mode 100644 src/mywebserver.cpp create mode 100644 src/mywebserver.h delete mode 100644 src/webpages.h diff --git a/data/config.html b/data/config.html new file mode 100644 index 0000000..7ea09a1 --- /dev/null +++ b/data/config.html @@ -0,0 +1,94 @@ + + + + + ESP32 WiFi 设置 + + + + +

WiFi 设置

+
+ + + + + + + +
+ + diff --git a/data/data_backup/config1.html b/data/data_backup/config1.html new file mode 100644 index 0000000..93db6ba --- /dev/null +++ b/data/data_backup/config1.html @@ -0,0 +1,50 @@ + + + + ESP32 WiFi Setup + + + + +

WiFi 设置

+
+
+

+ +
+

+ + +
+ + \ No newline at end of file diff --git a/data/data_backup/index1.html b/data/data_backup/index1.html new file mode 100644 index 0000000..9441c07 --- /dev/null +++ b/data/data_backup/index1.html @@ -0,0 +1,146 @@ + + + + ESP32 Data Display + + + + +

实时数据显示

+ +

累计使用时长: 加载中...

+ + +

温度: 加载中... °C

+

湿度: 加载中... %RH

+

光照强度(A): 加载中... lx

+

光照强度(B): 加载中... lx

+

电位器Wiper值: 加载中...

+

总线电压: 加载中... V

+

分流电压: 加载中... mV

+

电流: 加载中... A

+

功率: 加载中... W

+ +

设置Wiper值

+ + + +

灯光控制

+

灯光状态: 加载中...

+ + + +

自动调节

+

状态: 加载中...

+

目标照度: lux

+ + + + \ No newline at end of file diff --git a/data/index.html b/data/index.html new file mode 100644 index 0000000..dfa4216 --- /dev/null +++ b/data/index.html @@ -0,0 +1,264 @@ + + + + + ESP32 实时监控面板 + + + + + +

📟 ESP32 实时监控面板

+ +
+
+
累计使用时长
+
--
+
+
+ +
+
+ + +
+
+
温度
+
--
+
+
+
湿度
+
--
+
+
+ + +
+
+
光照 A
+
--
+
+
+
光照 B
+
--
+
+
+ + +
+
+
总线电压
+
--
+
+
+
电流
+
--
+
+
+
功率
+
--
+
+
+ + +
+
+ + + 0 + +
+ +
+ + + +
+ +
+ + + + +
+
+ + + diff --git a/platformio.ini b/platformio.ini index 07be14b..e6ac3f9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -14,7 +14,6 @@ board = esp32-s3-devkitc-1 framework = arduino lib_deps = robtillaart/INA226@^0.6.0 - esphome/ESPAsyncWebServer-esphome@^3.3.0 bblanchon/ArduinoJson@^7.4.1 monitor_speed = 115200 diff --git a/src/DHT11.cpp b/src/DHT11.cpp deleted file mode 100644 index 55ebb6c..0000000 --- a/src/DHT11.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/** - * DHT11.cpp - * Library for reading temperature and humidity from the DHT11 sensor. - * - * Author: Dhruba Saha - * Version: 2.1.0 - * License: MIT - */ - -#include "DHT11.h" - -/** - * Constructor for the DHT11 class. - * Initializes the pin to be used for communication and sets it to output mode. - * - * @param pin: Digital pin number on the Arduino board to which the DHT11 sensor is connected. - */ -DHT11::DHT11(int pin) : _pin(pin) -{ - pinMode(_pin, OUTPUT); - digitalWrite(_pin, HIGH); -} - -/** - * Sets the delay between consecutive sensor readings. - * If this method is not called, a default delay of 500 milliseconds is used. - * - * @param delay: Delay duration in milliseconds between sensor readings. - */ -void DHT11::setDelay(unsigned long delay) -{ - _delayMS = delay; -} - -/** - * Reads raw data from the DHT11 sensor. - * This method handles the direct communication with the DHT11 sensor and retrieves the raw data. - * It's used internally by the readTemperature, readHumidity, and readTemperatureHumidity methods. - * - * @param data: An array of bytes where the raw sensor data will be stored. - * The array must be at least 5 bytes long, as the DHT11 sensor returns 5 bytes of data. - * @return: Returns 0 if the data is read successfully and the checksum matches. - * Returns DHT11::ERROR_TIMEOUT if the sensor does not respond or communication times out. - * Returns DHT11::ERROR_CHECKSUM if the data is read but the checksum does not match. - */ -int DHT11::readRawData(byte data[5]) -{ - delay(_delayMS); - startSignal(); - unsigned long timeout_start = millis(); - - while (digitalRead(_pin) == HIGH) - { - if (millis() - timeout_start > TIMEOUT_DURATION) - { - return DHT11::ERROR_TIMEOUT; - } - } - - if (digitalRead(_pin) == LOW) - { - delayMicroseconds(80); - if (digitalRead(_pin) == HIGH) - { - delayMicroseconds(80); - for (int i = 0; i < 5; i++) - { - data[i] = readByte(); - if (data[i] == DHT11::ERROR_TIMEOUT) - { - return DHT11::ERROR_TIMEOUT; - } - } - - if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) - { - return 0; // Success - } - else - { - return DHT11::ERROR_CHECKSUM; - } - } - } - return DHT11::ERROR_TIMEOUT; -} - -/** - * Reads a byte of data from the DHT11 sensor during the communication process. - * - * @return: A byte of data read from the sensor. - */ -byte DHT11::readByte() -{ - byte value = 0; - - for (int i = 0; i < 8; i++) - { - while (digitalRead(_pin) == LOW) - ; - delayMicroseconds(30); - if (digitalRead(_pin) == HIGH) - { - value |= (1 << (7 - i)); - } - while (digitalRead(_pin) == HIGH) - ; - } - return value; -} - -/** - * Sends a start signal to the DHT11 sensor to initiate a data read. - * This involves setting the data pin low for a specific duration, then high, - * and finally setting it to input mode to read the data. - */ -void DHT11::startSignal() -{ - pinMode(_pin, OUTPUT); - digitalWrite(_pin, LOW); - delay(18); - digitalWrite(_pin, HIGH); - delayMicroseconds(40); - pinMode(_pin, INPUT); -} - -/** - * Reads and returns the temperature from the DHT11 sensor. - * Utilizes the readRawData method to retrieve raw data from the sensor and then extracts - * the temperature from the data array. - * - * @return: Temperature value in Celsius. Returns DHT11::ERROR_TIMEOUT if reading times out, - * or DHT11::ERROR_CHECKSUM if checksum validation fails. - */ -int DHT11::readTemperature() -{ - byte data[5]; - int error = readRawData(data); - if (error != 0) - { - return error; - } - //return data[2]; - int temp = data[2]; - if (temp != DHT11::ERROR_CHECKSUM && temp != DHT11::ERROR_TIMEOUT) - { - return temp; - } -} - -/** - * Reads and returns the humidity from the DHT11 sensor. - * Utilizes the readRawData method to retrieve raw data from the sensor and then extracts - * the humidity from the data array. - * - * @return: Humidity value in percentage. Returns DHT11::ERROR_TIMEOUT if reading times out, - * or DHT11::ERROR_CHECKSUM if checksum validation fails. - */ -int DHT11::readHumidity() -{ - byte data[5]; - int error = readRawData(data); - if (error != 0) - { - return error; - } - //return data[0]; - int humi = data[0]; - if (humi != DHT11::ERROR_CHECKSUM && humi != DHT11::ERROR_TIMEOUT) - { - return humi; - } -} - -/** - * Reads and returns the temperature and humidity from the DHT11 sensor. - * Utilizes the readRawData method to retrieve raw data from the sensor and then extracts - * both temperature and humidity from the data array. - * - * @param temperature: Reference to a variable where the temperature value will be stored. - * @param humidity: Reference to a variable where the humidity value will be stored. - * @return: An integer representing the status of the read operation. - * Returns 0 if the reading is successful, DHT11::ERROR_TIMEOUT if a timeout occurs, - * or DHT11::ERROR_CHECKSUM if a checksum error occurs. - */ -int DHT11::readTemperatureHumidity(int &temperature, int &humidity) -{ - byte data[5]; - int error = readRawData(data); - if (error != 0) - { - return error; - } - humidity = data[0]; - temperature = data[2]; - return 0; // Indicate success -} - -/** - * Returns a human-readable error message based on the provided error code. - * This method facilitates easier debugging and user feedback by translating - * numeric error codes into descriptive strings. - * - * @param errorCode The error code for which the description is required. - * @return A descriptive string explaining the error. - */ -String DHT11::getErrorString(int errorCode) -{ - switch (errorCode) - { - case DHT11::ERROR_TIMEOUT: - return "Error 253 Reading from DHT11 timed out."; - case DHT11::ERROR_CHECKSUM: - return "Error 254 Checksum mismatch while reading from DHT11."; - default: - return "Error Unknown."; - } -} - -int DHT11::getTempHumi(int &temperature, int &humidity) -{ - // Attempt to read the temperature and humidity values from the DHT11 sensor. - int result = readTemperatureHumidity(temperature, humidity); - - // Check the results of the readings. - // If the reading is successful, print the temperature and humidity values. - // If there are errors, print the appropriate error messages. - if (result == 0) { - Serial.print("Temperature: "); - Serial.print(temperature); - Serial.print(" °C\tHumidity: "); - Serial.print(humidity); - Serial.println(" %"); - } else { - // Print error message based on the error code. - Serial.println(DHT11::getErrorString(result)); - } -} - - diff --git a/src/DHT11.h b/src/DHT11.h deleted file mode 100644 index 5f20068..0000000 --- a/src/DHT11.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * DHT11.h - * Header file for the DHT11 library, providing functionalities to interface with - * the DHT11 temperature & humidity sensor. - * - * Author: Dhruba Saha - * Version: 2.1.0 - * License: MIT - */ - -#ifndef DHT11_h -#define DHT11_h - -#include "Arduino.h" - -/** - * DHT11 Class - * Provides methods to read temperature and humidity data from the DHT11 sensor. - */ -class DHT11 -{ -public: - /** - * Constructor - * Initializes the data pin to be used for communication with the DHT11 sensor. - * - * @param pin: Digital pin number on the Arduino board to which the DHT11 sensor is connected. - */ - DHT11(int pin); - - /** - * Sets the delay between consecutive sensor readings. - * If this method is not called, a default delay of 500 milliseconds is used. - * - * @param delay: Delay duration in milliseconds between sensor readings. - */ - void setDelay(unsigned long delay); - - /** - * Reads and returns the humidity from the DHT11 sensor. - * - * @return: Humidity value in percentage. Returns DHT11_ERROR_TIMEOUT if reading times out. - * Returns DHT11_ERROR_CHECKSUM if checksum validation fails. - */ - int readHumidity(); - - /** - * Reads and returns the temperature from the DHT11 sensor. - * - * @return: Temperature value in Celsius. Returns DHT11_ERROR_TIMEOUT if reading times out. - * Returns DHT11_ERROR_CHECKSUM if checksum validation fails. - */ - int readTemperature(); - - /** - * Reads and returns the temperature and humidity from the DHT11 sensor. - * - * @param temperature: Reference to a variable where the temperature value will be stored. - * @param humidity: Reference to a variable where the humidity value will be stored. - * @return: true if the reading is successful, false if it fails due to timeout or checksum error. - */ - int readTemperatureHumidity(int &temperature, int &humidity); - - int getTempHumi(int &temperature, int &humidity); - - // Constants to represent error codes. - static const int ERROR_CHECKSUM = 254; // Error code indicating checksum mismatch. - static const int ERROR_TIMEOUT = 253; // Error code indicating a timeout occurred during reading. - static const int TIMEOUT_DURATION = 1000; // Duration (in milliseconds) to wait before timing out. - - /** - * Returns a human-readable error message based on the provided error code. - * - * @param errorCode: The error code for which the message is required. - * @return: A string describing the error. - */ - static String getErrorString(int errorCode); - -private: - int _pin; // Pin number used for communication with the DHT11 sensor. - unsigned long _delayMS = 500; // Default delay in milliseconds between sensor readings. - - /** - * Private method to read raw data from the DHT11 sensor. - * This method encapsulates the communication with the sensor and data reading process, - * and is utilized by public methods to get temperature and humidity data. - * - * @param data: Array to store the raw data read from the sensor. - * @return: An integer representing the status of the read operation. - * Returns 0 if the reading is successful, DHT11::ERROR_TIMEOUT if a timeout occurs, - * or DHT11::ERROR_CHECKSUM if a checksum error occurs. - */ - int readRawData(byte data[5]); - - /** - * Reads a byte of data from the DHT11 sensor. - * - * @return: A byte of data read from the sensor. - */ - byte readByte(); - - /** - * Sends a start signal to the DHT11 sensor to initiate a data read. - * This involves setting the data pin low for a specific duration, then high, - * and finally setting it to input mode to read the data. - */ - void startSignal(); -}; - -#endif diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp new file mode 100644 index 0000000..25cc869 --- /dev/null +++ b/src/WebHandlers.cpp @@ -0,0 +1,208 @@ +#include "WebHandlers.h" + +#define LIGHT_CONTROL_PIN 1 + +// 全局WebServer指针,用于在处理函数中访问 +WebServer* webServerPtr = nullptr; + +// 读取SPIFFS文件的辅助函数 +String readFile(const String& path) { + if (!SPIFFS.exists(path)) { + return "File not found"; + } + + File file = SPIFFS.open(path, "r"); + if (!file) { + return "Failed to open file"; + } + + String content = file.readString(); + file.close(); + return content; +} + +// 根路径页面处理 +void handleRoot() { + String html = readFile("/index.html"); + webServerPtr->send(200, "text/html", html); +} + +// 配置页面处理 +void handleConfig() { + String html = readFile("/config.html"); + webServerPtr->send(200, "text/html", html); +} + +// 保存WiFi凭证处理 +void handleSaveWiFi() { + if (webServerPtr->hasArg("ssid") && webServerPtr->hasArg("password")) { + // 获取 SSID 和密码 + String ssid = webServerPtr->arg("ssid"); + String password = webServerPtr->arg("password"); + + // 存储到全局变量 + ssid.toCharArray(user_ssid, sizeof(user_ssid)); + password.toCharArray(user_pass, sizeof(user_pass)); + + // 设置待连接的WiFi信息 + SSID = ssid; + Password = password; + shouldConnectWiFi = true; + + Serial.println("Received WiFi credentials:"); + Serial.print("SSID: "); + Serial.println(user_ssid); + Serial.print("Password: "); + Serial.println(user_pass); + + // 使用ArduinoJson库生成成功响应 + JsonDocument doc; + doc["status"] = "success"; + doc["message"] = "WiFi设置已保存,正在连接..."; + + String jsonResponse; + serializeJson(doc, jsonResponse); + webServerPtr->send(200, "application/json", jsonResponse); + } else { + // 使用ArduinoJson库生成错误响应 + JsonDocument errorDoc; + errorDoc["status"] = "error"; + errorDoc["message"] = "缺少SSID或密码参数"; + + String errorResponse; + serializeJson(errorDoc, errorResponse); + webServerPtr->send(400, "application/json", errorResponse); + } +} + +// 传感器数据API处理 +void handleData() { + JsonDocument doc; + doc["temperature"] = sensorData.temperature; + doc["humidity"] = sensorData.humidity; + doc["lightA"] = sensorData.lightA; + doc["lightB"] = sensorData.lightB; + doc["wiper"] = ds3502.getWiper(); + doc["busVoltage"] = sensorData.busVoltage; + doc["shuntVoltage"] = sensorData.shuntVoltage_mV; + doc["current"] = sensorData.current; + doc["power"] = sensorData.power; + doc["duration"] = runtime.formatDuration(runtime.getActiveDuration()); + + String json; + serializeJson(doc, json); + webServerPtr->send(200, "application/json", json); +} + +// 设置Wiper值处理 +void handleSetWiper() { + if (webServerPtr->hasArg("value")) { + int wiperValue = webServerPtr->arg("value").toInt(); + ds3502.setWiper(wiperValue); + webServerPtr->send(200, "text/plain", "Wiper value set"); + } else { + webServerPtr->send(400, "text/plain", "Missing value parameter"); + } +} + +// 重置运行时长处理 +void handleResetDuration() { + runtime.resetActiveDuration(); + webServerPtr->send(200, "text/plain", "Duration reset"); +} + +// 开灯处理 +void handleLightOpen() { + LightOpen(); + webServerPtr->send(200, "text/plain", "Light ON"); +} + +// 关灯处理 +void handleLightClose() { + LightClose(); + webServerPtr->send(200, "text/plain", "Light OFF"); +} + +// 获取灯光状态处理 +void handleLightStatus() { + bool isOn = (digitalRead(LIGHT_CONTROL_PIN) == HIGH); // 高电平为开灯 + webServerPtr->send(200, "text/plain", isOn ? "on" : "off"); +} + +// 启动自动调节处理 +void handleStartAutoAdjust() { + if (webServerPtr->hasArg("target")) { + int targetLux = webServerPtr->arg("target").toInt(); + if (targetLux > 0) { + lightCtrl.setTargetLight(targetLux); + lightCtrl.adjustToTarget(); + isAutoAdjustEnabled = true; + webServerPtr->send(200, "text/plain", "Auto adjust started"); + } else { + webServerPtr->send(400, "text/plain", "Invalid target lux"); + } + } else { + webServerPtr->send(400, "text/plain", "Missing target parameter"); + } +} + +// 停止自动调节处理 +void handleStopAutoAdjust() { + isAutoAdjustEnabled = false; + webServerPtr->send(200, "text/plain", "Auto adjust stopped"); +} + +// 获取自动调节状态处理 +void handleAutoAdjustStatus() { + webServerPtr->send(200, "text/plain", isAutoAdjustEnabled ? "enabled" : "disabled"); +} + +// 404处理 +void handleNotFound() { + webServerPtr->send(404, "text/plain", "404 Not Found"); +} + +// Web服务器初始化函数 +void WebServer_Init(WebServer& server) { + // 设置全局指针 + webServerPtr = &server; + + // 初始化SPIFFS + if (!SPIFFS.begin(true)) { + Serial.println("An Error has occurred while mounting SPIFFS"); + return; + } + + // 启用CORS + server.enableCORS(true); + + // 根路径页面 + server.on("/", HTTP_GET, handleRoot); + + // AP配网相关 + server.on("/config", HTTP_GET, handleConfig); + server.on("/saveWiFi", HTTP_POST, handleSaveWiFi); + + // 数据API + server.on("/data", HTTP_GET, handleData); + + // 设备控制API + server.on("/setWiper", HTTP_POST, handleSetWiper); + server.on("/resetDuration", HTTP_POST, handleResetDuration); + + // 灯光控制API + server.on("/LightOpen", HTTP_POST, handleLightOpen); + server.on("/LightClose", HTTP_POST, handleLightClose); + server.on("/lightStatus", HTTP_GET, handleLightStatus); + + // 自动调节API + server.on("/startAutoAdjust", HTTP_POST, handleStartAutoAdjust); + server.on("/stopAutoAdjust", HTTP_POST, handleStopAutoAdjust); + server.on("/autoAdjustStatus", HTTP_GET, handleAutoAdjustStatus); + + // 404处理 + server.onNotFound(handleNotFound); + + // 启动服务器 + server.begin(); +} \ No newline at end of file diff --git a/src/WebHandlers.h b/src/WebHandlers.h new file mode 100644 index 0000000..0325189 --- /dev/null +++ b/src/WebHandlers.h @@ -0,0 +1,55 @@ +#ifndef WEBHANDLERS_H +#define WEBHANDLERS_H + +#include +#include +#include +#include +#include "SPIFFS.h" +#include "TJC_Show.h" +#include "LightControl.h" +#include "RunTime.h" +#include "DS3502.h" +#include "WiFiControl.h" + +// 声明外部变量 +extern SensorData sensorData; +extern DS3502 ds3502; +extern RunTime runtime; +extern LightControl lightCtrl; +extern bool isAutoAdjustEnabled; +extern char user_ssid[64]; +extern char user_pass[64]; + +// WiFi连接相关变量 +extern bool shouldConnectWiFi; +extern String SSID; +extern String Password; + +// 声明外部函数 +extern void LightOpen(); +extern void LightClose(); +extern void connectToWiFi(String ssid, String password); + +// Web处理函数声明 +void handleRoot(); +void handleConfig(); +void handleSaveWiFi(); +void handleData(); +void handleSetWiper(); +void handleResetDuration(); +void handleLightOpen(); +void handleLightClose(); +void handleLightStatus(); +void handleStartAutoAdjust(); +void handleStopAutoAdjust(); +void handleAutoAdjustStatus(); +void handleNotFound(); + +// 辅助函数 +String readFile(const String& path); + +// Web服务器初始化函数 +void WebServer_Init(WebServer& server); + +#endif \ No newline at end of file diff --git a/src/WebServer.cpp b/src/WebServer.cpp deleted file mode 100644 index 1934cb4..0000000 --- a/src/WebServer.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// #include "WebServer.h" - - -// extern RunTime runtime; -// extern MCP45HVX1 digiPot; -// extern INA226 INA; -// extern DS18B20 ds18b20; -// extern BH1750 bh1750_a; -// extern BH1750 bh1750_b; - -// AsyncWebServer server(80); - -// void WebServer_Init(const char* ssid, const char* password) { -// WiFi.begin(ssid, password); // WiFi -// while (WiFi.status() != WL_CONNECTED) { -// delay(1000); -// Serial.println("Connecting to WiFi..."); -// } -// Serial.print("Address: "); -// Serial.println(WiFi.localIP()); - -// // 根路径的页面 -// server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { -// request->send_P(200, "text/html", index_html); -// }); - -// // 温度接口 -// server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request) { -// String temp = String(ds18b20.getTempC()); -// request->send(200, "text/plain", temp); -// }); - -// // 光照强度(传感器A) -// server.on("/lightA", HTTP_GET, [](AsyncWebServerRequest *request) { -// String lightA = String(bh1750_a.readLightLevel()); -// request->send(200, "text/plain", lightA); -// }); - -// // 光照(传感器B) -// server.on("/lightB", HTTP_GET, [](AsyncWebServerRequest *request) { -// String lightB = String(bh1750_b.readLightLevel()); -// request->send(200, "text/plain", lightB); -// }); - -// // 配置Wiper接口 -// server.on("/wiper", HTTP_GET, [](AsyncWebServerRequest *request) { -// String wiper = String(digiPot.readWiper()); -// request->send(200, "text/plain", wiper); -// }); - -// server.on("/busVoltage", HTTP_GET, [](AsyncWebServerRequest *request) { -// String busVoltage = String(INA.getBusVoltage(), 3); -// request->send(200, "text/plain", busVoltage); -// }); - -// server.on("/shuntVoltage", HTTP_GET, [](AsyncWebServerRequest *request) { -// String shuntVoltage = String(INA.getShuntVoltage_mV(), 3); -// request->send(200, "text/plain", shuntVoltage); -// }); - -// server.on("/current", HTTP_GET, [](AsyncWebServerRequest *request) { -// String current = String(INA.getCurrent_mA(), 3); -// request->send(200, "text/plain", current); -// }); - -// server.on("/power", HTTP_GET, [](AsyncWebServerRequest *request) { -// String power = String(INA.getPower_mW(), 3); -// request->send(200, "text/plain", power); -// }); - -// // 获取累计时长接口 -// server.on("/duration", HTTP_GET, [](AsyncWebServerRequest *request) { -// request->send(200, "text/plain", runtime.formatDuration(runtime.getActiveDuration())); -// }); - -// // 清空累计时长接口 -// server.on("/resetDuration", HTTP_POST, [](AsyncWebServerRequest *request) { -// runtime.resetActiveDuration(); -// request->send(200, "text/plain", "Duration reset"); -// }); - -// // 接收设置Wiper的请求 -// server.on("/setWiper", HTTP_POST, [](AsyncWebServerRequest *request) { -// if (request->hasParam("value", true)) { -// int wiperValue = request->getParam("value", true)->value().toInt(); -// digiPot.writeWiper(wiperValue); -// request->send(200, "text/plain", "Wiper value set"); -// } else { -// request->send(400, "text/plain", "Missing value parameter"); -// } -// }); - -// server.begin(); -// } \ No newline at end of file diff --git a/src/WebServer.h b/src/WebServer.h deleted file mode 100644 index 2e90d86..0000000 --- a/src/WebServer.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef WEBSERVER_H -#define WEBSERVER_H - -#include "webpages.h" // 包含 HTML 页面内容 -#include -#include -#include "BH1750.h" -#include "Wire.h" -//#include "MCP45HVX1.h" -#include "INA226.h" -#include "RunTime.h" - - - -void WebServer_Init(void); - -#endif // WEBSERVER_H \ No newline at end of file diff --git a/src/WiFiControl.cpp b/src/WiFiControl.cpp index 8abbf41..be7a10b 100644 --- a/src/WiFiControl.cpp +++ b/src/WiFiControl.cpp @@ -1,6 +1,8 @@ #include "WiFiControl.h" #include -#include +#include +#include "SPIFFS.h" +#include "mywebserver.h" // AP 模式下的 SSID 和密码 const char* AP_SSID = "LampController_AP"; @@ -10,42 +12,7 @@ const char* AP_PASSWORD = "12345678"; char user_ssid[64] = ""; char user_pass[64] = ""; - -//extern AsyncWebServer server(80); // 创建 Web 服务器实例 - -// 简单的 HTML 表单页面 -const char html_form[] PROGMEM = R"rawliteral( - - - - WiFi Configuration - - - -
-

Connect to WiFi

-
- - - - - - - -
-
- - -)rawliteral"; +extern mywebserver* webServer; void WiFi_Init() { @@ -56,14 +23,12 @@ void WiFi_Init() Serial.println("AP Mode started"); Serial.print("AP IP address: "); Serial.println(WiFi.softAPIP()); - } - -void connectToWiFi() +void connectToWiFi(String ssid, String password) { WiFi.mode(WIFI_STA); // 切换为 Station 模式 - WiFi.begin(user_ssid, user_pass); + WiFi.begin(ssid, password); Serial.println("Connecting to WiFi..."); diff --git a/src/WiFiControl.h b/src/WiFiControl.h index 6420192..1d8de0a 100644 --- a/src/WiFiControl.h +++ b/src/WiFiControl.h @@ -3,8 +3,9 @@ #include + void WiFi_Init(); -void connectToWiFi(); -void setupWebServer(); +void connectToWiFi(String ssid, String password); + #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 111a1c2..fe8a655 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,26 +2,32 @@ #include "BH1750.h" #include "Wire.h" #include -#include #include - +#include #include "INA226.h" #include #include // 用于存储非易失性数据 #include "TJC_Show.h" #include "RunTime.h" -#include "WebServer.h" + #include "WiFiControl.h" #include "DS3502.h" #include "LightControl.h" #include +//#include "mywebserver.h" +#include "WebHandlers.h" + // #include // 全局变量用于存储 WiFi 凭据 extern char user_ssid[64]; // 存储 SSID extern char user_pass[64]; // 存储密码 +String SSID; +String Password; +bool shouldConnectWiFi = false; + // Ticker 用于定时检查电流状态 Ticker currentCheckTicker; @@ -31,7 +37,7 @@ DS3502 ds3502(0x28); // INA226 电流监控器 INA226 INA(0x40); -AsyncWebServer server(80); +WebServer server(80); // DHT11 温湿度传感器 @@ -162,162 +168,6 @@ void LightClose() { } -void WebServer_Init(void) { - // 根路径页面 - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ - 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 = "

Configuration Received

Please wait while the device connects to WiFi...

"; - request->send(200, "text/html", response); - }); -// int32_t IRIS_Protocol_Pack(uint8_t Command,uint16_t LenthofIn, uint8_t *BufferIn, uint8_t *PackData); - // 合并数据接口 - server.on("/data", HTTP_GET, [](AsyncWebServerRequest *request){ - //StaticJsonDocument<256> doc; - JsonDocument doc; - doc["temperature"] = sensorData.temperature; - doc["humidity"] = sensorData.humidity; - doc["lightA"] = sensorData.lightA; - doc["lightB"] = sensorData.lightB; - doc["wiper"] = ds3502.getWiper(); - doc["busVoltage"] = sensorData.busVoltage; - doc["shuntVoltage"] = sensorData.shuntVoltage_mV; - doc["current"] = sensorData.current; - doc["power"] = sensorData.power; - doc["duration"] = runtime.formatDuration(runtime.getActiveDuration()); - - String json; - serializeJson(doc, json); - request->send(200, "application/json", json); - // uint8_t *bufferfosend; - // int lentofpack=IRIS_Protocol_Pack(0x00, json.length(), (uint8_t*)json.c_str(),bufferfosend); - // Serial1.write(bufferfosend,lentofpack); - // delete[] bufferfosend; - - - }); - - // 设置Wiper值 - server.on("/setWiper", HTTP_POST, [](AsyncWebServerRequest *request){ - if (request->hasParam("value", true)) { - int wiperValue = request->getParam("value", true)->value().toInt(); - ds3502.setWiper(wiperValue); - request->send(200, "text/plain", "Wiper value set"); - } else { - request->send(400, "text/plain", "Missing value parameter"); - } - }); - - // 清空累计时长 - server.on("/resetDuration", HTTP_POST, [](AsyncWebServerRequest *request){ - runtime.resetActiveDuration(); - request->send(200, "text/plain", "Duration reset"); - }); - - // 灯光控制接口 - server.on("/LightOpen", HTTP_POST, [](AsyncWebServerRequest *request){ - LightOpen(); - request->send(200, "text/plain", "Light ON"); - }); - - server.on("/LightClose", HTTP_POST, [](AsyncWebServerRequest *request){ - LightClose(); - request->send(200, "text/plain", "Light OFF"); - }); - - // 获取灯光状态接口 - server.on("/lightStatus", HTTP_GET, [](AsyncWebServerRequest *request){ - bool isOn = (digitalRead(LIGHT_CONTROL_PIN) == HIGH); // 高电平为开灯 - request->send(200, "text/plain", isOn ? "on" : "off"); - }); - - // 启动自动调节 - server.on("/startAutoAdjust", HTTP_POST, [](AsyncWebServerRequest *request){ - if (request->hasParam("target", true)) { - int targetLux = request->getParam("target", true)->value().toInt(); - if (targetLux > 0) { - lightCtrl.setTargetLight(targetLux); - //lightCtrl.runUntilTargetReached(targetLux, 150); - lightCtrl.adjustToTarget(); - isAutoAdjustEnabled = true; - request->send(200, "text/plain", "Auto adjust started"); - } else { - request->send(400, "text/plain", "Invalid target lux"); - } - } else { - request->send(400, "text/plain", "Missing target parameter"); - } - }); - - // 停止自动调节 - server.on("/stopAutoAdjust", HTTP_POST, [](AsyncWebServerRequest *request){ - isAutoAdjustEnabled = false; - request->send(200, "text/plain", "Auto adjust stopped"); - }); - - // 获取自动调节状态 - server.on("/autoAdjustStatus", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/plain", isAutoAdjustEnabled ? "enabled" : "disabled"); - }); - - // 启动服务器 - server.begin(); -} - - - - -//usb串口打印信息 -// void SerialPrintInfo(void) { -// // 获取温湿度数据 -// dht11.readTemperatureHumidity(temperature, humidity); - -// // 获取光照数据 -// float lightA = bh1750_a.readLightLevel(); -// float lightB = bh1750_b.readLightLevel(); - -// // 获取电流监控数据 -// float busVoltage = INA.getBusVoltage(); -// float shuntVoltage_mV = INA.getShuntVoltage_mV(); -// float current = INA.getCurrent(); -// float power = INA.getPower(); - -// // 打印信息(只使用变量) -// Serial.printf("Temperature: %dC, Humidity: %d%%\n", temperature, humidity); -// Serial.printf("A: %.0f lux :: B: %.0f lux \n", lightA, lightB); - -// Serial.println("\nBUS\tSHUNT\tCURRENT\tPOWER"); -// Serial.printf("%.2f\t%.2f\t%.2f\t%.2f\n", busVoltage, shuntVoltage_mV, current, power); -// } - void SerialPrintInfo(void) { UpdateSensorData(sensorData); @@ -373,7 +223,7 @@ void setup(void) WiFi_Init(); //WebServer 初始化 - WebServer_Init(); + WebServer_Init(server); // 初始化 runtime NVS runtime.begin(); @@ -414,7 +264,6 @@ void loop(void) lastSensorRead = millis(); } - //串口解析tjc控制指令 tjcShow.processSerial(); @@ -427,6 +276,13 @@ void loop(void) if (isAutoAdjustEnabled) { lightCtrl.adjustToTarget(); // 使用新的持续调节函数 } + + server.handleClient(); // 替换webServer->loop() + + if (shouldConnectWiFi) { + connectToWiFi(SSID, Password); + shouldConnectWiFi = false; // 重置标志位 + } } diff --git a/src/mywebserver.cpp b/src/mywebserver.cpp new file mode 100644 index 0000000..626f7df --- /dev/null +++ b/src/mywebserver.cpp @@ -0,0 +1,151 @@ +#include "mywebserver.h" +#include + +#include "SPIFFS.h" + +String getContentType(String filename) +{ + if (filename.endsWith(".htm")) + return "text/html"; + else if (filename.endsWith(".html")) + return "text/html"; + else if (filename.endsWith(".css")) + return "text/css"; + else if (filename.endsWith(".js")) + return "application/javascript"; + else if (filename.endsWith(".png")) + return "image/png"; + else if (filename.endsWith(".gif")) + return "image/gif"; + else if (filename.endsWith(".jpg")) + return "image/jpeg"; + else if (filename.endsWith(".ico")) + return "image/x-icon"; + else if (filename.endsWith(".xml")) + return "text/xml"; + else if (filename.endsWith(".pdf")) + return "application/x-pdf"; + else if (filename.endsWith(".zip")) + return "application/x-zip"; + else if (filename.endsWith(".gz")) + return "application/x-gzip"; + return "text/plain"; +} + + +bool handleFileRead(String path) +{ // 处理浏览器HTTP访问 + + if (path.endsWith("/")) + { // 如果访问地址以"/"为结尾 + path = "/index.html"; // 则将访问地址修改为/index.html便于SPIFFS访问 + } + + String contentType = getContentType(path); // 获取文件类型 + + if (SPIFFS.exists(path)) + { // 如果访问的文件可以在SPIFFS中找到 + File file = SPIFFS.open(path, "r"); // 则尝试打开该文件 + MYSERVER->streamFile(file, contentType); // 并且将该文件返回给浏览器 + file.close(); // 并且关闭文件 + return true; // 返回true + } + return false; // 如果文件未找到,则返回false +} + +void handleUserRequet() +{ + + // 获取用户请求网址信息 + String webAddress = MYSERVER->uri(); + + // 通过handleFileRead函数处处理用户访问 + bool fileReadOK = handleFileRead(webAddress); + + // 如果在SPIFFS无法找到用户访问的资源,则回复404 (Not Found) + if (!fileReadOK) + { + MYSERVER->send(404, "text/plain", "404 Not Found"); + } +} + +// 获取文件类型 + +void founddate(){ + Serial.println("sdfasdfasdf"); + Serial.println(MYSERVER->arg("rolloffset")); + Serial.println(MYSERVER->arg("pitchoffset")); + if (MYSERVER->hasArg("Angle0")) + { + Serial.println(MYSERVER->arg("Angle0")); + /* code */ + } + if (MYSERVER->hasArg("Angle90")) + { + Serial.println(MYSERVER->arg("Angle90")); + /* code */ + } + + Serial.println(MYSERVER->arg("pitchoffset")); +} + + mywebserver::mywebserver() + { + + if(SPIFFS.begin()){ // 启动闪存文件系统 + Serial.println("SPIFFS Started."); + } else { + Serial.println("SPIFFS Failed to Start."); + } + server = new WebServer(80); + server->enableCORS(true); + MYSERVER=server; + server->onNotFound(handleUserRequet); + server->on("/setting",HTTP_GET,founddate); + } + + +mywebserver::mywebserver(int port) +{ + Serial.begin(9600); + if(SPIFFS.begin()){ // 启动闪存文件系统 + Serial.println("SPIFFS Started."); + } else { + Serial.println("SPIFFS Failed to Start."); + } + server = new WebServer(port); + + + + server->enableCORS(true); + MYSERVER=server; + server->sendHeader("Access-Control-Allow-Origin", "*"); + server->sendHeader("Access-Control-Allow-Methods","server->sendHeader"); + + + server->onNotFound(handleUserRequet); + server->on("/setting",HTTP_GET,founddate); + +} + +void mywebserver::loop() +{ + server->handleClient(); +} + +void mywebserver::begin() +{ + server->begin(); + +} + +void mywebserver::on(String str,void *funct()) +{ + server->on(str,funct); +} + + + + + + diff --git a/src/mywebserver.h b/src/mywebserver.h new file mode 100644 index 0000000..70407fe --- /dev/null +++ b/src/mywebserver.h @@ -0,0 +1,25 @@ +#ifndef MYWEBSERVER_H +#define MYWEBSERVER_H +#include +#include + + + + static WebServer *MYSERVER; + + class mywebserver + { + public: + mywebserver(); + WebServer *server; + mywebserver(int port); + void loop(); + void begin(); + void on(String str,void *funct()); + + + private: + }; + + +#endif \ No newline at end of file diff --git a/src/webpages.h b/src/webpages.h deleted file mode 100644 index b796112..0000000 --- a/src/webpages.h +++ /dev/null @@ -1,354 +0,0 @@ -// #ifndef WEBPAGES_H -// #define WEBPAGES_H - -// #include - -// const char index_html[] PROGMEM = R"rawliteral( -// -// -// -// ESP32 Data Display -// -// -// -// -//

实时数据显示

- -//

累计使用时长: 加载中...

-// - -//

温度: 加载中... °C

-//

湿度: 加载中... %RH

-//

光照强度(A): 加载中... lx

-//

光照强度(B): 加载中... lx

-//

电位器Wiper值: 加载中...

-//

总线电压: 加载中... V

-//

分流电压: 加载中... mV

-//

电流: 加载中... A

-//

功率: 加载中... W

- -//

设置Wiper值

-// -// - -//

灯光控制

-//

灯光状态: 加载中...

-// -// - -//

自动调节

-//

状态: 加载中...

-//

目标照度: lux

-// -// -// -// -// )rawliteral"; - -// #endif // WEBPAGES_H - -#ifndef WEBPAGES_H -#define WEBPAGES_H - -#include - -const char index_html[] PROGMEM = R"rawliteral( - - - - ESP32 Data Display - - - - -

实时数据显示

- -

累计使用时长: 加载中...

- - -

温度: 加载中... °C

-

湿度: 加载中... %RH

-

光照强度(A): 加载中... lx

-

光照强度(B): 加载中... lx

-

电位器Wiper值: 加载中...

-

总线电压: 加载中... V

-

分流电压: 加载中... mV

-

电流: 加载中... A

-

功率: 加载中... W

- -

设置Wiper值

- - - -

灯光控制

-

灯光状态: 加载中...

- - - -

自动调节

-

状态: 加载中...

-

目标照度: lux

- - - - -)rawliteral"; - -// 新增 config_html 页面 -const char config_html[] PROGMEM = R"rawliteral( - - - - ESP32 WiFi Setup - - - - -

WiFi 设置

-
-
-

- -
-

- - -
- - -)rawliteral"; - -#endif // WEBPAGES_H \ No newline at end of file