From 1c2201afc9bf662b5f9f5c244502b3a954939abf Mon Sep 17 00:00:00 2001 From: chenxin Date: Wed, 12 Feb 2025 11:38:33 +0800 Subject: [PATCH] tpl0401a --- platformio.ini | 2 +- src/DigitalPot.cpp | 24 ++++++ src/DigitalPot.h | 19 +++++ src/RunTime.cpp | 5 +- src/RunTime.h | 1 + src/TJC_Show.cpp | 87 +++++++++++---------- src/TJC_Show.h | 22 +++--- src/WebServer.cpp | 94 +++++++++++++++++++++++ src/WebServer.h | 18 +++++ src/WiFiControl.cpp | 17 +++++ src/WiFiControl.h | 19 +++++ src/main.cpp | 181 +++++++++----------------------------------- src/webpages.h | 99 ++++++++++++++++++++++++ 13 files changed, 392 insertions(+), 196 deletions(-) create mode 100644 src/DigitalPot.cpp create mode 100644 src/DigitalPot.h create mode 100644 src/WiFiControl.cpp create mode 100644 src/WiFiControl.h create mode 100644 src/webpages.h diff --git a/platformio.ini b/platformio.ini index 0c8ba31..916fe35 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ platform = http://111.198.24.44:11080/v6.5.0.zip board = esp32-s3-devkitc-1 framework = arduino lib_deps = - esphome/ESPAsyncWebServer-esphome@^3.3.0 robtillaart/INA226@^0.6.0 robtillaart/DS18B20@^0.2.4 + esphome/ESPAsyncWebServer-esphome@^3.3.0 monitor_speed = 115200 diff --git a/src/DigitalPot.cpp b/src/DigitalPot.cpp new file mode 100644 index 0000000..df0bcfa --- /dev/null +++ b/src/DigitalPot.cpp @@ -0,0 +1,24 @@ +#include "DigitalPot.h" + +TPL0401A::TPL0401A(uint8_t i2cAddress) : _i2cAddress(i2cAddress) +{ +} + +uint16_t TPL0401A::writeWiper(uint16_t wiperValue) { + Wire1.beginTransmission(0x2E); // device address TPL04001-A #46 (0x2E), TPL04001-B #46 (0x2E) + Wire1.write(byte(0x00)); // sends instruction. 0x00 = Write + Wire1.write(wiperValue); // sends value + Wire1.endTransmission(); // end transmission + + _wiperValue = wiperValue; // 更新成员变量 + + // Print the current pot value + Serial.print("pot: "); + Serial.println(wiperValue); + + return wiperValue; +} + +uint16_t TPL0401A::readWiperValue() const { + return _wiperValue; +} \ No newline at end of file diff --git a/src/DigitalPot.h b/src/DigitalPot.h new file mode 100644 index 0000000..cfcaa2d --- /dev/null +++ b/src/DigitalPot.h @@ -0,0 +1,19 @@ +#ifndef DIGITALPOT_H +#define DIGITALPOT_H + +#include "Wire.h" +#include + +class TPL0401A { + public: + TPL0401A(uint8_t i2cAddress); + uint16_t writeWiper(uint16_t wiperValue); + uint16_t readWiperValue() const; + private: + uint8_t _i2cAddress; + uint16_t _wiperValue; + }; + + extern TPL0401A digiPot; + +#endif diff --git a/src/RunTime.cpp b/src/RunTime.cpp index ec02d1b..b1a8c65 100644 --- a/src/RunTime.cpp +++ b/src/RunTime.cpp @@ -1,5 +1,5 @@ #include "RunTime.h" -#include + RunTime runtime; @@ -12,7 +12,8 @@ void RunTime::begin() { activeDuration = preferences.getULong("activeDuration", 0); // 从 NVS 加载数据 } -void RunTime::checkCurrent() { +void RunTime::checkCurrent() //时长判定 +{ float current = INA.getBusVoltage(); if (current > 10.0) { if (!isActive) { diff --git a/src/RunTime.h b/src/RunTime.h index 21e0ee3..5f44044 100644 --- a/src/RunTime.h +++ b/src/RunTime.h @@ -2,6 +2,7 @@ #define RUNTIME_H #include "INA226.h" +#include #include class RunTime { diff --git a/src/TJC_Show.cpp b/src/TJC_Show.cpp index abbe491..badf38c 100644 --- a/src/TJC_Show.cpp +++ b/src/TJC_Show.cpp @@ -2,52 +2,63 @@ extern RunTime runtime; +extern TPL0401A digiPot; +extern uint16_t wiperValue; -TJC_Show::TJC_Show(HardwareSerial& serial, DS18B20& sensor, BH1750& bh1750_a, BH1750& bh1750_b, MCP45HVX1& digiPot, INA226& INA) - : _serial(serial), _sensor(sensor), _bh1750_a(bh1750_a), _bh1750_b(bh1750_b), _digiPot(digiPot), _INA(INA) {} +TJC_Show::TJC_Show(DS18B20& ds18b20, BH1750& bh1750_a, BH1750& bh1750_b, TPL0401A& digiPot, INA226& INA) + : _serial(TJC_SERIAL), _ds18b20(ds18b20), _bh1750_a(bh1750_a), _bh1750_b(bh1750_b), _digiPot(digiPot), _INA(INA) {} - -// 陶晶池串口屏初始化 -void TJC_Show::TJC_Show_Init() -{ - _serial.begin(115200, SERIAL_8N1, TJC_RX_Pin, TJC_TX_Pin); - while (_serial.read() >= 0); // 清空串口缓冲区 - _serial.print("page main\xff\xff\xff"); // 跳转到 main 页面 -} - -// 陶晶池串口屏显示二维码 -void TJC_Show::showQR() -{ - char addr[64]; - IPAddress ip = WiFi.localIP(); - sprintf(addr, "qr0.txt=\"http://%d.%d.%d.%d/\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]); - _serial.print(addr); +void TJC_Show::init() { + _serial.begin(115200, SERIAL_8N1, TJC_RX_PIN, TJC_TX_PIN); + clearSerialBuffer(); + sendCommand("page main\xff\xff\xff"); } -//陶晶池串口屏发送 -void TJC_Show::showINFO(unsigned long activeDuration) { +void TJC_Show::showQR() { + 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(addr, sizeof(addr), "qr0.txt=\"http://%d.%d.%d.%d/\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]); + sendCommand(addr); +} + +void TJC_Show::showInfo() { char str[128]; - sprintf(str, "t0.txt=\"%.2f\"\xff\xff\xff", _sensor.getTempC()); - _serial.print(str); + snprintf(str, sizeof(str), "t0.txt=\"%.2f\"\xff\xff\xff", _ds18b20.getTempC()); + sendCommand(str); - sprintf(str, "t1.txt=\"%.f\"\xff\xff\xff", _bh1750_a.readLightLevel()); - _serial.print(str); - sprintf(str, "t2.txt=\"%.f\"\xff\xff\xff", _bh1750_b.readLightLevel()); - _serial.print(str); + snprintf(str, sizeof(str), "t1.txt=\"%.f\"\xff\xff\xff", _bh1750_a.readLightLevel()); + sendCommand(str); + snprintf(str, sizeof(str), "t2.txt=\"%.f\"\xff\xff\xff", _bh1750_b.readLightLevel()); + sendCommand(str); - sprintf(str, "t14.txt=\"%s\"\xff\xff\xff", runtime.formatDuration(runtime.getActiveDuration())); - _serial.print(str); + snprintf(str, sizeof(str), "t14.txt=\"%s\"\xff\xff\xff", runtime.formatDuration(runtime.getActiveDuration())); + sendCommand(str); - sprintf(str, "t8.txt=\"%d\"\xff\xff\xff", _digiPot.readWiper()); - _serial.print(str); + snprintf(str, sizeof(str), "t8.txt=\"%d\"\xff\xff\xff", _digiPot.readWiperValue()); + sendCommand(str); - sprintf(str, "t9.txt=\"%.3f\"\xff\xff\xff", _INA.getBusVoltage(), 3); - _serial.print(str); - sprintf(str, "t10.txt=\"%.3f\"\xff\xff\xff", _INA.getShuntVoltage_mV(), 3); - _serial.print(str); - sprintf(str, "t11.txt=\"%.3f\"\xff\xff\xff", _INA.getCurrent_mA(), 3); - _serial.print(str); - sprintf(str, "t12.txt=\"%.3f\"\xff\xff\xff", _INA.getPower_mW(), 3); - _serial.print(str); + snprintf(str, sizeof(str), "t9.txt=\"%.3f\"\xff\xff\xff", _INA.getBusVoltage()); + sendCommand(str); + snprintf(str, sizeof(str), "t10.txt=\"%.3f\"\xff\xff\xff", _INA.getShuntVoltage_mV()); + sendCommand(str); + snprintf(str, sizeof(str), "t11.txt=\"%.3f\"\xff\xff\xff", _INA.getCurrent_mA()); + sendCommand(str); + snprintf(str, sizeof(str), "t12.txt=\"%.3f\"\xff\xff\xff", _INA.getPower_mW()); + sendCommand(str); +} + +void TJC_Show::clearSerialBuffer() { + while (_serial.read() >= 0); // 清空串口缓冲区 +} + +void TJC_Show::sendCommand(const char* command) { + _serial.print(command); } \ No newline at end of file diff --git a/src/TJC_Show.h b/src/TJC_Show.h index 1db1637..fc61e4a 100644 --- a/src/TJC_Show.h +++ b/src/TJC_Show.h @@ -4,30 +4,32 @@ #include #include "BH1750.h" #include "DS18B20.h" -#include "MCP45HVX1.h" +#include "DigitalPot.h" #include "INA226.h" #include #include "RunTime.h" -//陶晶池串口屏 -#define TJC Serial1 -#define TJC_TX_Pin 42 -#define TJC_RX_Pin 41 +// 定义陶晶池串口屏的串口和引脚 +#define TJC_SERIAL Serial1 +#define TJC_TX_PIN 42 +#define TJC_RX_PIN 41 class TJC_Show { public: - TJC_Show(HardwareSerial& serial, DS18B20& sensor, BH1750& bh1750_a, BH1750& bh1750_b, MCP45HVX1& digiPot, INA226& INA); - void TJC_Show_Init(); + TJC_Show(DS18B20& ds18b20, BH1750& bh1750_a, BH1750& bh1750_b, TPL0401A& digiPot, INA226& INA); + void init(); void showQR(); - void showINFO(unsigned long activeDuration); + void showInfo(); private: HardwareSerial& _serial; - DS18B20& _sensor; + DS18B20& _ds18b20; BH1750& _bh1750_a; BH1750& _bh1750_b; - MCP45HVX1& _digiPot; + TPL0401A& _digiPot; INA226& _INA; + void clearSerialBuffer(); + void sendCommand(const char* command); }; #endif // TJC_SHOW_H \ No newline at end of file diff --git a/src/WebServer.cpp b/src/WebServer.cpp index e69de29..1934cb4 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -0,0 +1,94 @@ +// #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 index e69de29..6ade132 100644 --- a/src/WebServer.h +++ b/src/WebServer.h @@ -0,0 +1,18 @@ +#ifndef WEBSERVER_H +#define WEBSERVER_H + +#include "webpages.h" // 包含 HTML 页面内容 +#include +#include +#include "DS18B20.h" +#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 new file mode 100644 index 0000000..5bd4e1a --- /dev/null +++ b/src/WiFiControl.cpp @@ -0,0 +1,17 @@ +#include "WiFiControl.h" +void WiFi_Init() +{ + #if SELECTED_WIFI_MODE == WIFI_MODE_STA + WiFi.begin(STA_SSID, STA_PASSWORD); // WiFi + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + Serial.println("Connecting to WiFi..."); + } + Serial.print("Address: "); + Serial.println(WiFi.localIP()); + #elif SELECTED_WIFI_MODE == WIFI_MODE_AP + WiFi.softAP(AP_SSID, AP_PASSWORD); + Serial.print("AP IP address: "); + Serial.println(WiFi.softAPIP()); + #endif +} \ No newline at end of file diff --git a/src/WiFiControl.h b/src/WiFiControl.h new file mode 100644 index 0000000..cef4935 --- /dev/null +++ b/src/WiFiControl.h @@ -0,0 +1,19 @@ +#include + +#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" + +// AP模式下的SSID和密码 +#define AP_SSID "APSSID" +#define AP_PASSWORD "APPassword" + +void WiFi_Init(void); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d8791d2..6029808 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,8 +3,6 @@ #include "Wire.h" #include #include -//#include "TCJ_Show.h" -//#include "ESP32_WebServer.h" #include #include "MCP45HVX1.h" #include "INA226.h" @@ -12,26 +10,29 @@ #include // 用于存储非易失性数据 #include "TJC_Show.h" #include "RunTime.h" - +#include "WebServer.h" +#include "WiFiControl.h" +#include "DigitalPot.h" // Ticker 用于定时检查电流状态 Ticker currentCheckTicker; // MCP45HVX1 数字电位器 -MCP45HVX1 digiPot(0x3E); +MCP45HVX1 mcp45hvx1(0x3C); + +//TPL0401A 数字电位器 +TPL0401A digiPot(0x2E); // INA226 电流监控器 INA226 INA(0x40); AsyncWebServer server(80); -const char* ssid = "SERVIRST-CT"; -const char* password = "servirst8888"; // DS18B20 温度传感器 -#define ONE_WIRE_BUS 8 -OneWire oneWire(ONE_WIRE_BUS); +#define DS18B20_PIN 8 +OneWire oneWire(DS18B20_PIN); DS18B20 ds18b20(&oneWire); BH1750 bh1750_a; @@ -46,171 +47,56 @@ BH1750 bh1750_b; #define BUZZER_PIN 17 extern RunTime runtime; -int activeDuration; Preferences prefs; -// HTML 页面内容 -const char index_html[] PROGMEM = R"rawliteral( - - - - ESP32 Data Display - - - - -

