Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WiFiWebManager

Ein umfassendes ESP32-Framework für WLAN-Management mit Web-Interface, das robuste Verbindungsverwaltung, erweiterbares Web-UI und persistente Datenspeicherung bietet.

🚀 Features

  • Intelligente WLAN-Verbindung: 3-Versuch-System mit automatischem Fallback zu AP-Modus
  • Reset-Button Support: Hardware-Reset über GPIO 0 (3s = WLAN Reset, 10s = Vollreset)
  • Automatischer Reconnect: Überwachung und Wiederherstellung verlorener Verbindungen
  • Erweiterbares Web-Interface: Einfaches Hinzufügen eigener Konfigurationsseiten
  • Custom Data API: Persistente Speicherung verschiedener Datentypen
  • Debug-Modus: Ein/ausschaltbare Debug-Ausgaben für Entwicklung
  • OTA-Updates: Firmware-Updates über Web-Interface, mit Anzeige der App-Version auf der Update-Seite (setFirmwareVersion)
  • WLAN-Status-LED (optional): adressierbare On-Board-RGB-LED (WS2812) zeigt den Verbindungsstatus (grün/gelb/rot, AP = rot blinkend) — Pin frei wählbar, per Funktion ein-/ausschaltbar
  • Responsive Design: Modernes Web-UI für Desktop und Mobile

📦 Installation

Arduino IDE Library Manager

  1. Öffnen Sie Arduino IDE
  2. Gehen Sie zu Sketch > Include Library > Manage Libraries
  3. Suchen Sie nach "WiFiWebManager"
  4. Klicken Sie auf Install

Manuelle Installation

  1. Laden Sie die neueste Version von Releases
  2. Entpacken Sie die ZIP-Datei in Ihren Arduino/libraries Ordner
  3. Starten Sie Arduino IDE neu

🛠️ Abhängigkeiten

Dieses Framework benötigt:

  • ESPAsyncWebServer (wird automatisch installiert)
  • AsyncTCP (Abhängigkeit von ESPAsyncWebServer)

📖 Quick Start

#include <WiFiWebManager.h>

WiFiWebManager wifiManager;

void setup() {
    Serial.begin(115200);
    
    // Optional: Debug-Modus aktivieren
    wifiManager.setDebugMode(true);
    
    // Optional: Standard-Hostname setzen
    wifiManager.setDefaultHostname("MeinESP32");

    // Optional: Version, die auf der /update-Seite angezeigt wird
    wifiManager.setFirmwareVersion("1.0.0");
    
    wifiManager.begin();
}

void loop() {
    wifiManager.loop(); // WICHTIG: Muss aufgerufen werden!
}

🌐 Web-Interface

Nach dem Start ist das Web-Interface verfügbar unter:

Standard-Seiten:

  • / - Status und Übersicht (kann vom Inhalt angepasst werden)
  • /wlan - WLAN-Konfiguration (fix)
  • /ntp - NTP-Einstellungen (fix)
  • /update - OTA-Firmware-Update; zeigt Version (fix)
  • /reset - Reset-Optionen (fix)

🔧 Erweiterte Nutzung

Eigene Seiten hinzufügen (Die Namen für die Standard-Seiten sind reserviert)

// Einfache GET-Seite
wifiManager.addPage("Meine Seite", "/custom", 
    [](AsyncWebServerRequest *request) -> String {
        return "<h1>Benutzerdefinierte Seite</h1><p>Ihr Inhalt hier</p>";
    }
);

// Seite mit GET und POST
wifiManager.addPage("Einstellungen", "/settings", 
    // GET Handler
    [](AsyncWebServerRequest *request) -> String {
        String html = "<h1>Einstellungen</h1>";
        html += "<form action='/settings' method='POST'>";
        html += "<input name='wert' placeholder='Wert eingeben'>";
        html += "<input type='submit' value='Speichern'>";
        html += "</form>";
        return html;
    },
    // POST Handler
    [](AsyncWebServerRequest *request) -> String {
        String wert = request->getParam("wert", true)->value();
        // Wert verarbeiten...
        return "<p>Gespeichert: " + wert + "</p><a href='/settings'>Zurück</a>";
    }
);

