diff --git a/include/ad7606.h b/include/ad7606.h index 8be2a19..0472176 100644 --- a/include/ad7606.h +++ b/include/ad7606.h @@ -9,10 +9,10 @@ namespace ad7606 { // 数据/控制引脚 static const int PIN_AD_MISO = 8; // DOUTA -> ESP32 MISO -static const int PIN_AD_CS = 12; // CS_N +static const int PIN_AD_CS = 39; // CS_N static const int PIN_AD_CONVST = 13; // CONVST(CO-A/CO-B 共用) -static const int PIN_AD_RESET = 5; // RESET -static const int PIN_AD_BUSY = 14; // BUSY +static const int PIN_AD_RESET = 40; // RESET +static const int PIN_AD_BUSY = 38; // BUSY // 可选:过采样和模式引脚(-1 表示不配置/已硬件固定) static const int PIN_AD_OS0 = -1; diff --git a/include/init.h b/include/init.h index 6ff47fa..35f3a10 100644 --- a/include/init.h +++ b/include/init.h @@ -2,6 +2,7 @@ #define INIT_H #include +#include #include namespace esp32 { @@ -17,7 +18,7 @@ bool loadSettings(); void connectWiFi(); // 初始化系统 -void initSystem(Adafruit_ST7735& tft); +void initSystem(Adafruit_ST7735& tft, U8G2_FOR_ADAFRUIT_GFX& u8g2); // 获取后端接口 URL(来自 settings.json) const String& getBackendUrl(); diff --git a/src/init.cpp b/src/init.cpp index 04538a0..4cf97b6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -14,15 +14,19 @@ static String backendUrl = ""; // TFT 显示器引用 (在 initSystem 中设置) static Adafruit_ST7735* tftPtr = nullptr; +static U8G2_FOR_ADAFRUIT_GFX* u8g2Ptr = nullptr; // 在屏幕上打印日志 void tftLog(const char* msg, uint16_t color) { - if (tftPtr == nullptr) + if (tftPtr == nullptr || u8g2Ptr == nullptr) return; - tftPtr->setTextColor(color); - tftPtr->println(msg); - tftPtr->setCursor(tftPtr->getCursorX(), - tftPtr->getCursorY() + 2); // 增加2像素行距 + u8g2Ptr->setForegroundColor(color); + int16_t x = tftPtr->getCursorX(); + int16_t y = tftPtr->getCursorY(); + u8g2Ptr->setCursor(x, y); + u8g2Ptr->print(msg); + // 更新光标位置,准备下一行(中文字体高度约14像素) + tftPtr->setCursor(0, y + 14); } // 读取并解析配置文件 @@ -55,7 +59,7 @@ bool loadSettings() { wifiPassword = doc["wifi"]["password"].as(); // 读取后端接口(可选) - if (doc.containsKey("backend")) { + if (doc["backend"].is() && doc["backend"]["url"].is()) { backendUrl = doc["backend"]["url"].as(); } if (backendUrl.isEmpty()) { @@ -63,9 +67,8 @@ bool loadSettings() { backendUrl = "http://nf.xn--876a.net/api/data"; } - tftLog("Config loaded:", GREEN); - tftPtr->print(" SSID: "); - tftLog(wifiSSID.c_str(), WHITE); + tftLog("配置已加载:", GREEN); + tftLog((" SSID: " + wifiSSID).c_str(), WHITE); return true; } @@ -77,35 +80,40 @@ void connectWiFi() { return; } - tftPtr->print("Connecting: "); - tftLog(wifiSSID.c_str(), WHITE); + tftLog(("连接 WiFi: " + wifiSSID).c_str(), WHITE); WiFi.mode(WIFI_STA); WiFi.begin(wifiSSID.c_str(), wifiPassword.c_str()); int attempts = 0; + int16_t x = tftPtr->getCursorX(); + int16_t y = tftPtr->getCursorY(); while (WiFi.status() != WL_CONNECTED && attempts < 20) { delay(500); - tftPtr->print("."); + u8g2Ptr->setCursor(x + attempts * 6, y); + u8g2Ptr->print("."); attempts++; } - tftPtr->println(); + tftPtr->setCursor(0, y + 14); if (WiFi.status() == WL_CONNECTED) { - tftLog("WiFi connected!", GREEN); - tftPtr->print("IP: "); - tftLog(WiFi.localIP().toString().c_str(), WHITE); + tftLog("WiFi 已连接!", GREEN); + tftLog(("IP: " + WiFi.localIP().toString()).c_str(), WHITE); } else { - tftLog("WiFi failed!", RED); + tftLog("WiFi 连接失败!", RED); } } // 初始化系统 -void initSystem(Adafruit_ST7735& tft) { +void initSystem(Adafruit_ST7735& tft, U8G2_FOR_ADAFRUIT_GFX& u8g2) { tftPtr = &tft; + u8g2Ptr = &u8g2; + tft.setCursor(0, tft.getCursorY() + 14); - tftLog("=== ESP32-S3 ===", YELLOW); - tft.println(); + tftLog("=== 欢迎使用 ESP32 ===", YELLOW); + tftLog("微弱压力数据采集系统", YELLOW); + + tft.setCursor(0, tft.getCursorY() + 14); // 读取配置文件并连接 WiFi if (loadSettings()) { @@ -114,7 +122,9 @@ void initSystem(Adafruit_ST7735& tft) { } // 提供后端 URL 给外部使用 -const String& getBackendUrl() { return backendUrl; } +const String& getBackendUrl() { + return backendUrl; +} } // namespace init } // namespace esp32 diff --git a/src/main.cpp b/src/main.cpp index b280333..3d2001f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,6 +69,9 @@ struct AppState { char statusMsg[64]; uint32_t statusUntilMs = 0; uint16_t statusColor = WHITE; + + // 帮助界面 + bool helpMode = false; }; static UI appUI; @@ -153,9 +156,9 @@ static void postRecording(AppState& s) { } payload += "]"; // 附带录制起止时间(毫秒) - payload += ",\"startTime\":"; + payload += ",\"recStartMs\":"; payload += String(s.recStartMs); - payload += ",\"endTime\":"; + payload += ",\"recEndMs\":"; payload += String(s.recEndMs); if (s.fitReady) { payload += ",\"fit\":{\"a\":"; @@ -190,11 +193,7 @@ static void postRecording(AppState& s) { } if (ok) { s.statusColor = GREEN; - if (idStr.length()) - snprintf(s.statusMsg, sizeof(s.statusMsg), "上传成功\nID:%s", - idStr.c_str()); - else - snprintf(s.statusMsg, sizeof(s.statusMsg), "上传成功"); + snprintf(s.statusMsg, sizeof(s.statusMsg), "上传成功"); s.statusUntilMs = millis() + 3000; } else { s.statusColor = RED; @@ -215,6 +214,29 @@ static void buildScene(void* ctx, DisplayList& out) { // 背景整屏清除 out.addFillRect(1, 0, 0, SCREEN_W, SCREEN_H, BLACK); + // 帮助界面 + if (st->helpMode) { + out.addText(2, SCREEN_W / 2, 14, YELLOW, "帮助 / 操作说明", true); + + uint16_t normal = WHITE; + uint16_t hint = esp32::utils::rgbTo565(0x80E1FF); + int y = 34; + out.addText(10, SCREEN_W / 2, y, normal, "左键: 录制开始/停止", true); y += 16; + out.addText(11, SCREEN_W / 2, y, normal, "停止后自动上传", true); y += 16; + out.addText(12, SCREEN_W / 2, y, normal, "右键: 标定并切换档位", true); y += 16; + out.addText(13, SCREEN_W / 2, y, normal, "≥2点后显示 mN 拟合", true); y += 16; + out.addText(14, SCREEN_W / 2, y, normal, "上键: 打开/关闭帮助", true); y += 22; + out.addText(15, SCREEN_W / 2, y, hint, "按 上键 返回主界面", true); + + // 底部上传状态提示(临时显示) + uint32_t nowMs = millis(); + if (st->statusUntilMs > nowMs && st->statusMsg[0] != '\0') { + out.addText(400, SCREEN_W / 2, SCREEN_H - 10, st->statusColor, + st->statusMsg, true); + } + return; + } + // 第一行:显示原始码 并在拟合可用时附加 mN char line[64]; if (st->fitReady) { @@ -427,13 +449,13 @@ void setup() { // u8g2_font_wqy12_t_chinese1: 12像素,常用汉字(约2500字) // u8g2_font_wqy12_t_chinese2: 12像素,更多汉字(约6000字) // u8g2_font_wqy12_t_chinese3: 12像素,完整汉字(约9000字) - u8g2.setFont(u8g2_font_wqy12_t_chinese3); // 12像素字体,比 unifont 小 + u8g2.setFont(u8g2_font_wqy12_t_gb2312); // 12像素字体,比 unifont 小 tft.setTextColor(WHITE); tft.setTextSize(1); // 初始化系统(读取配置并连接 WiFi) - init::initSystem(tft); + init::initSystem(tft, u8g2); // UI 初始化,传入 u8g2 以支持中文 appUI.begin(&tft, &u8g2); @@ -496,8 +518,8 @@ void loop() { } } - // BTN_RIGHT:记录当前电压到当前档位,并循环到下一档 - if (rightPressed && !prevRight) { + // BTN_RIGHT:记录当前电压到当前档位,并循环到下一档(帮助界面下无效) + if (!app.helpMode && rightPressed && !prevRight) { float c = (float)app.lastRaw; int idx = app.presetIdx; app.capturedCode[idx] = c; @@ -533,8 +555,8 @@ void loop() { app.presetIdx = (app.presetIdx + 1) % 4; } - // 左键:开始/停止录制,停止后上传 - if (leftPressed && !prevLeft) { + // 左键:开始/停止录制,停止后上传(帮助界面下无效) + if (!app.helpMode && leftPressed && !prevLeft) { if (!app.recActive) { app.recActive = true; app.recLen = 0; @@ -546,6 +568,11 @@ void loop() { postRecording(app); } } + + // 上键:打开/关闭帮助界面(任意界面有效) + if (upPressed && !prevUp) { + app.helpMode = !app.helpMode; + } // printf("l:%s, r:%s, u:%s\n", leftPressed ? "Y" : "N", rightPressed ? "Y" // : "N", upPressed ? "Y" : "N"); 驱动 UI 帧刷新