实时数据显示

-

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

- -

温度: 加载中... °C

-

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

-

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

-

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

-

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

-

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

-

电流: 加载中... mA

-

功率: 加载中... mW

-

设置Wiper值

- - - - - )rawliteral"; - - - // 初始化Web -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()); +void WebServer_Init(void) { // 根路径的页面 - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) - { + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { request->send_P(200, "text/html", index_html); }); // 温度接口 - server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request) - { + 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) - { + 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) - { + 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()); + server.on("/wiper", HTTP_GET, [](AsyncWebServerRequest *request) { + String wiper = String(digiPot.readWiperValue()); request->send(200, "text/plain", wiper); }); - server.on("/busVoltage", HTTP_GET, [](AsyncWebServerRequest *request) - { + 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) - { + 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) - { + 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) - { + server.on("/power", HTTP_GET, [](AsyncWebServerRequest *request) { String power = String(INA.getPower_mW(), 3); request->send(200, "text/plain", power); }); @@ -238,7 +124,6 @@ void WebServer_Init(const char* ssid, const char* password) }); server.begin(); - //Serial.println("Web server started"); } @@ -265,7 +150,7 @@ void Buzzer(void) { } -TJC_Show tjcShow(TJC, ds18b20, bh1750_a, bh1750_b, digiPot, INA); +TJC_Show tjcShow(ds18b20, bh1750_a, bh1750_b, digiPot, INA); void setup(void) @@ -275,14 +160,15 @@ void setup(void) // 初始化 I2C 总线 Wire.begin(5, 4); // SDA SCL + mcp45hvx1.begin(5, 4); + // INA226 初始化 INA.setMaxCurrentShunt(10.0, 0.005); // 设置最大电流和分流电阻 // MCP45HVX1 初始化 - digiPot.begin(5, 4); + //digiPot.begin(5, 4); // 启动定时器,每秒检查电流状态 - //currentCheckTicker.attach(1, checkCurrent); currentCheckTicker.attach(1, []() { runtime.checkCurrent(); }); //sensor.begin(); @@ -292,22 +178,26 @@ void setup(void) Wire1.begin(36, 35); bh1750_a.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire); bh1750_b.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire1); + + //WiFi 初始化 + WiFi_Init(); //WebServer 初始化 - WebServer_Init(ssid, password); + WebServer_Init(); // 初始化 runtime NVS runtime.begin(); // 串口屏初始化 - tjcShow.TJC_Show_Init(); - + tjcShow.init(); tjcShow.showQR(); + + digiPot.writeWiper(30); } void loop(void) -{// put your main code here, to run repeatedly: +{ ds18b20.printTemperature(); //ds18b20温度 //printLightLevels(bh1750_a, bh1750_b); //bh1750照度 @@ -317,9 +207,10 @@ void loop(void) // MCP45HVX1 操作 //digiPot.writeWiper(127); // 随机设置 Wiper 值,random(0, 256) - + mcp45hvx1.writeWiper(random(0, 127)); Serial.print("Current Wiper Value: "); - Serial.println(digiPot.readWiper()); + Serial.println(mcp45hvx1.readWiper()); + // INA226 数据读取 Serial.println("\nBUS\tSHUNT\tCURRENT\tPOWER"); @@ -333,7 +224,7 @@ void loop(void) Serial.println(); - tjcShow.showINFO(activeDuration); //串口屏 + tjcShow.showInfo(); //串口屏 FansControl(); diff --git a/src/webpages.h b/src/webpages.h new file mode 100644 index 0000000..d75827f --- /dev/null +++ b/src/webpages.h @@ -0,0 +1,99 @@ +#ifndef WEBPAGES_H +#define WEBPAGES_H + +#include + +const char index_html[] PROGMEM = R"rawliteral( + + + + ESP32 Data Display + + + + +

实时数据显示

+

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

+ +

温度: 加载中... °C

+

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

+

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

+

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

+

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

+

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

+

电流: 加载中... mA

+

功率: 加载中... mW

+

设置Wiper值

+ + + + +)rawliteral"; // 添加分号 + +#endif // WEBPAGES_H \ No newline at end of file