Custom Data verwenden (Key max. 13 Zeichen)

// Verschiedene Datentypen speichern
wifiManager.saveCustomData("deviceName", "Sensor1");        // String
wifiManager.saveCustomData("interval", 5000);               // int
wifiManager.saveCustomData("enabled", true);                // bool
wifiManager.saveCustomData("calibration", 1.25f);           // float

// Daten laden mit Default-Werten
String name = wifiManager.loadCustomData("deviceName", "Standard");
int interval = wifiManager.loadCustomDataInt("interval", 1000);
bool enabled = wifiManager.loadCustomDataBool("enabled", false);
float calib = wifiManager.loadCustomDataFloat("calibration", 1.0);

// Existenz prüfen und löschen
if (wifiManager.hasCustomData("oldValue")) {
    wifiManager.removeCustomData("oldValue");
}

🔘 Reset-Button (GPIO 0)

Verbinden Sie einen Taster zwischen GPIO 0 und GND:

  • 3-10 Sekunden drücken: Nur WLAN-Daten löschen
  • >10 Sekunden drücken: Kompletter Werks-Reset

🐛 Debug-Modus

// Debug-Modus aktivieren (nur über Code möglich)
wifiManager.setDebugMode(true);

// Status abfragen
bool isDebugActive = wifiManager.getDebugMode();

💡 WLAN-Status-LED (optional)

Viele ESP32-S3-Boards haben eine adressierbare On-Board-RGB-LED (WS2812). Der WiFiWebManager kann darauf den WLAN-Status spiegeln — standardmäßig deaktiviert, per Funktion mit frei wählbarem Pin einschaltbar. Kein zusätzlicher Treiber nötig (nutzt neopixelWrite() aus dem ESP32-Core).

Farbe Bedeutung
🟢 grün verbunden, gute Feldstärke (RSSI ≥ Schwelle, Default −70 dBm)
🟡 gelb verbunden, schwache Feldstärke
🔴 rot Verbindung verloren / (noch) kein STA-Connect
🔴 rot blinkend AP-Setup-Modus (ESP32_SETUP)
void setup() {
    wifiManager.enableStatusLed(48);       // aktivieren + GPIO (z. B. 48 beim S3-DevKitC-1)
    // optional:
    wifiManager.setStatusLedBrightness(40);      // 0..255 (Default 40)
    wifiManager.setStatusLedRssiThreshold(-70);  // Grenze gut/schwach (dBm)
    wifiManager.setStatusLedSelfTest(true);      // Boot-Selbsttest rot/grün/blau
    wifiManager.begin();
}

Ein-/Ausschalten und Pin lassen sich auch zur Laufzeit ändern:

wifiManager.disableStatusLed();     // LED aus
wifiManager.enableStatusLed(38);    // wieder an, jetzt an GPIO 38

🧵 FreeRTOS-Service-Task + Watchdog (ab v3.0.0)

Ab v3.0.0 erledigt die Lib ihre Wartung (Reset-Button, OTA-Handle, Status-LED, WLAN-Scan/-Reconnect, OTA-Stall-Check) standardmäßig in einer eigenen FreeRTOS-Task wfwm_svc (Core 1, weg von WiFi/lwIP). Damit blockieren WLAN-Scan/-Reconnect nicht mehr deinen loop().

Rückwärtskompatibel: Die öffentliche loop() bleibt bestehen und wird zum No-Op, solange die Service-Task läuft — bestehende Sketches, die loop() aufrufen, funktionieren unverändert weiter.

// Optional VOR begin():
wifiManager.setServiceTask(false);   // exakt bisheriges Verhalten (du rufst loop() selbst)

