Ich habe versucht einen AP/STA mode so zu programieren das ich ein Capture Portal und gleichzeitigs Auto WPS benutzen kann aber ich bekomme es nicht hin.
ich würde gerne beides berei stellen können.
endweder man verbindet sich mit dem Capture Portal oder man drückt die WPS Taste am router.
Mein Code:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <EEPROM.h>
// ==== AP/Captive Portal ====
const IPAddress apIP(192, 168, 1, 1);
const char* apSSID = "ESP8266 SETUP";
DNSServer dnsServer;
ESP8266WebServer server(80);
// ==== WiFi Credentials ====
char cfgssid[64];
char cfgpassword[64];
// ==== WPS und Config ====
bool wpsActive = false;
bool configMode = true; // Konfigurationsmodus aktiv
// ==== UI/Scan State ====
String ssidList;
// ============================ Hilfsfunktionen ============================
void saveWiFiCredentials(const String& ssid, const String& psk) {
int i = 0;
for (i = 0; i < 256; ++i) {
char c = (i < (int)ssid.length()) ? ssid[i] : 0;
EEPROM.write(i, c);
if (!c) break;
}
for (i = 0; i < 256; ++i) {
char c = (i < (int)psk.length()) ? psk[i] : 0;
EEPROM.write(256 + i, c);
if (!c) break;
}
EEPROM.commit();
}
void loadWiFiCredentials() {
int i = 0;
for (i = 0; i < 256; ++i) {
char c = (char)EEPROM.read(i);
if (c == 0) break;
if (i < (int)sizeof(cfgssid) - 1) cfgssid[i] = c;
}
cfgssid[min(i, (int)sizeof(cfgssid) - 1)] = 0;
for (i = 0; i < 256; ++i) {
char c = (char)EEPROM.read(i + 256);
if (c == 0) break;
if (i < (int)sizeof(cfgpassword) - 1) cfgpassword[i] = c;
}
cfgpassword[min(i, (int)sizeof(cfgpassword) - 1)] = 0;
}
void buildSsidList() {
ssidList = "";
Serial.println("Scanne verfügbare WiFi-Netzwerke...");
// WiFi-Scan im AP_STA Modus
int n = WiFi.scanNetworks();
Serial.print("Gefundene Netzwerke: "); Serial.println(n);
if (n == 0) {
ssidList = "<option value=\"\">Keine Netzwerke gefunden</option>";
} else {
for (int i = 0; i < n; ++i) {
String ssid = WiFi.SSID(i);
if (ssid.length() > 0) { // Leere SSIDs ignorieren
ssidList += "<option value=\"";
ssidList += ssid;
ssidList += "\">";
ssidList += ssid;
ssidList += " (";
ssidList += WiFi.RSSI(i);
ssidList += " dBm)";
ssidList += "</option>";
}
}
}
}
// ============================ Captive Portal & WPS ============================
String urlDecode(String input) {
String s = input;
s.replace("%20", " ");
s.replace("+", " ");
return s;
}
String htmlPage(String title, String body) {
String s = "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>";
s += title;
s += "</title></head><body>";
s += body;
s += "</body></html>";
return s;
}
void startCaptivePortal() {
if (!configMode) return; // Nur im Konfigurationsmodus starten
// AP starten ohne WiFi-Modus zu ändern (bleibt AP_STA)
WiFi.softAP(apSSID);
delay(200);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
dnsServer.start(53, "*", apIP);
// SSID-Liste für Captive Portal erstellen
buildSsidList();
// Hauptseite mit WPS-Status und manueller Konfiguration
server.on("/", HTTP_GET, []() {
if (!configMode) {
server.send(200, "text/html", htmlPage("Konfiguration beendet", "<h1>WiFi bereits konfiguriert</h1>"));
return;
}
String s = "<h1>ESP8266 SETUP</h1>";
s += "<div style='margin: 20px 0;'>";
s += "<a href=\"/settings\" class='button3'>⚙️ Manuelle Wi-Fi Einstellungen</a>";
s += "</div>";
s += "<style>";
s += "html {background-color: #000; color: #fff; display:flex;justify-content:center;align-items:center; font-family: Arial;}";
s += ".button3 {color:#fff;padding:15px 30px;border:none;font-size:16px;background:linear-gradient(to bottom,#bced7f,#99e43c);text-decoration:none;display:inline-block;margin:10px;border-radius:5px;}";
s += "h1 {text-align: center;}";
s += "</style>";
server.send(200, "text/html", htmlPage("ESP8266 Setup", s));
});
// Manuelle WiFi-Einstellungen
server.on("/settings", HTTP_GET, []() {
if (!configMode) {
server.send(200, "text/html", htmlPage("Konfiguration beendet", "<h1>WiFi bereits konfiguriert</h1>"));
return;
}
String s = "<h1>Wi-Fi Einstellungen</h1>";
s += "<form method=\"get\" action=\"/setap\">";
s += "<p>SSID auswählen:</p>";
s += "<select name=\"ssid\" style='width:100%;padding:10px;margin:10px 0;'>" + ssidList + "</select>";
s += "<p>Passwort:</p>";
s += "<input name=\"pass\" type=\"password\" style='width:100%;padding:10px;margin:10px 0;'>";
s += "<p><input type=\"submit\" value=\"Verbinden\" style='padding:15px 30px;font-size:16px;background:linear-gradient(to bottom,#bced7f,#99e43c);border:none;color:#fff;'></p>";
s += "</form>";
s += "<p><a href='/'>← Zurück zur Hauptseite</a></p>";
s += "<style>html {background-color: #000; color: #fff; padding: 20px; font-family: Arial;} a {color: #99e43c;}</style>";
server.send(200, "text/html", htmlPage("Wi-Fi Einstellungen", s));
});
// WiFi-Verbindung testen und speichern
server.on("/setap", HTTP_GET, []() {
if (!configMode) {
server.send(200, "text/html", htmlPage("Konfiguration beendet", "<h1>WiFi bereits konfiguriert</h1>"));
return;
}
String ssid = urlDecode(server.arg("ssid"));
String pass = urlDecode(server.arg("pass"));
String s = "<h1>Verbindung wird getestet...</h1>";
s += "<p>Versuche Verbindung zu: " + ssid + "</p>";
s += "<div id='status'>Bitte warten...</div>";
s += "<script>";
s += "setTimeout(function(){";
s += "document.getElementById('status').innerHTML = 'Verbindung läuft...';";
s += "}, 2000);";
s += "</script>";
s += "<style>html {background-color: #000; color: #fff; text-align: center; font-family: Arial;}</style>";
server.send(200, "text/html", htmlPage("Verbindung testen", s));
// Verbindung im AP_STA Modus testen
WiFi.begin(ssid.c_str(), pass.c_str());
unsigned long startAttemptTime = millis();
bool connected = false;
while (millis() - startAttemptTime < 15000) {
if (WiFi.status() == WL_CONNECTED) {
connected = true;
break;
}
delay(500);
if (configMode) { // Nur bedienen wenn noch im Konfigurationsmodus
server.handleClient();
dnsServer.processNextRequest();
}
}
if (connected) {
Serial.println("Manuelle WiFi-Verbindung erfolgreich!");
Serial.print("Verbunden mit: "); Serial.println(ssid);
Serial.print("IP-Adresse: "); Serial.println(WiFi.localIP());
// Konfigurationsmodus beenden
configMode = false;
wpsActive = false;
// WiFi-Credentials speichern
saveWiFiCredentials(ssid, pass);
// Captive Portal und DNS Server stoppen
server.stop();
dnsServer.stop();
WiFi.softAPdisconnect(true);
Serial.println("Konfigurationsmodus beendet - WPS und Captive Portal deaktiviert");
delay(2000);
ESP.restart();
} else {
// Fehlgeschlagen - zurück zur Einstellungsseite
WiFi.disconnect();
server.sendHeader("Location", String("http://") + apIP.toString() + "/settings", true);
server.send(302, "text/plain", "");
}
});
server.onNotFound([]() {
if (configMode) {
server.sendHeader("Location", String("http://") + apIP.toString() + "/", true);
server.send(302, "text/plain", "");
} else {
server.send(404, "text/plain", "Not Found");
}
});
server.begin();
Serial.println("Captive Portal gestartet. Verbinde dich mit '" + String(apSSID) + "' und öffne 192.168.1.1");
}
void startWPS() {
if (!configMode || WiFi.status() == WL_CONNECTED) {
return;
}
if (!wpsActive) {
Serial.println("Starte WPS...");
Serial.println("WPS läuft dauerhaft bis zur erfolgreichen Verbindung");
// WPS im AP_STA Modus starten (Push Button Mode)
WiFi.beginWPSConfig();
wpsActive = true;
Serial.println("WPS aktiviert - drücke WPS-Button am Router innerhalb von 2 Minuten");
}
}
void checkWPS() {
if (!configMode) return;
int status = WiFi.status();
Serial.print("WiFi Status während WPS: "); Serial.println(status);
if (status == WL_CONNECTED) {
String newSSID = WiFi.SSID();
if (newSSID.length() > 0) {
Serial.println("WPS erfolgreich - Konfiguration gespeichert!");
Serial.print("Verbunden mit: "); Serial.println(newSSID);
Serial.print("IP-Adresse: "); Serial.println(WiFi.localIP());
// Konfigurationsmodus beenden
configMode = false;
wpsActive = false;
// WiFi-Credentials speichern, inkl. PSK wenn verfügbar
String psk = WiFi.psk();
saveWiFiCredentials(newSSID, psk.length() > 0 ? psk : "");
// Captive Portal und DNS Server stoppen
server.stop();
dnsServer.stop();
WiFi.softAPdisconnect(true);
Serial.println("Konfigurationsmodus beendet - WPS und Captive Portal deaktiviert");
delay(2000);
ESP.restart();
} else {
Serial.println("WPS SSID leer - Verbindung ungültig");
}
} else if (status == WL_NO_SSID_AVAIL || status == WL_CONNECT_FAILED) {
// WPS fehlgeschlagen, versuche neu zu starten
if (wpsActive) {
Serial.println("WPS fehlgeschlagen, starte neu in 10 Sekunden...");
wpsActive = false;
delay(10000);
startWPS(); // Neu starten
}
}
}
void tryConnectSTA() {
if (strlen(cfgssid) > 0) {
Serial.print("Versuche Verbindung mit gespeichertem SSID: ");
Serial.println(cfgssid);
WiFi.begin(cfgssid, cfgpassword);
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < 10000) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nVerbunden mit gespeicherten Credentials!");
Serial.print("IP-Adresse: "); Serial.println(WiFi.localIP());
configMode = false;
} else {
Serial.println("\nVerbindung mit gespeicherten Credentials fehlgeschlagen");
configMode = true;
}
} else {
Serial.println("Keine WiFi-Credentials gespeichert");
Serial.println("Starte Konfigurationsmodus: WPS + Captive Portal");
configMode = true;
startWPS(); // WPS automatisch starten
}
}
// ============================ Setup & Loop ============================
void setup() {
Serial.begin(115200);
EEPROM.begin(512);
delay(10);
loadWiFiCredentials();
WiFi.mode(WIFI_AP_STA);
tryConnectSTA(); // Zuerst versuchen zu verbinden
if (configMode) {
startWPS(); // WPS sofort starten
startCaptivePortal(); // Captive Portal starten
// Konfigurationsmodus: Warten bis WiFi verbunden ist
Serial.println("Warte auf WiFi-Konfiguration...");
while (configMode) {
server.handleClient();
dnsServer.processNextRequest();
checkWPS();
delay(500); // Etwas längere Pause für WPS (bis zu 2 Min pro Versuch)
}
Serial.println("WiFi konfiguriert - starte normalen Betrieb");
delay(2000); // Kurz warten vor Neustart
ESP.restart(); // Neustart für sauberen Übergang
}
// Hier angekommen bedeutet: WiFi ist verbunden, normaler Betrieb kann starten
Serial.println("Setup abgeschlossen - WiFi verbunden");
Serial.print("SSID: "); Serial.println(WiFi.SSID());
Serial.print("IP: "); Serial.println(WiFi.localIP());
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi-Verbindung verloren - versuche Reconnect");
WiFi.reconnect();
delay(5000);
}
delay(1000);
}
Endschuldigung dafür das in meinem Text viele fehler sind.
Leide leider an Legasthenie.
Hoffendlich kann mir jemand helfen oder hat eine gute Idee wie ich es umsetzen kann.
Vielen Dank
