From b3c2aadbdbe97838fd10907df497e7e1e14d6e87 Mon Sep 17 00:00:00 2001 From: M-Factory Date: Wed, 18 Feb 2026 17:06:25 +0900 Subject: [PATCH] ESPTimeCast Firmware 1.0.1 - Patch Release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • ESP32 auto pin handling: Improved board detection and automatic MAX7219 pin configuration for ESP32 variants. • Reliable Web UI update mechanism: Replaced size-only validation of /index.html with content comparison to ensure HTML updates correctly, even when file size remains unchanged. • AP-mode SSID/Password bug: Saving in AP mode now preserves the correct SSID and password, preventing the device from getting stuck in AP mode. • AP-mode loop refactor: Display animation and web server handling optimized for better responsiveness and stability. • Web UI updates: factory_reset and upload endpoints updated to match the new design. Small UI improvements. ⸻ Notes: • Users experiencing AP-mode issues should reselect their WiFi and re-enter their password once to restore STA mode. • Patch release only; no new features added. --- ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino | 72 +++++++++++++++++---- ESPTimeCast_ESP32/index_html.h | 2 + ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino | 36 ++++++++--- ESPTimeCast_ESP8266/index_html.h | 2 + 4 files changed, 92 insertions(+), 20 deletions(-) diff --git a/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino b/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino index 49fcbfb..ffa9f3f 100644 --- a/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino +++ b/ESPTimeCast_ESP32/ESPTimeCast_ESP32.ino @@ -20,12 +20,40 @@ #include "months_lookup.h" // Languages for the Months of the Year #include "index_html.h" // Web UI -#define HARDWARE_TYPE MD_MAX72XX::FC16_HW -#define MAX_DEVICES 4 +// ============================ +// Board-specific MAX7219 pin mapping +// ============================ +#if defined(CONFIG_IDF_TARGET_ESP32S2) +// ESP32-S2 Mini #define CLK_PIN 7 #define CS_PIN 11 #define DATA_PIN 12 +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +// ESP32-S3 WROOM / Camera board +#define CLK_PIN 18 +#define CS_PIN 16 +#define DATA_PIN 17 + +#elif defined(CONFIG_IDF_TARGET_ESP32C3) +// ESP32-C3 Super Mini +#define CLK_PIN 7 +#define CS_PIN 20 +#define DATA_PIN 8 + +#elif defined(ESP32) +// Default ESP32 boards (DevKit, WROOM, etc) +#define CLK_PIN 18 +#define CS_PIN 23 +#define DATA_PIN 5 + +#else +#error "Unsupported board!" +#endif + +#define HARDWARE_TYPE MD_MAX72XX::FC16_HW +#define MAX_DEVICES 4 + #ifdef ESP8266 WiFiEventHandler mConnectHandler; WiFiEventHandler mDisConnectHandler; @@ -2406,9 +2434,9 @@ void setup() { esp_log_level_set("esp_littlefs", ESP_LOG_NONE); Serial.println(); Serial.println(F("[SETUP] Starting setup...")); -#if defined(ARDUINO_USB_MODE) +#if defined(ARDUINO_USB_MODE) || defined(USB_SERIAL) Serial.setTxTimeoutMs(50); - Serial.println("[SERIAL] USB CDC detected — TX timeout enabled"); + Serial.println(F("[SERIAL] USB CDC detected — TX timeout enabled")); delay(500); #endif Serial.println(F("[FS] Mounting LittleFS (auto-format enabled)...")); @@ -2520,17 +2548,37 @@ void ensureHtmlFileExists() { if (!f) { Serial.println(F("[FS] ERROR: /index.html exists but failed to open! Will rewrite.")); } else { - size_t actualSize = f.size(); - f.close(); - if (actualSize == expectedSize) { - Serial.printf("[FS] /index.html found (size OK: %u bytes). Using file system version.\n", actualSize); - return; // STOP HERE — file is good + bool identical = true; + + for (size_t i = 0; i < expectedSize; i++) { + if (!f.available()) { + identical = false; + break; + } + + char fileChar = f.read(); + char progChar = pgm_read_byte_near(index_html + i); + + if (fileChar != progChar) { + identical = false; + break; + } } - Serial.printf( - "[FS] /index.html size mismatch! Expected %u bytes, found %u. Rewriting...\n", - expectedSize, actualSize); + // Also check if file has extra trailing bytes + if (f.available()) { + identical = false; + } + + f.close(); + + if (identical) { + Serial.printf("[FS] /index.html content identical (%u bytes). Using file system version.\n", expectedSize); + return; + } + + Serial.println(F("[FS] /index.html content differs. Rewriting...")); } } else { Serial.println(F("[FS] /index.html NOT found. Writing embedded content to LittleFS...")); diff --git a/ESPTimeCast_ESP32/index_html.h b/ESPTimeCast_ESP32/index_html.h index 37aece7..ad9af2b 100644 --- a/ESPTimeCast_ESP32/index_html.h +++ b/ESPTimeCast_ESP32/index_html.h @@ -535,6 +535,8 @@ opacity: 0.5; user-select: none; margin-top: 6rem; text-decoration: underline; + text-decoration-thickness: 1px; + text-underline-offset: 2px; } .collapsible-toggle .icon-area { diff --git a/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino b/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino index 85a652b..10e8d36 100644 --- a/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino +++ b/ESPTimeCast_ESP8266/ESPTimeCast_ESP8266.ino @@ -2503,17 +2503,37 @@ void ensureHtmlFileExists() { if (!f) { Serial.println(F("[FS] ERROR: /index.html exists but failed to open! Will rewrite.")); } else { - size_t actualSize = f.size(); - f.close(); - if (actualSize == expectedSize) { - Serial.printf("[FS] /index.html found (size OK: %u bytes). Using file system version.\n", actualSize); - return; // STOP HERE — file is good + bool identical = true; + + for (size_t i = 0; i < expectedSize; i++) { + if (!f.available()) { + identical = false; + break; + } + + char fileChar = f.read(); + char progChar = pgm_read_byte_near(index_html + i); + + if (fileChar != progChar) { + identical = false; + break; + } } - Serial.printf( - "[FS] /index.html size mismatch! Expected %u bytes, found %u. Rewriting...\n", - expectedSize, actualSize); + // Also check if file has extra trailing bytes + if (f.available()) { + identical = false; + } + + f.close(); + + if (identical) { + Serial.printf("[FS] /index.html content identical (%u bytes). Using file system version.\n", expectedSize); + return; + } + + Serial.println(F("[FS] /index.html content differs. Rewriting...")); } } else { Serial.println(F("[FS] /index.html NOT found. Writing embedded content to LittleFS...")); diff --git a/ESPTimeCast_ESP8266/index_html.h b/ESPTimeCast_ESP8266/index_html.h index 37aece7..ad9af2b 100644 --- a/ESPTimeCast_ESP8266/index_html.h +++ b/ESPTimeCast_ESP8266/index_html.h @@ -535,6 +535,8 @@ opacity: 0.5; user-select: none; margin-top: 6rem; text-decoration: underline; + text-decoration-thickness: 1px; + text-underline-offset: 2px; } .collapsible-toggle .icon-area {