Task-Watchdog (Default AN)

Die Lib bringt einen Task-Watchdog mit und überwacht damit nur die Service-Task — ein langer Consumer-loop() löst also keinen Reset aus. Die Reset-Ursache wird beim Boot geloggt (u. a. klar als WATCHDOG-RESET).

// Optional VOR begin():
wifiManager.enableWatchdog(true, 30, true);  // an, Timeout 30 s, panic=true (Default)
wifiManager.enableWatchdog(false);           // aus

// Eigene Consumer-Tasks einhängen (statt selbst mit esp_task_wdt zu hantieren):
wifiManager.watchdogAddCurrentTask();     // aktuelle Task eintragen
wifiManager.watchdogFeedCurrentTask();    // füttern
wifiManager.watchdogRemoveCurrentTask();  // austragen

OTA-Selbstheilung bei abgebrochenem Upload

Reißt ein /update-Upload mittendrin ab (gestörtes WLAN), kommt der final-Chunk nie. Optional erkennt die Service-Task diesen Stillstand und startet nach einem Timeout sauber neu (intakte alte Firmware wiederhergestellt). Default AUS (0) — die Lib bricht einen laufenden OTA dann nie selbst ab. Mit ms > 0 aktivierbar (Empfehlung ≥ 20000):

wifiManager.setOtaStallTimeout(20000);   // ms; 0 = AUS (Default)

OTA unter Last (Nebenläufigkeit) + quiesce-Muster

Betreibt der Consumer viele eigene FreeRTOS-Tasks (Netz-/CPU-Last), soll der OTA-Empfang trotzdem zuverlässig laufen. Die Lib unterstützt das doppelt:

  • Automatische Service-Task-Pause: Sobald ein OTA startet, nimmt sich die Lib-eigene Service-Task aus dem Watchdog und pausiert, bis der OTA fertig ist — sie konkurriert dann nicht mit dem AsyncTCP-Empfang.
  • quiesce-Muster für den Consumer: setOnUpdateStart() (vor dem ersten Flash-Write) und das Gegenstück setOnUpdateEnd(success) (am Ende) erlauben es, eigene Tasks für die Dauer des OTA generisch anzuhalten und danach wieder freizugeben:
volatile bool pause = false;
void myTask(void*) { for(;;){ if(!pause){ /* Arbeit */ } vTaskDelay(pdMS_TO_TICKS(10)); } }

wifiManager.setOnUpdateStart([]()        { pause = true;  /* Peripherie stoppen */ });
wifiManager.setOnUpdateEnd  ([](bool ok) { pause = false; /* Betrieb wieder freigeben */ });

Hinweis: Reißt ein /update wirklich ab und ist die Selbstheilung AUS, endet der OTA nicht sauber → onUpdateEnd feuert dann nicht. Für automatische Freigabe in diesem Fall setOtaStallTimeout(ms>0) setzen.

„ESP neu starten"

Die /reset-Seite hat jetzt oben einen grünen Button „ESP neu starten" — reiner Neustart ohne Datenverlust (nützlich z. B. um nach einem abgebrochenen OTA die Peripherie zurückzuholen).


📋 API-Referenz

Basis-Funktionen

void begin();                    // Initialisierung
void loop();                     // Hauptschleife (in loop() aufrufen!)
void reset();                    // Software-Reset

Hostname-Management

void setDefaultHostname(const String& hostname);  // Standard setzen
String getHostname();                             // Aktuellen abrufen

Firmware-Version

void setFirmwareVersion(const String& version);   // Version für /update-Seite setzen

Einmal in setup() aufrufen, damit die Firmware-Version im Web-UI sichtbar ist:

wifiManager.setFirmwareVersion("1.0.0");

OTA-Callbacks (Peripherie/Tasks um den Flash herum steuern)

