Bonjour à tous
la réponse positive et l’intérêt général pour le blog précédent via un Portail captif, m’a amené à écrire un autre blog spécial sur le sujet et d’aborder certains des points et souhaits de vous en détail. Parmi beaucoup d’autres questions détaillées que je vais aborder plus tard, le désir était d’utiliser le portail captif non seulement sur un ESP8266, mais aussi sur le ESP32 ESP32 Courir. Ce n’est pas possible natif. Pour ce faire, certains changements, en particulier des bibliothèques utilisées, doivent être apportés. Le code d’aujourd’hui ne fonctionne donc que sur l’ESP32. Dans le détail, en plus des ajustements de la bibliothèque, certaines optimisations ont été ajoutées spécifiquement pour l’ESP32.
Certains lecteurs du blog peuvent avoir constaté que l’ESP ne pouvait plus correctement renouer avec un point d’accès après qu’il a été redémarré. J’ai pu rétablir ce bogue après une longue recherche. Ceci est probablement en combinaison avec certains points d’accès, dans lequel ESP est rejeté en dépit des données d’accès WLAN correctes lors de la connexion au point d’accès svond et par conséquent passe du mode de la station à son propre mode de point d’accès. Dans ce processus, les données d’accès précédentes de l’ALAN sont supprimées de l’EEPROM (telle est l’intention).
La solution pour ce bogue côté système est d’essayer la connexion à plusieurs reprises en dépit de soi-disant "mauvais" données d’accès avant de revenir au mode point d’accès.
Comme autre petite amélioration, l’adresse IP actuelle, quel que soit le mode dans lequel se trouve l’ESP32, est sortie sur l’interface sérielle. Donc, si vous souhaitez sortir cette adresse IP sur votre écran, vous n’avez qu’à modifier la sortie à l’endroit correspondant dans le code.
Afin d’être compatible avec de nombreux conseils d’administration de l’ESP dans la mesure du possible, je continue de me passer de la production des statistiques aux ports extérieurs de l’ESP.
Toujours dans cette partie, l’ESP32 s’accumule avec notre code portail captif ultérieur Portail captif Sur. Le Wi-Fi a le nom "ESP_Config" et le mot de passe "12345678". Avec cela, nous pouvons nous connecter à notre téléphone mobile, et sont ensuite automatiquement dirigés à partir du téléphone mobile vers le site Web De Portail Captif. Cela correspond essentiellement à la partie précédente dans la conception et la fonctionnalité.
Sur ce site, nous pouvons maintenant cliquer sur le lien système "WiFi Paramètres" et maintenant nous arrivons à une page de configuration WLAN complète, avec laquelle nous pouvons maintenant sélectionner à la fois un réseau avec lequel l’ESP32 devrait se connecter:
Le réseau sans fil sélectionné ici et le mot de passe saisi sont stockés dans l’EEPROM. Sur le bateau suivant, l’ESP32 tente de se connecter à ce réseau. Si cela échoue, après plusieurs tentatives, par exemple, parce que le réseau n’est plus accessible ou que le mot de passe a été modifié, l’ESP retourne en mode point d’accès et attend une reconfiguration.
Le code personnalisé pour le portail captif pour l’ESP32 est :
[
#include <Wifi.H (en)> #include <WiFiClient (WiFiClient).H (en)> #include <Web.H (en)> #include <ESPmDNS (EN ANGLAIS).H (en)> #include <DNSServateur.H (en)> #include <Eeprom.H (en)> #define GPIO_OUT_W1TS_REG (DR_REG_GPIO_BASE + 0x0008) #define GPIO_OUT_W1TC_REG (DR_REG_GPIO_BASE + 0x000c) Statique Const Octet WiFiPwdLen (WiFiPwdLen) = 25; Statique Const Octet APSTANameLen = 20; Struct WiFiEEPromData { Bool APSTA APSTA = Vrai; Mode Point d’accès ou Station - vrai mode AP Bool PwDReq (en) = Faux; Mot de passeRequired Bool CapPortal (CapPortal) = Vrai ; CaptivePortal en mode AP Char Char APSTAName APSTAName[APSTANameLen]; STATION /AP Point Name TO conneCT, s’il est déca fondé Char Char WiFiPwd (WiFiPwd)[WiFiPwdLen (WiFiPwdLen)]; WiFiPAssword, s’il est défini Char Char ConfigValid[3]; Si Config est Vaild, tag "TK" est nécessaire" }; / nom d’hôte pour mDNS. Devrait travailler au moins sur les fenêtres. Essayer http://esp8266.local */ Const Char Char *ESPHostname ESPHostname = "ESP32"; Serveur DNS Const Octet DNS_PORT = 53; DNSServateur dnsServateur; Conmmon Paramenters Bool SoftAccOK (en) = Faux; Serveur Web Webserver Serveur(80); /Paramètres du réseau AP doux // Ipaddress apIP(172, 20, 0, 1); Ipaddress netMsk netMsk (en)(255, 255, 255, 0); Unsigned Long currentMillis = 0; Unsigned Long startMillis; /- Statut WLAN actuel // Court Statut = WL_IDLE_STATUS; WiFiEEPromData MyWiFiConfig (en); String Temp =""; Vide Configuration() { REG_WRITE(GPIO_OUT_W1TS_REG, Peu(GPIO_NUM_16)); Ensemble d’assainissement d’erreur de méditation De gourou Retard(1); REG_WRITE(GPIO_OUT_W1TC_REG, Peu(GPIO_NUM_16)); Guru Méditation Erreur d’assainissement clair Bool ConnectSuccess = Faux; Bool CréerSoftAPSucc = Faux; Bool CInitFSSystem (en) = Faux; Bool CInitHTTPServateur = Faux; Octet Len; Série.Commencer(9600); Tandis que (!Série) { ; attendre que le port en série se connecte. Nécessaire pour l’USB natif } Série.println(F("Serial Interface initalisé au 9600 Baud.")); Wifi.setAutoReconnect (Faux); Wifi.Persistante(Faux); Wifi.Débrancher(); Wifi.setHostname setHostname(ESPHostname ESPHostname); Réglez le nom d’hôte DHCP affecté à la station ESP. Si (chargeCredentials()) Chargez les informations d’identification WLAN pour les paramètres WiFi { Série.println(F("Qualifications valides trouvées.")); Si (MyWiFiConfig (en).APSTA APSTA == Vrai) AP Mode { Série.println(F("Mode point d’accès sélectionné.")); Série.println(MyWiFiConfig (en).APSTA APSTA); Len = Strlen(MyWiFiConfig (en).APSTAName APSTAName); MyWiFiConfig (en).APSTAName APSTAName[Len+1] = '\0'; Len = Strlen(MyWiFiConfig (en).WiFiPwd (WiFiPwd)); MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Len+1] = '\0'; CréerSoftAPSucc = CréerWifiSoftAP(); } Autre { Série.println(F("Mode Station sélectionné.")); Len = Strlen(MyWiFiConfig (en).APSTAName APSTAName); MyWiFiConfig (en).APSTAName APSTAName[Len+1] = '\0'; Len = Strlen(MyWiFiConfig (en).WiFiPwd (WiFiPwd)); MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Len+1] = '\0'; Len = ConnectWifiAP (en)(); Si ( Len == 3 ) { ConnectSuccess = Vrai; } Autre { ConnectSuccess = Faux; } } } Autre { Définir par défaut Config - Créer AP Série.println(F("Aucun titre d’identification valide trouvé.")); SetDefaultWiFiConfig (); CréerSoftAPSucc = CréerWifiSoftAP(); saveCredentials (en)(); Retard(500); } Si ((ConnectSuccess Ou CréerSoftAPSucc)) { Série.Imprimer (F("Adresse IP: ")); Si (CréerSoftAPSucc) { Série.println(Wifi.softAPIP softAPIP());} Si (ConnectSuccess) { Série.println(Wifi.localIP());} InitalizeHTTPServer(); } Autre { Série.setDebugOutput(Vrai); Debug Sortie pour WLAN sur Serial Interface. Série.println(F("Erreur: Ne peut pas se connecter à WLAN. Définissez la configuration DEFAULT.")); SetDefaultWiFiConfig(); CréerSoftAPSucc = CréerWifiSoftAP(); InitalizeHTTPServer(); SetDefaultWiFiConfig(); saveCredentials (en)(); } } Vide InitalizeHTTPServer() { Bool initok = Faux; /- Configuration des pages Web: racine, pages config wifi, détecteurs de portails captifs SO et non trouvé. */ Serveur.Sur("/", handleRoot); Serveur.Sur("/wifi", poignéeWifi); Si (MyWiFiConfig (en).CapPortal (CapPortal)) { Serveur.Sur("/generate_204", handleRoot); } Portail captif Android. Peut-être pas né cessaire. Peut être manipulé par nonFound gestionnaire. Si (MyWiFiConfig (en).CapPortal (CapPortal)) { Serveur.Sur("/favicon.ico", handleRoot); } Un autre portail captif Android. Peut-être pas né cessaire. Peut être manipulé par nonFound gestionnaire. Vérifié sur Sony Handy Si (MyWiFiConfig (en).CapPortal (CapPortal)) { Serveur.Sur("/fwlink", handleRoot); } Portail captif Microsoft. Peut-être pas né cessaire. Peut être manipulé par nonFound gestionnaire. server.on ("/generate_204", handleRoot); Portail captif Android. Peut-être pas né cessaire. Peut être manipulé par nonFound gestionnaire. server.on ("/favicon.ico", handleRoot); Un autre portail captif Android. Peut-être pas né cessaire. Peut être manipulé par nonFound gestionnaire. Vérifié sur Sony Handy server.on ("/fwlink", handleRoot); Portail captif Microsoft. Peut-être pas né cessaire. Peut être manipulé par nonFound gestionnaire. Serveur.onNotFound ( poignéeNotFound ); Speicherung Header-Elemente anfordern server.collectHeaders(Headers, sizeof(Headers)/ sizeof(Headers[0]); Serveur.Commencer(); Démarrage du serveur Web } Boolean CréerWifiSoftAP() { Wifi.Débrancher(); Série.Imprimer(F("Initalize SoftAP")); Si (MyWiFiConfig (en).PwDReq (en)) { SoftAccOK (en) = Wifi.softAP (softAP)(MyWiFiConfig (en).APSTAName APSTAName, MyWiFiConfig (en).WiFiPwd (WiFiPwd)); Passwortlànge mindestens 8 Zeichen ! } Autre { SoftAccOK (en) = Wifi.softAP (softAP)(MyWiFiConfig (en).APSTAName APSTAName); Point d’accès sans mot de passe Fonction de surcharge:; WiFi.softAP (ssid, mot de passe, canal, caché) } Retard(2000); Sans délai, j’ai vu l’adresse IP vide Wifi.softAPConfig (en)(apIP, apIP, netMsk netMsk (en)); Si (SoftAccOK (en)) { /Configuration du serveur DNS redirigeant tous les domaines vers l’apIP / dnsServateur.setErrorReplyCode(DNSReplyCode (en)::NoError (NoError)); dnsServateur.Commencer(DNS_PORT, "*", apIP); Série.println(F("succès.".)); Serial.setDebugOutput (vrai); Debug Sortie pour WLAN sur Serial Interface. } Autre { Série.println(F("Erreur AP soft.")); Série.println(MyWiFiConfig (en).APSTAName APSTAName); Série.println(MyWiFiConfig (en).WiFiPwd (WiFiPwd)); } Retour SoftAccOK (en); } Octet ConnectWifiAP (en)() { Série.println(F("Initalizing Wifi Client.")); Octet connRes = 0; Octet Ⅰ = 0; Wifi.Débrancher(); Wifi.softAPdisconnect(Vrai); La fonction définira actuellement le SSID configuré et le mot de passe de l’AP soft à des valeurs nulles. Le paramètre est facultatif. Si réglé pour vrai, il va éteindre le mode soft-AP. Retard(500); Wifi.Commencer(MyWiFiConfig (en).APSTAName APSTAName, MyWiFiConfig (en).WiFiPwd (WiFiPwd)); connRes = Wifi.waitForConnectResult(); Tandis que (( connRes == 0 ) Et (Ⅰ != 10)) si connRes 0 "IDLE_STATUS - changer Statius" { connRes = Wifi.waitForConnectResult(); Retard(2000); Ⅰ++; Série.Imprimer(F(".")); déclaration(s) } Tandis que (( connRes == 1 ) Et (Ⅰ != 10)) si connRes 1 NO_SSID_AVAILin - SSID ne peut être atteint { connRes = Wifi.waitForConnectResult(); Retard(2000); Ⅰ++; Série.Imprimer(F(".")); déclaration(s) } Si (connRes == 3 ) { Wifi.setAutoReconnect(Vrai); Définissez si le module tentera de se reconnecter à un point d’accès au cas où il serait déconnecté. Répondeur MDNS d’installation Si (!Mdns.Commencer(ESPHostname ESPHostname)) { Série.println(F("Erreur: MDNS")); } Autre { Mdns.addService("http", "tcp", 80); } } Tandis que (( connRes == 4 ) Et (Ⅰ != 10)) si connRes 4 Mauvais mot de passe. Parfois, cela se produit avec pwD corrct { Wifi.Commencer(MyWiFiConfig (en).APSTAName APSTAName, MyWiFiConfig (en).WiFiPwd (WiFiPwd)); connRes = Wifi.waitForConnectResult(); Retard(3000); Ⅰ++; Série.Imprimer(F(".")); } Si (connRes == 4 ) { Série.println(F("STA Pwd Err")); Série.println(MyWiFiConfig (en).APSTAName APSTAName); Série.println(MyWiFiConfig (en).WiFiPwd (WiFiPwd)); Wifi.Débrancher(); } si (connRes 6 ) - Serial.println ("DISCONNECTED - Not in station mode"); WiFi.printDiag (Serial); Série.println(""); Retour connRes; } #define SD_BUFFER_PIXELS 20 (- Chargez les informations d’identification WLAN de l’EEPROM / Bool chargeCredentials() { Bool RetValue; Eeprom.Commencer(512); Eeprom.Avoir(0, MyWiFiConfig (en)); Eeprom.Fin(); Si (String(MyWiFiConfig (en).ConfigValid) = String("TK")) { RetValue = Vrai; } Autre { RetValue = Faux; Paramètres WLAN non trouvés. } Retour RetValue; } (- Stockez les informations d’identification WLAN à eEPROM / Bool saveCredentials (en)() { Bool RetValue; Vérifier les erreurs logiques RetValue = Vrai; Si (MyWiFiConfig (en).APSTA APSTA == Vrai ) AP Mode { Si (MyWiFiConfig (en).PwDReq (en) Et (Sizeof(String(MyWiFiConfig (en).WiFiPwd (WiFiPwd))) < 8)) { RetValue = Faux; Config invalide } Si (Sizeof(String(MyWiFiConfig (en).APSTAName APSTAName)) < 1) { RetValue = Faux; Config invalide } } Si (RetValue) { Eeprom.Commencer(512); Pour (Int Ⅰ = 0 ; Ⅰ < Sizeof(MyWiFiConfig (en)) ; Ⅰ++) { Eeprom.Écrire(Ⅰ, 0); } strncpy( MyWiFiConfig (en).ConfigValid , "TK", Sizeof(MyWiFiConfig (en).ConfigValid) ); Eeprom.Mettre(0, MyWiFiConfig (en)); Eeprom.Commettre(); Eeprom.Fin(); } Retour RetValue; } Vide SetDefaultWiFiConfig() { Octet Len; MyWiFiConfig (en).APSTA APSTA = Vrai; MyWiFiConfig (en).PwDReq (en) = Vrai; PW par défaut requis MyWiFiConfig (en).CapPortal (CapPortal) = Vrai; strncpy( MyWiFiConfig (en).APSTAName APSTAName, "ESP_Config", Sizeof(MyWiFiConfig (en).APSTAName APSTAName) ); Len = Strlen(MyWiFiConfig (en).APSTAName APSTAName); MyWiFiConfig (en).APSTAName APSTAName[Len+1] = '\0'; strncpy( MyWiFiConfig (en).WiFiPwd (WiFiPwd), "12345678", Sizeof(MyWiFiConfig (en).WiFiPwd (WiFiPwd)) ); Len = Strlen(MyWiFiConfig (en).WiFiPwd (WiFiPwd)); MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Len+1] = '\0'; strncpy( MyWiFiConfig (en).ConfigValid, "TK", Sizeof(MyWiFiConfig (en).ConfigValid) ); Len = Strlen(MyWiFiConfig (en).ConfigValid); MyWiFiConfig (en).ConfigValid[Len+1] = '\0'; Série.println(F("Reset WiFi Credentials.")); } Vide handleRoot() { Page principale: Temp = ""; Octet PicCompte = 0; Octet ServArgs = 0; En-tête HTML Serveur.envoyerHeader("Cache-Contrôle", "no-cache, no-store, must-revalidate"); Serveur.envoyerHeader("Pragma", "no-cache"); Serveur.envoyerHeader("Expires", "-1"); Serveur.setContentLength(CONTENT_LENGTH_UNKNOWN); Contenu HTML Serveur.Envoyer ( 200, "texte/html", Temp ); Speichersparen - Schon mal dem Cleint senden Temp = ""; Temp += "Lt;! DOCTYPE HTML-gt;lt;html lang’de’gt;lt;head’lt;lt;meta charset’UTF-8'gt;'lt;meta name''viewport content''width’device-width, initial-scale-1.0,'''''''''''''''''''''''''; Serveur.envoyerContent(Temp); Temp = ""; Temp += « Type de style de style »'texte/css''''''''lt;!-- DIV.container ' min-height: 10em; affichage: cellule de table; alignez-vous verticalement : milieu de la hauteur : 35px; largeur :90px; font-taille: 16px'; Serveur.envoyerContent(Temp); Temp = ""; Temp += "corps 'couleur de fond: powderblue;' Lt;/style 'gt;"; Temp += "lt;head’lt;lt;title 'gt;Hauptseite’lt;/title 'lt;/head’gt;"; Temp += "lt;h2'gt;Hauptseite’lt;/h2'gt;"; Temp += "Lt;body’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Traitement de la demande d’utilisateur Temp = ""; Temp += "-lt;table border'2 bgcolor - largeur blanche ' 500 cellpadding '5 'gt;'lt;caption’lt;lt;p’lt;p’lt;h3 'gt;Systemlinks:'lt;/h2 'gt;/p’gt;/caption 'gt;"; Temp += "Lt;tr’gt;lt;lt;lt;lt;lt;br’gt;"; Temp += "'lt;a href'/wifi'''wifi'''wiFI''wiFI Einstellungen’lt;/a’lt;br’gt;lt;lt;br’gt;br’gt;"; Temp += "Lt;/th’lt;/tr’gt;/table’t;'lt;'lt;br’gt;lt;br’lt;lt;br’t;br’gt;"; Temp += "lt;footer’gt;lt;p’er;Programmed and designed by: Tobias Kuch-lt;/p’lt;p’lt;p’gt;Contact information: 'lt;a href’mailto:tobias.kuch@googlemail.com’gt;tobias.kuch@googlemail.com’lt;/a’gt;;/p’lt;/p’gt;/p’lt;/p’lt;/p’lt;/p’lt;;p.; Temp += "Lt;/corps 'lt;/html’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Serveur.Client().Arrêter(); L’arrêt est nécessaire parce que nous n’avons envoyé aucune longueur de contenu } Vide poignéeNotFound() { Si (captivePortal()) { Si caprive portail rediriger au lieu d’afficher la page d’erreur. Retour; } Temp = ""; En-tête HTML Serveur.envoyerHeader("Cache-Contrôle", "no-cache, no-store, must-revalidate"); Serveur.envoyerHeader("Pragma", "no-cache"); Serveur.envoyerHeader("Expires", "-1"); Serveur.setContentLength(CONTENT_LENGTH_UNKNOWN); Contenu HTML Temp += "Lt;! DOCTYPE HTML-gt;lt;html lang’de’gt;lt;head’lt;lt;meta charset’UTF-8'gt;'lt;meta name''viewport content''width’device-width, initial-scale-1.0,'''''''''''''''''''''''''; Temp += « Type de style de style »'texte/css''''''''lt;!-- DIV.container ' min-height: 10em; affichage: cellule de table; alignez-vous verticalement : milieu de la hauteur : 35px; largeur :90px; font-taille: 16px'; Temp += "corps 'couleur de fond: powderblue;' Lt;/style 'gt;"; Temp += "lt;head’lt;lt;title’gt;File not found’lt;/title’lt;/head’gt;"; Temp += "lt;h2'gt; 404 File Not Found’lt;/h2 'lt;lt;br’gt;"; Temp += "Lt;h4-gt;Debug Information: 'lt;/h4 'lt;lt;br’gt;"; Temp += "Lt;body’gt;"; Temp += "URI: "; Temp += Serveur.Uri(); Temp += "NMethod: "; Temp+= ( Serveur.Méthode() == HTTP_GET ) ? "GET" : "POST"; Temp += "Lt;br’gt;Arguments: "; Temp += Serveur.Args(); Temp += "N"; Pour ( uint8_t Ⅰ = 0; Ⅰ < Serveur.Args(); Ⅰ++ ) { Temp += " " + Serveur.argName argName ( Ⅰ ) + ": " + Serveur.Arg ( Ⅰ ) + "N"; } Temp += "Lt;br’gt;Server Hostheader: "+ Serveur.hostHeader (en)(); Pour ( uint8_t Ⅰ = 0; Ⅰ < Serveur.En-têtes(); Ⅰ++ ) { Temp += " " + Serveur.headerName ( Ⅰ ) + ": " + Serveur.En-tête ( Ⅰ ) + "N’lt;br’gt;"; } Temp += "Lt;/table 'gt;'lt;/form’lt;br’gt;lt;lt;br’lt;br’lt;lt;lt;table border'2 bgcolor ' largeur blanche '500 cellpadding '5 'gt;gt;-lt;caption 'lt;'lt;p’lt;lt;h2 'gt;Vous voudrez peut-être naviguer à: 'lt;/h2'lt;/p 'gt;/caption 'gt;/caption 'gt;"; Temp += "Lt;tr’gt;lt;lt;'"; Temp += "Lt;a href'/'gt;Main Page’lt;/a’lt;lt;br’gt;"; Temp += "Lt;a href'/wifi'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''; Temp += "Lt;/th’lt;/tr’gt;/table’t;'lt;'lt;br’gt;lt;br’lt;lt;br’t;br’gt;"; Temp += "-lt;footer’gt;lt;p’gt;Programmed by: Tobias Kuch’lt;/p’lt;p’lt;p’gt;Contact information: 'lt;a href’mailto:tobias.kuch@googlemail.com’gt;tobias.kuch@googlemail.com’lt;/a’gt;.lt;/p’lt;/p’lt;/p’lt;/p’lt;/p.lt;/p.'lt;; Temp += "Lt;/corps 'lt;/html’gt;"; Serveur.Envoyer ( 404, "", Temp ); Serveur.Client().Arrêter(); L’arrêt est nécessaire parce que nous n’avons envoyé aucune longueur de contenu Temp = ""; } Réorienter vers le portail captif si nous avons reçu une demande pour un autre domaine. Rendement vrai dans ce cas afin que le gestionnaire de page n’essayez pas de gérer la demande à nouveau. */ Boolean captivePortal() { Si (!Isip(Serveur.hostHeader (en)()) && Serveur.hostHeader (en)() != (String(ESPHostname ESPHostname)+".local")) { Serial.println ("Request redirected to captive portal"); Serveur.envoyerHeader("Emplacement", String("http://") + toStringIp(Serveur.Client().localIP()), Vrai); Serveur.Envoyer ( 302, "texte/plaine", ""); Le contenu vide inhibe l’en-tête de longueur de contenu ainsi nous devons fermer la prise nous-mêmes. Serveur.Client().Arrêter(); L’arrêt est nécessaire parce que nous n’avons envoyé aucune longueur de contenu Retour Vrai; } Retour Faux; } /- Wifi config page gestionnaire / Vide poignéeWifi() { Page: /wifi Octet Ⅰ; Octet Len ; Temp = ""; Vérifier les paramètres du site Si (Serveur.hasArg("Reboot") ) Système de redémarrage { Temp = "Système de redémarrage en 5 secondes."; Serveur.Envoyer ( 200, "texte/html", Temp ); Retard(5000); Serveur.Client().Arrêter(); Wifi.Débrancher(); Retard(1000); } Si (Serveur.hasArg("WiFiMode") Et (Serveur.Arg("WiFiMode") == "1") ) Mode station STA Connectez-vous à une autre station WIFI { startMillis = Millis(); Reset Time Up Counter pour éviter l’exploitation du whiole en mode ralenti Connectez-vous à STATION existante Si ( Sizeof(Serveur.Arg("WiFi_Network")) > 0 ) { Série.println("Mode STA"); MyWiFiConfig (en).APSTA APSTA = Faux; Mode point d’accès ou station - faux mode de gare Temp = ""; Pour ( Ⅰ = 0; Ⅰ < APSTANameLen;Ⅰ++) { MyWiFiConfig (en).APSTAName APSTAName[Ⅰ] = 0; } Temp = Serveur.Arg("WiFi_Network"); Len = Temp.Longueur(); Pour ( Ⅰ = 0; Ⅰ < Len;Ⅰ++) { MyWiFiConfig (en).APSTAName APSTAName[Ⅰ] = Temp[Ⅰ]; } Temp = ""; Pour ( Ⅰ = 0; Ⅰ < WiFiPwdLen (WiFiPwdLen);Ⅰ++) { MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Ⅰ] = 0; } Temp = Serveur.Arg("STAWLanPW"); Len = Temp.Longueur(); Pour ( Ⅰ = 0; Ⅰ < Len;Ⅰ++) { Si (Temp[Ⅰ] > 32) Steuerzeichen raus { MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Ⅰ] = Temp[Ⅰ]; } } Temp = "WiFi Connect à AP: -"; Temp += MyWiFiConfig (en).APSTAName APSTAName; Temp += "-lt;br’gt;WiFi PW: -"; Temp += MyWiFiConfig (en).WiFiPwd (WiFiPwd); Temp += "-lt;br’gt;"; Temp += "Connexion au mode STA en 2 secondes. Lt;br’gt;"; Serveur.Envoyer ( 200, "texte/html", Temp ); Serveur.envoyerContent(Temp); Retard(2000); Serveur.Client().Arrêter(); Serveur.Arrêter(); Temp = ""; Wifi.Débrancher(); Wifi.softAPdisconnect(Vrai); Retard(500); ConnectWifiAP (en) Bool SaveOk (SaveOk) = saveCredentials (en)(); Ⅰ = ConnectWifiAP (en)(); Retard(700); Si (Ⅰ != 3) 4: WL_CONNECT_FAILED - Mot de passe est incorrect 1: WL_NO_SSID_AVAILin - SSID configuré ne peut pas être atteint { Série.Imprimer(F(" Ne peut pas se connecter à un réseau spécifié. Motif: ")); Série.println(Ⅰ); Serveur.Client().Arrêter(); Retard(100); Wifi.setAutoReconnect (Faux); Retard(100); Wifi.Débrancher(); Retard(1000); SetDefaultWiFiConfig(); CréerWifiSoftAP(); Retour; } Autre { Config sûr Bool SaveOk (SaveOk) = saveCredentials (en)(); InitalizeHTTPServer(); Retour; } } } Si (Serveur.hasArg("WiFiMode") Et (Serveur.Arg("WiFiMode") == "2") ) Modifier le mode AP { startMillis = Millis(); Reset Time Up Counter pour éviter l’exploitation du whiole en mode ralenti Configurer le point d’accès Temp = Serveur.Arg("APPointName"); Len = Temp.Longueur(); Temp =Serveur.Arg("APPW"); Si (Serveur.hasArg("PasswordReq")) { Ⅰ = Temp.Longueur(); } Autre { Ⅰ = 8; } Si ( ( Len > 1 ) Et (Serveur.Arg("APPW") == Serveur.Arg("APPWRepeat")) Et ( Ⅰ > 7) ) { Temp = ""; Série.println(F("APMode")); MyWiFiConfig (en).APSTA APSTA = Vrai; Point d’accès ou mode Sation - vrai mode AP Si (Serveur.hasArg("CaptivePortal")) { MyWiFiConfig (en).CapPortal (CapPortal) = Vrai ; CaptivePortal en mode AP } Autre { MyWiFiConfig (en).CapPortal (CapPortal) = Faux ; } Si (Serveur.hasArg("PasswordReq")) { MyWiFiConfig (en).PwDReq (en) = Vrai ; Mot de passe requis en mode AP } Autre { MyWiFiConfig (en).PwDReq (en) = Faux ; } Pour ( Ⅰ = 0; Ⅰ < APSTANameLen;Ⅰ++) { MyWiFiConfig (en).APSTAName APSTAName[Ⅰ] = 0; } Temp = Serveur.Arg("APPointName"); Len = Temp.Longueur(); Pour ( Ⅰ = 0; Ⅰ < Len;Ⅰ++) { MyWiFiConfig (en).APSTAName APSTAName[Ⅰ] = Temp[Ⅰ]; } MyWiFiConfig (en).APSTAName APSTAName[Len+1] = '\0'; Temp = ""; Pour ( Ⅰ = 0; Ⅰ < WiFiPwdLen (WiFiPwdLen);Ⅰ++) { MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Ⅰ] = 0; } Temp = Serveur.Arg("APPW"); Len = Temp.Longueur(); Pour ( Ⅰ = 0; Ⅰ < Len;Ⅰ++) { MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Ⅰ] = Temp[Ⅰ]; } MyWiFiConfig (en).WiFiPwd (WiFiPwd)[Len+1] = '\0'; Temp = ""; Si (saveCredentials (en)()) Enregistrer AP ConfigCongfig { Temp = "Daten des AP Modes erfolgreich gespeichert. Redémarrer notwendig."; } Autre { Temp = "Daten des AP Modes fehlerhaft."; } } Autre Si (Serveur.Arg("APPW") != Serveur.Arg("APPWRepeat")) { Temp = ""; Temp = "WLAN Passwort nicht gleich. Abgebrochen.; } Autre { Temp = ""; Temp = "WLAN Passwort oder AP Nom zu kurz. Abgebrochen.; } } En-tête HTML Serveur.envoyerHeader("Cache-Contrôle", "no-cache, no-store, must-revalidate"); Serveur.envoyerHeader("Pragma", "no-cache"); Serveur.envoyerHeader("Expires", "-1"); Serveur.setContentLength(CONTENT_LENGTH_UNKNOWN); Contenu HTML Temp += "Lt;! DOCTYPE HTML-gt;lt;html lang’de’gt;lt;head’lt;lt;meta charset’UTF-8'gt;'lt;meta name''viewport content''width’device-width, initial-scale-1.0,'''''''''''''''''''''''''; Serveur.Envoyer ( 200, "texte/html", Temp ); Temp = ""; Temp += « Type de style de style »'texte/css''''''''lt;!-- DIV.container ' min-height: 10em; affichage: cellule de table; alignez-vous verticalement : milieu de la hauteur : 35px; largeur :90px; font-taille: 16px'; Temp += "corps 'couleur de fond: powderblue;' 'lt;/style 'gt;'lt;'lt;head;'lt;title 'gt;Smartes Tuerschild - WiFi Settings’lt;/title 'gt;'lt;/head’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Temp += "lt;h2 'gt;WiFi Einstellungen’lt;/h2 'lt;body’lt;lt;lt;left’gt;"; Temp += "-lt;table border'2 bgcolor ' largeur blanche '500 'gt;'lt;td’gt;lt;h4 'gt;Current WiFi Paramètres: 'lt;/h4 'gt;"; Si (Serveur.Client().localIP() == apIP) { Temp += "Mode : Soft Access Point (AP)-lt;br-gt;"; Temp += "SSID : " + String (MyWiFiConfig (en).APSTAName APSTAName) + "Lt;br’gt;lt;br’gt;"; } Autre { Temp += "Mode : Station (STA) 'lt;br’gt;"; Temp += "SSID : "+ String (MyWiFiConfig (en).APSTAName APSTAName) + "Lt;br’gt;"; Temp += "BSSID : " + Wifi.BSSIDstr()+ "Lt;br’gt;lt;br’gt;"; } Temp += "Lt;/td’lt;/table’lt;'lt;br’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Temp += Méthode d’action'/wifi''post'''post'''"; Temp += "-lt;table border'2 bgcolor ' largeur blanche '500 'gt;'lt;tr’gt;lt;lt;lt;'lt;'lt;lt;lt;br’gt;"; Si (MyWiFiConfig (en).APSTA APSTA == 1) { Temp += " 'lt;input type’radio' value''1' name’WiFiMode' ''wiFiMode' 'gt; WiFi Station Mode’lt;br’gt;"; } Autre { Temp += "'lt;input type' 'radio' value''1' name’WiFiMode' checked 'gt; WiFi Station Mode’lt;br’gt;"; } Temp += "Réseaux WiFi disponibles: 'lt;table border'2 bgcolor 'blanc 'gt;'lt;/tr’gt;'lt;/th’lt;/th’lt;td;Td’gt;Number 'lt;/td’gt;'l td;SSID -lt;/td 'lt;'lt;td;Encryption 'lt;/td’gt;/td’lt;'lt;td;td;td’gt;WiFi Strength 'lt;/td 'gt;"; Serveur.envoyerContent(Temp); Temp = ""; Wifi.scanDelete(); Int ¡n = Wifi.scanNetworks (scanNetworks)(Faux, Faux); WiFi.scanNetworks (async, show_hidden) Si (¡n > 0) { Pour (Int Ⅰ = 0; Ⅰ < ¡n; Ⅰ++) { Temp += "Lt;/tr’gt;lt;/th’gt;"; String Nrb = String(Ⅰ); Temp += "Lt;td’gt;" + Nrb + "Lt;/td’gt;"; Temp += "Lt;td’gt;" + Wifi.Ssid(Ⅰ) +"Lt;/td’gt;"; Nrb = GetEncryptionType(Wifi.cryptageType(Ⅰ)); Temp += "Lt;td’gt;"+ Nrb + "Lt;/td’gt;"; Temp += "Lt;td’gt;" + String(Wifi.RSSI RSSI(Ⅰ)) + "Lt;/td’gt;"; } } Autre { Temp += "Lt;/tr’gt;lt;/th’gt;"; Temp += "Lt;td’gt;1 'lt;/td’gt;"; Temp += "Lt;td’gt;No WLAN trouvé’lt;/td’gt;"; Temp += "Lt;td’gt; --- 'lt;/td’gt;"; Temp += "Lt;td’gt; --- 'lt;/td’gt;"; } Temp += "-lt;/table 'gt;'lt;lt;table border'2 bgcolor 'blanc 'gt;'lt;/tr’lt;/th’lt;'lt;'lt;t’lt;td’td’gt;Connect to WiFi SSID: 'lt;/td’lt;td;td;td;td;'lt;'s select name’WiFi_Network’a; Si (¡n > 0) { Pour (Int Ⅰ = 0; Ⅰ < ¡n; Ⅰ++) { Temp += " Valeur d’option '" + Wifi.Ssid(Ⅰ) +"'>" + Wifi.Ssid(Ⅰ) +"Lt;/option’gt;"; } } Autre { Temp += "Lt;option value’No_WiFi_Network''no WiFiNetwork trouvé !/option 'gt;"; } Serveur.envoyerContent(Temp); Temp = ""; Temp += "Lt;/select’gt;/td’lt;/tr’lt;/tr’gt;/th’lt;/th’lt;/tr’lt;/tr’lt;/th 'lt;'lt;Tt;td’gt;WiFi Password: 'lt;/td’gt;'lt;td;gt;td;gt;'; Temp += « Type d’entrée »texte' nom 'STAWLanPW' maxlength''40' size''40'gt;"; Temp += "Lt;/td’lt;/tr’gt;/lt;/th’lt;'lt;'lt;br’gt;'lt;/th’lt;/th’lt;/tr’gt;lt;/table -gt;/table 'gt;'lt;lt;lat;table border'2 bgcolor ' largeur blanche '500 'gt;'lt;tr’gt;lt;'lt;'lt;'lt;'lt;br’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Si (MyWiFiConfig (en).APSTA APSTA == Vrai) { Temp += " 'lt;input type' name''WiFiMode' value''2' checked’gt; WiFi Access Point Mode 'lt;br’gt;"; } Autre { Temp += " 'lt;input type’radio' name''WiFiMode' value''2' ''gt; WiFi Access Point Mode 'lt;br’gt;"; } Temp += "-lt;table border'2 bgcolor ' blanc 'gt;'lt;/tr’gt;'lt;/th’gt; 'lt;td’gt; 'lt;td’gt;WiFi Access Point Name: 'lt;/td’gt;'lt;td’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Si (MyWiFiConfig (en).APSTA APSTA == Vrai) { Temp += «Lt;input type’texte' nom 'APPointName' maxlength'"+String(APSTANameLen-1)+"'taille'30' valeur'" + String(MyWiFiConfig (en).APSTAName APSTAName) + "''''lt;/td’gt;"; } Autre { Temp += «Lt;input type’texte' nom 'APPointName' maxlength'"+String(APSTANameLen-1)+"' taille'30' 'gt;'lt;/td’gt;"; } Serveur.envoyerContent(Temp); Temp = ""; Si (MyWiFiConfig (en).APSTA APSTA == Vrai) { Temp += "Lt;/tr’gt;lt;/th 'lt;'lt;td’gt;WiFi Password: 'lt;/td’gt;lt;td;td;td;td’gt;"; Temp += " ''APPW' maxlength'"+String(WiFiPwdLen (WiFiPwdLen)-1)+"'taille'30' valeur'" + String(MyWiFiConfig (en).WiFiPwd (WiFiPwd)) + "'gt; 'lt;/td 'gt;"; Temp += "Lt;/tr’gt;lt;/th 'lt;'lt;td’gt;Repeat WiFi Password: 'lt;/td 'gt;"; Temp += «Lt;td’gt;lt;lt;type d’entrée type 'password' nom 'APPWRepeat' maxlength'"+String(WiFiPwdLen (WiFiPwdLen)-1)+"'taille'30' valeur'" + String(MyWiFiConfig (en).WiFiPwd (WiFiPwd)) + "'gt; 'lt;/td 'gt;"; } Autre { Temp += "Lt;/tr’gt;lt;/th 'lt;'lt;td’gt;WiFi Password: 'lt;/td’gt;lt;td;td;td;td’gt;"; Temp += " ''APPW' maxlength'"+String(WiFiPwdLen (WiFiPwdLen)-1)+"' taille'30'gt; 'lt;/td’gt;"; Temp += "Lt;/tr’gt;lt;/th 'lt;'lt;td’gt;Repeat WiFi Password: 'lt;/td 'gt;"; Temp += «Lt;td’gt;lt;lt;type d’entrée type 'password' nom 'APPWRepeat' maxlength'"+String(WiFiPwdLen (WiFiPwdLen)-1)+"' taille'30'gt; 'lt;/td’gt;"; } Temp += "Lt;/table’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Si (MyWiFiConfig (en).PwDReq (en)) { Temp += "Le nom de la boîte à contrôle''passwordReq' a vérifié le mot de passe pour Login. "; } Autre { Temp += "Le nom de la boîte à contrôle''passwordReq' 'lt;input type''checkbox' ''PasswordReq' ''''' ''' '' ''; } Serveur.envoyerContent(Temp); Temp = ""; Si (MyWiFiConfig (en).CapPortal (CapPortal)) { Temp += " 'lt;input type’checkbox' name’CaptivePortal' checked’gt; Activate Captive Portal"; } Autre { Temp += Nom de la boîte à contrôle 'CaptivePortal' ''''''''Ant;'input type’checkbox' ''CaptivePortal' ''Activate Captive Portal'; } Serveur.envoyerContent(Temp); Temp = ""; Temp += "lt;br’gt;/tr’lt;/th’lt;/th’lt;/table’lt;'lt;'lt;br’gt; 'lt;type''submit' name'''Settings' value'1' style’height: 50px; largeur: 140px' autofocus 'gt;Set WiFi Settings’lt;/button 'gt;"; Temp += « Le type de bouton » « soumettre » le nom de 'Reboot' 'valeur''1' style’height: 50px; largeur: 200px' 'gt;Reboot System’lt;/button’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Temp += « Le type de bouton » ' 'reset' name''action' value''1' style’height: 50px; largeur: 100px' 'gt;Reset’lt;/button 'lt;/form’gt;"; Temp += "-lt;table border'2 bgcolor ' largeur blanche '500 cellpadding '5 'gt;'lt;caption’lt;lt;p’lt;p’lt;h3 'gt;Liens système: 'lt;/h2'gt;'lt;/p’lt;/caption’lt;/caption’lt;tr’gt;lt;'lt;'lt;'lt;'lt;'lt;br’gt;"; Serveur.envoyerContent(Temp); Temp = ""; Temp += "-lt;a href'/'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''a’t;'lt;/table'',lt;br’lt;br’lt;'lt;/th’lt;/th’lt;/'lt;/tr’lt;/table''t;lt;br’gt;"; Temp += "lt;footer’gt;lt;p’gt;d;Programmé et conçu par: Tobias Kuch’lt;/p’lt;lt;p’lt;p’gt;Contact information: 'lt;a href 'mailto:tobias.kuch@googlemail.com''gt;tobias.kuch@googlemail.com’lt;/a’gt;.lt;/p’gt;/footer’gt;"; Temp += "Lt;/corps 'lt;/html’gt;"; Serveur.envoyerContent(Temp); Serveur.Client().Arrêter(); L’arrêt est nécessaire parce que nous n’avons envoyé aucune longueur de contenu Temp = ""; } C’est une adresse IP ? */ Boolean Isip(String Rue) { Pour (Int Ⅰ. = 0; Ⅰ. < Rue.Longueur(); Ⅰ.++) { Int C = Rue.charAt(Ⅰ.); Si (C != '.' && (C < '0' || C > '9')) { Retour Faux; } } Retour Vrai; } String GetEncryptionType(Octet ceType) { String Sortie = ""; lire le type de chiffrement et imprimer le nom: Interrupteur (ceType) { Cas 5: Sortie = "WEP"; Retour Sortie; Pause; Cas 2: Sortie = "WPA"; Retour Sortie; Pause; Cas 4: Sortie = "WPA2"; Retour Sortie; Pause; Cas 7: Sortie = "Aucun"; Retour Sortie; Pause; Cas 8: Sortie = "Auto"; Retour Sortie; Pause; } } TU t’enchaînes ? */ String toStringIp(Ipaddress Ip) { String Res = ""; Pour (Int Ⅰ. = 0; Ⅰ. < 3; Ⅰ.++) { Res += String((Ip >> (8 * Ⅰ.)) & 0xff) + "."; } Res += String(((Ip >> 8 * 3)) & 0xff); Retour Res; } String formatBytes(Size_t Octets) { affichage lisible des tailles de mémoire Si (Octets < 1024) { Retour String(Octets) + "Byte"; } Autre Si (Octets < (1024 * 1024)) { Retour String(Octets / 1024.0) + " KB "; } Autre Si (Octets < (1024 * 1024 * 1024)) { Retour String(Octets / 1024.0 / 1024.0) + " Mb "; } } Vide Boucle() { Si (SoftAccOK (en)) { dnsServateur.processusNextRequest(); Dns } HTTP (en) Serveur.handleClient(); }]
Dans la prochaine partie, nous voulons examiner l’utilisation pratique de notre code et construire un petit serveur de fichiers basé sur ce code.
Je vous souhaite beaucoup de plaisir avec le portail captif et lors de sa mise en œuvre dans mes propres projets ESP32.
18 commentaires
Walter
Hi, this code is bugged, please fix it. Thanks,
Jan
Hallo Gerald, herzlichsten Dank!!! Ich hatte da schon einige Stunden herumprobiert, aber immer die falsche Stelle erwischt. Es ist exakt so wie beschrieben: durch das Auskommentieren dieser Zeile in der setup() werden die Credentials nicht überschrieben, dennoch wird ein AP angelegt mit den hinterlegten Zugangsdaten. Dadurch ist es egal, wenn das Gerät mal nicht ins WLAN kommen sollte, der AP stört ja nicht und ließe sich auch durch einen Button aktivieren. Danke nochmal!
Gerald Lechner
Hallo Jan
Ich würde in der Setup-Routine
if ((ConnectSuccess or CreateSoftAPSucc))
{
Serial.print (F("IP Address: “));
if (CreateSoftAPSucc) { Serial.println(WiFi.softAPIP());}
if (ConnectSuccess) { Serial.println(WiFi.localIP());}
InitalizeHTTPServer();
}
else
{
Serial.setDebugOutput(true); //Debug Output for WLAN on Serial Interface.
Serial.println(F(”Error: Cannot connect to WLAN. Set DEFAULT Configuration."));
SetDefaultWiFiConfig();
CreateSoftAPSucc = CreateWifiSoftAP();
InitalizeHTTPServer();
SetDefaultWiFiConfig();
saveCredentials();
}
}
die Zeile saveCredentials(); auskommentieren. Die wird nur dann aufgerufen, wenn keine Verbindung möglich war. Wenn die Credentials hier nicht gespeichert werden, geht der ESP32 zwar in den AP-Modus, speichert diesen Zustand aber nicht ab. Damit werden beim nächsten Start wieder die abgespeicherten Credentials für den Station-Mode genutzt.
Jan
Herzlichen Dank für den tollen Sketch, läuft mit den kleinen Korrekturen soweit sehr gut. Leider werden die manuell gespeicherten WLAN-Daten gelöscht, sobald das WLAN beim Start nicht verfügbar ist. Offenbar werden die Zugangsdaten für AP und STA an der gleichen Stelle im eeprom gespeichert, sodass die vorigen Zugangsdaten unwiederbringlich gelöscht werden, sobald das Gerät in den AP-Modus wechselt. Frage: wie ließen sich die AP-Zugangdaten hart festschreiben, um zu verhindern, dass die eingetragenen WLAN-Daten im AP-Modus gelöscht werden? Im eeprom möchte ich ausschließlich die Daten für den STA-Modus speichern.
Jan
Ein sehr schöner Sketch, herzlichen Dank für die Arbeit und Veröffentlichung. Mit den Tipps aus den Kommentaren läuft das soweit sehr zuverlässig auf meinem ESP32.
Leider stört ein ‘Feature’ in meinem Projekt ganz erheblich: Findet der ESP beim Starten das vorher konfigurierte WLAN nicht, werden die Zugangsdaten komplett gelöscht. Das ist bei temporärem oder instalbilem WLAN ziemlich störend. Meine Frage in die Runde: an welcher Stelle kann ich das am besten verhindern? Die Routine für den Reset-Knopf möchte ich ja nicht komplett löschen. Ziel: WLAN-Zugangsdaten werden nur durch Reset oder Überschreiben gelöscht, nicht aber automatisch.
Danke für Tipps!!!
Achim
Hi kann mir einer schreiben wie diese ESPmDNS.h finde und einbinde .
Normal kann ich Bibilotheken einbinden aber diese finde ich nicht oder die IDE meckert das die Zip keine Bibliothek enthält
Tobias
Sehr geehrter Herr Holler,
Ich muss leider 2 Punkte korrigieren. Zum einen ist die Beschränkung auf 20 Zeichen der SSID kein Fehler sondern eine Limitierung, die im Sinne des open Source Gedankens angepasst werden kann. Zum anderen werden Tests der Software beim Entwickeln und kursorische Abschlusstests vor Veröffentlichung durchgeführt. Ihre generalisierte Aussage, das Tests überhaupt nicht durchgeführt werden ist daher nicht korrekt.
Jedoch sind generell leider auch zeitliche Limitierungen bei der Entwicklung einzuhalten, sodass eben Bugs nicht ganz vermieden werden können. Ich freue mich jedoch, das diese sich bisher auf ein Bug bei einem komplexem Code wie diesen beschränken. Sachliche Hinweise auf diese oder für alle relevante Verbesserungswünsche, ohne Wertung, sind daher immer willkommen und werden im nächsten Release ggf. berücksichtigt.
Walter Holler
Wäre es zu viel verlangt, den veröffentlichten Code vorher mal selbst auszuprobieren?
Ich habe den Code auf meinen neu gekauften ESP32 geladen und mindestens 2 Fehler gefunden:
1) Der Vergleichs-Operator für Gleichheit ist “==”. Das einfache “=” ist eine Zuweisung.
Also in loadCredentials() :
if (String(MyWiFiConfig.ConfigValid) == String(“TK”))
statt
if (String(MyWiFiConfig.ConfigValid) = String(“TK”))
2) Die maximale Länge der SSID Namen ist 32 nicht 20, sonst funktioniert es nicht bei längeren Namen wie bei mir.
static const byte APSTANameLen = 32; //was 20
Dann funktioniert auch der AP Mode, Auswahl des WLANs und Eingabe des Passwords und Wechsel in mein WLAN.
Jedoch nach Reset des ESP32 startet er wieder im AP mode..?
MCL
|ich kann kein ESP_Config finden… Nur ein ESP_C9013b….
das liegt auch an ‘alten’ credentials.
‘C9013b’ ist der zweite Teil der MAC Adresse…
Man kann die Kommandos zum Überschreiben der Credantials ‘zu Fuss’ schreiben oder so:
// if (false) // overwrite only ONCE!!
if (loadCredentials()) // Load WLAN credentials for WiFi Settings
Also einmals mit ’ if (false) ’ kompilieren und laden.
=> so werden die Credentials garantiert korrekt überschrieben
Danach wieder auskommentieren und statt dessen ’ if (loadCredentials()) ’ verwenden und laden.
Manfred
Einfach den Code in einen vernünftigen Editor (z.B. Notpad++) kopieren und schon siehst Du, dass diese Klammer das Gegenstück von Zeile 1 ist. Fehlersuche dauerte nicht länger als die Eingabe Deiner Kommentars.
Tobias
Hallo Matthias,
Gleiches Problem und gleiche wie bei Christoph.
Gruß
Tobias
Hallo Christoph,
Dies liegt darin begründet, das der ESP intern die Credentials speichert, (von deinem vorherigen Projekt) . Um diese loszuwerden, führe EINMALIG in der Setup Routine folgende Sequenz aus:
SetDefaultWiFiConfig();
saveCredentials();
CreateSoftAPSucc = CreateWifiSoftAP();
Damit werden die Daten von dem Vorprojekt überschrieben. Nachdem diese überschrieben wurden, können die Zeilen wieder entfernt werden.
Wolfgang
Gibt es eigentlich auch einen Teil 1?
Ulrich Klaas
Hallo,
im Code für den 8266 ist die Fehlerbehebung aber noch nicht drin ??
Der hat sich nicht verändert. Geschieht das noch ?
mfG
Ulli
Peter Pitzeier
In bool loadCredentials() muss natürlich
if (String(MyWiFiConfig.ConfigValid) == String(“TK”))
und nicht
if (String(MyWiFiConfig.ConfigValid) = String(“TK”))
Christoph O
Danke für das CapturePortal-Besipiel!
Ich habe bei mir das Problem, dass ich vor einiger Zeit bereits einmal einen anderen WLAN-Accesspoint geflasht habe. Die SSID habe ich damals “Heinzelmännchen” genannt.
Nun erscheint nach dem flashen dieses Beispiels wieder der Name “Heinzelmännchen” als SSID und nicht der angegebene “ESP_Config”. Ich vermute, dass “Heinzelmännchen” noch aus alten Zeiten im EEPROM steht und nicht überschrieben wurde.
Ich kann mich leider nicht mit dem Passwort “12345678” verbinden. Das alte Passwort von Heinzelmännchen kenne ich leider nicht mehr.
Kann mir irgendwer weiterhelfen?
Klar, ich könnte wieder ein eigenen WLAN-Accesspoint flashen und alles überschreiben aber hier scheint trotzdem noch ein Bug im Quelltext zu sein.
Matthias
Hallo Zusammen,
ich kann kein ESP_Config finden… Nur ein ESP_C9013b….
Das Passwort funktioniert bei dem letzteren auch nicht.
Ich habe nichts an dem Arduino scetch verändert.
Hat sonst jemand noch dieses Problem?
Ich benutze ein Lolin D32 Pro mit einem ESP32 Wrover Chip
Danke und Gruss
Matthias
Joe
Die
]
gehört wo hin ????