void setOnUpdateStart(std::function<void()> cb);            // vor dem ersten Flash-Write
void setOnUpdateEnd(std::function<void(bool success)> cb);  // am Ende (Erfolg/Abbruch)

onUpdateStart wird direkt vor dem ersten Flash-Schreiben aufgerufen (bei /update UND ArduinoOTA/espota) — hier störende Peripherie (z. B. Kamera-Treiber/DMA) stoppen. onUpdateEnd(success) ist das Gegenstück am Ende: success=true nach erfolgreichem Flash (kurz vor dem Neustart), false bei Fehler/Abbruch — hier die eigenen Tasks/Peripherie wieder freigeben (quiesce-Muster, siehe „OTA unter Last"):

wifiManager.setOnUpdateStart([]()        { camera.deinit(); });
wifiManager.setOnUpdateEnd  ([](bool ok) { /* Tasks wieder freigeben */ });

Debug-Funktionen

void setDebugMode(bool enabled);  // Debug ein/aus
bool getDebugMode();              // Status abrufen

WLAN-Status-LED

void enableStatusLed(uint8_t pin, uint8_t brightness = 40);  // aktivieren + Pin
void disableStatusLed();                                     // ausschalten
void setStatusLedPin(uint8_t pin);                           // Pin neu zuweisen
void setStatusLedBrightness(uint8_t brightness);             // 0..255
void setStatusLedRssiThreshold(int dbm);                     // gut/schwach, Default -70
void setStatusLedSelfTest(bool enabled);                     // Boot-Selbsttest

Seiten-Management

void addPage(const String& titel, const String& pfad, 
             ContentHandler getHandler, 
             ContentHandler postHandler = nullptr);
void removePage(const String& pfad);

Custom Data API

// Speichern
void saveCustomData(const String& key, const String& value);
void saveCustomData(const String& key, int value);
void saveCustomData(const String& key, bool value);
void saveCustomData(const String& key, float value);

// Laden
String loadCustomData(const String& key, const String& defaultValue = "");
int loadCustomDataInt(const String& key, int defaultValue = 0);
bool loadCustomDataBool(const String& key, bool defaultValue = false);
float loadCustomDataFloat(const String& key, float defaultValue = 0.0);

// Verwaltung
bool hasCustomData(const String& key);
void removeCustomData(const String& key);
std::vector<String> getCustomDataKeys();  // Alle gespeicherten Custom-Keys auflisten

⚠️ Wichtige Hinweise

  • WICHTIG: wifiManager.loop() muss in der loop() Funktion aufgerufen werden
  • Custom Data: Verwenden Sie keine reservierten Schlüssel (ssid, pwd, hostname, etc.)
  • Performance: Debug-Modus nur bei Bedarf aktivieren
  • Reset-Button: GPIO 0 ist standardmäßig der Boot-Button auf den meisten ESP32-Boards

🔗 Beispiele

Siehe /examples Ordner für vollständige Beispiele:

  • Basic - Grundlegende Nutzung
  • Test - Custom Pages, Custom Data und Debug-Ausgaben (Demo mit simulierten Werten)
  • ServiceTaskWatchdog - v3.0.0-Features: Service-Task, Watchdog, OTA-Selbstheilung, eigene überwachte Task

📝 Changelog

Version Datum Beschreibung
3.1.0 2026-09-21 OTA unter Last / Nebenläufigkeit: neue API setOnUpdateEnd(bool success) als Gegenstück zu setOnUpdateStart() (quiesce-Muster: eigene Tasks bei OTA-Start anhalten, bei Ende/Abbruch freigeben).
Die Lib-eigene Service-Task pausiert jetzt echt während eines OTA (nimmt sich aus dem Watchdog + schläft), statt im 10-ms-Takt zu konkurrieren.
Auf HW verifiziert: 2-MB-/update läuft unter Multi-Task-Last (CPU beide Cores + lwIP-Sättigung) komplett durch.
3.0.2 2026-09-21 OTA-Empfang weiter gehärtet: kein Geräte-Reboot mehr bei ArduinoOTA-Fehler (espota rebootete zuvor u. U. schon im Handshake → „No response"); ArduinoOTA.handle() wird alle 10 ms gepollt.
OTA-Selbstheilung standardmäßig AUS (setOtaStallTimeout(0)): ein laufender /update wird nie mehr selbst abgebrochen; Recovery nur auf Wunsch (setOtaStallTimeout(ms>0), empfohlen ≥ 20000).
/update-Fortschrittsdiagnose (alle 64 KB) bei aktivem Debug.
3.0.1 2026-09-21 Fix OTA-Empfang (Regression aus 3.0.0): Service-Task läuft auf Core 1 (weg von WiFi/lwIP/AsyncTCP auf Core 0); Service-Task hält sich während eines OTA komplett zurück (kein Scan/Reconnect/LED/Reset-Button); Watchdog-Fütterung während espota via onProgress; Stall-Timeout-Default 8 s → 20 s.
3.0.0 2026-09-17 FreeRTOS-Service-Task (wfwm_svc, Default AN; öffentliche loop() wird No-Op, setServiceTask(false) für altes Verhalten); Task-Watchdog (Default AN) + Reset-Ursache-Log beim Boot; OTA-Selbstheilung per Stall-Timeout (setOtaStallTimeout); „ESP neu starten"-Button auf /reset; Fix: Checkboxen/Radios links neben dem Text. MAJOR (Laufzeitverhalten ändert sich, quellcode-kompatibel).
2.2.0 2026-09-15 setOnUpdateStart() — Pre-Flash-Callback, um störende Peripherie vor einem OTA zu stoppen.
2.1.0 2026-09-03 Optionale WLAN-Status-LED (WS2812) via enableStatusLed().

📄 Lizenz

MIT License - siehe LICENSE für Details.

🤝 Beitragen

Beiträge sind willkommen! Bitte eröffnen Sie ein Issue oder einen Pull Request auf GitHub.

📞 Support

📊 Systemanforderungen

  • Hardware: ESP32 (alle Varianten)
  • RAM: ~50KB für Framework + Webserver
  • Flash: ~200KB für Code + Web-Assets
  • Arduino Core: ESP32 v2.0.0 oder höher

WiFiWebManager Library - Funktions Referenz

📋 Grundlegende Methoden

Funktion Beschreibung Parameter Rückgabe
WiFiWebManager() Konstruktor - initialisiert Reset-Button (GPIO 0) - -
begin() Startet WiFiWebManager, verbindet WiFi oder startet AP - void
loop() Muss in main loop() aufgerufen werden - void
reset() Führt kompletten Werks-Reset durch - void

🌐 Netzwerk-Konfiguration

Funktion Beschreibung Parameter Rückgabe
setDefaultHostname(hostname) Setzt Standard-Hostname aus Code String hostname void
getHostname() Gibt aktuellen Hostname zurück - String
setFirmwareVersion(version) App-Version auf der /update-Seite String version void

Werks-Reset erfolgt über die öffentliche Methode reset() (siehe Grundlegende Methoden). WLAN-only- bzw. Voll-Reset lassen sich zusätzlich über den Hardware-Reset-Button (GPIO 0) auslösen.

📄 Custom Pages (Webseiten)

Funktion Beschreibung Parameter Rückgabe
addPage(title, path, getHandler) Fügt GET-only Seite hinzu String title, String path, ContentHandler getHandler void
addPage(title, path, getHandler, postHandler) Fügt Seite mit GET und POST hinzu String title, String path, ContentHandler getHandler, ContentHandler postHandler void
removePage(path) Entfernt Custom Page String path void

💾 Custom Data API

Speichern (Setter)

Funktion Beschreibung Parameter Einschränkungen
saveCustomData(key, value) Speichert String-Wert String key, String value Key max. 13 Zeichen
saveCustomData(key, value) Speichert Integer-Wert String key, int value Key max. 13 Zeichen
saveCustomData(key, value) Speichert Boolean-Wert String key, bool value Key max. 13 Zeichen
saveCustomData(key, value) Speichert Float-Wert String key, float value Key max. 13 Zeichen

Laden (Getter)

Funktion Beschreibung Parameter Rückgabe
loadCustomData(key, defaultValue) Lädt String-Wert String key, String defaultValue = "" String
loadCustomDataInt(key, defaultValue) Lädt Integer-Wert String key, int defaultValue = 0 int
loadCustomDataBool(key, defaultValue) Lädt Boolean-Wert String key, bool defaultValue = false bool
loadCustomDataFloat(key, defaultValue) Lädt Float-Wert String key, float defaultValue = 0.0 float

Verwaltung

Funktion Beschreibung Parameter Rückgabe
hasCustomData(key) Prüft ob Key existiert String key bool
removeCustomData(key) Löscht gespeicherten Wert String key void
getCustomDataKeys() Gibt alle Custom Keys zurück - std::vector<String>

🛠️ Debug & Utilities

Funktion Beschreibung Parameter Rückgabe
setDebugMode(enabled) Aktiviert/deaktiviert Debug-Ausgaben bool enabled void
getDebugMode() Gibt Debug-Status zurück - bool

⚠️ Wichtige Einschränkungen

🔑 Key-Einschränkungen

  • Maximale Länge: 13 Zeichen
  • Reservierte Keys (können nicht verwendet werden):
    • ssid, pwd, hostname
    • useStaticIP, ip, gateway, subnet, dns
    • ntpEnable, ntpServer, bootAttempts

🔄 Boot-Attempt System

  • Max. 3 Verbindungsversuche bei WiFi-Fehlern
  • Nach 3 fehlgeschlagenen Versuchen → automatischer AP-Modus
  • Erfolgreiche Verbindung setzt Counter zurück

🔧 Hardware Reset-Button (GPIO 0)

Druckdauer Aktion
3-10 Sekunden Nur WiFi-Daten löschen
>10 Sekunden Kompletter Werks-Reset

📝 Beispiel-Code

#include "WiFiWebManager.h"

WiFiWebManager wwm;

// Custom Page Handler
String handleMyPage(AsyncWebServerRequest *request) {
    return "<h1>Meine Seite</h1><p>Status: " + 
           wwm.loadCustomData("status", "OK") + "</p>";
}

void setup() {
    Serial.begin(115200);
    
    // Hostname setzen
    wwm.setDefaultHostname("MeinESP32");
    
    // Debug aktivieren
    wwm.setDebugMode(true);
    
    // Custom Page hinzufügen
    wwm.addPage("Status", "/status", handleMyPage);
    
    // Custom Data speichern (Key max. 13 Zeichen!)
    wwm.saveCustomData("temp_max", 25.5f);
    wwm.saveCustomData("alerts", true);
    wwm.saveCustomData("count", 42);
    
    wwm.begin();
}

void loop() {
    wwm.loop();
    
    // Custom Data laden
    float maxTemp = wwm.loadCustomDataFloat("temp_max", 20.0f);
    bool alertsOn = wwm.loadCustomDataBool("alerts", false);
}

🌍 Standard-Webseiten

Das System stellt automatisch folgende Seiten bereit:

  • / - Home/Status-Übersicht
  • /wlan - WiFi-Konfiguration
  • /ntp - NTP-Zeitserver Einstellungen
  • /update - OTA Firmware-Update
  • /reset - Reset-Optionen

About

Ein vielseitiges, modernes ESP32-WebGUI Framework mit WLAN-, Hostname-, IP- und NTP-Verwaltung, OTA-Update und Werksreset. Optimiert für die Integration von eigene Projekte – vollständig steuerbar per Webinterface.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages