Stabiler HTTP 1.1 WLAN Webserver mit dem ESP8266 Microcontroller

Nach einigen Experimenten mit dem ESP8266 WLAN Microcontroller (was ist das?), habe ich versucht einen stabilen kleinen Webserver zu realisieren. Am Ende habe ich es geschafft, eine stabile Variante zu erzeugen.

Angefangen habe ich mit der AT Firmware 0.9.5 und habe die AT Kommandos über einen Arduino erzeugt und interpretiert. Es hat zwar funktioniert, wurde aber regelmäßig instabil. Und es ist offen gesagt relativ furchtbar zu programmieren.
Danach habe ich mit der nodemcu Firmware experimentiert. Der Webserver war dann in lua geschrieben und an den verfügbaren Beispielen orientiert. Auch das war nie wirklich stabil. Der Webserver war immer wieder offline. Und ab und zu hat es den ESP auch so „zerrissen“, dass ich ihn neu flashen musste.

Wirklich voran ging es dann mit der Verfügbarkeit der ESP8266 Toolchain in der Arduino IDE (siehe hier). Das Webclient Beispiel war schon stabiler, lief aber auch immer wieder in Probleme. Die hier angehängte C-Code läuft nun seit mehreren Tagen bei mir stabil – und da möchte ich sie nicht für mich alleine behalten.

Als Demo wird eine kleine HTML Seite erzeugt, die zwei Funktionen zum Schalten anbietet. Funktion 1 erzeugt eine Ausgabe auf der seriellen Schnittstelle und schaltet GPIO2. Funktion 2 erzeugt nur eine Ausgabe auf der seriellen Schnittstelle.

ESP8266_Webserver

Der Sinn der seriellen Ausgaben ist einerseits natürlich für Debugging mit dem Seriellen Monitor in der IDE. Ich diese Ausgaben aber auch genutzt, um einen Arduino zu steuern. Dieser empfängt die seriellen Ausgaben (Softserial langt) und steuert damit alle Ein- und Ausgänge des Arduino. Auf diese Weise lässt sich sehr einfach eine Kopplung zwischen Arduino und ESP8266 erzeugen. Dazu schreibe ich später nochmal einen Beitrag.

Bei der folgenden Implementierung sind im Unterschied zu den üblichen Beispielen folgende Punkte verbessert / behoben:

  1. Bei Verlust der WLAN verbindung nach der ersten Verbindung wird die Verbindung falls nötig neu aufgebaut.
  2. Es wird eine saubere HTTP 1.1 Verbindung mit gültigem Header und „connection close“ erzeugt. Die mir bekannten Beispiele erzeugen entweder keinen Header oder setzen auf HTTP 1.0. Dadurch ist nicht sauber definiert, ob die Verbindung am Ende der Übertragung der Seite geschlossen werden soll. Dies kann zu Problemen führen.
  3. Falls nicht vorhandene Daten abgefragt werden, wird eine 404 Antwort erzeugt. Viele Browser suchen z.B. nach der favicon.ico und warten dann lange auf ein Timeout. Das kann den Webserver blockieren.
  4. Es kommt ab und zu leeren Anfragen an den ESP8266. Das könnte ein Fehler im SDK sein. Dieser Fehler wird hier abgefangen.

Den Code gibt es hier – bitte das eigene SSID und das Passwort eintragen: ESP_Webserver_HTTP11

Nachtrag 10.08.2015: Hier gibt es eine Version des Codes als AccessPoint.

173 Gedanken zu „Stabiler HTTP 1.1 WLAN Webserver mit dem ESP8266 Microcontroller

  1. Eggert Feddersen

    Zum ESP Webserver:
    Hallo, ich möchte mich herzlich bedanken für die sehr gute Veröffentlichung.
    Klappt prima. Ich bin auf dem Gebiet noch ein bloody beginner.
    Werde Dein Programm als Basis zum Lernen verwenden. Nochmals vielen Dank.
    Eggert

    Antworten
      1. Thomas

        Moin moin,

        als Erstes auch mein Dank für die hier toll dargestellte Problematik und die Bereitstellung deines Codes. Leider läuft das bei mir nicht…

        Ich habe ein 8266 NodeMCU Board (dieses hier: https://www.amazon.de/AZDelivery-NodeMCU-ESP8266-ESP-12E-Development/dp/B06Y1ZPNMS )
        Kompilieren und Hochladen klappt. Öffnen mit dem Browser geht nicht. Zwar wird beim Aktualisieren der Seite ab und zu für einen Bruchteil einer Sekunde die richtige Seite (wie oben abgebildet) angezeigt, danach die Meldung , dass die Seite nicht angezeigt werden kann 🙁

        Der serielle Monitor spuckt auch nichts aus…

        Hast du da zufällg ne Idee?

        Liebe Grüße aus Lübeck,
        Thomas

        Antworten
        1. ST Beitragsautor

          Hallo Thomas,

          lies bitte mal die Kommentare weiter unten 😉
          Die Lösung steht sogar schon 2x da. Die aktuelle ESP8266 Entwicklungsumgebung ist buggy.

          Gruss Stefan

          Antworten
        2. Jochen-Paul

          Hallo,
          am Problem, dass beim Öffnen des Browsers die Seite für einen Bruchteil einer Sekunde öffnet, bin ich auch fast verzweifelt.
          Lösung:
          Bordverwalter öffnen -> ESP8266 eintippen -> auf Version 2.5.0 updaten -> schliessen.
          Fertig.
          Jochen-Paul

          Antworten
        1. Erich

          Hallo Stefan, Hallo Jürgen!
          Danke für eure Anleitungen
          „ESP_Webserver_HTTP11“ und „http://pastebin.com/8uwAhSQ0“
          Jetzt habe ich eine Frage zum fastled_7_switches Projekt.
          Ist es möglich diese Sketch so zu kürzen bzw. ändern dass diese 6 fastled Funktionen ohne web Kontrolle einfach hintereinder endlos durchlaufen oder nach dem anlegen der 3.3V mit einem zufälligen Prog. starten?
          Ich kann ja leider nur Kopieren aber nicht Programmieren.

          Gruß Erich

          Antworten
          1. ST Beitragsautor

            Hallo Erich,

            klar ist das möglich. Der Code auf Pastebin hat ein paar heftige Limitationen. Man löst im WEbIF eine Aktion aus und dann machen die LEDs etwas. Während dessen ist aber das WebIF geblockt. Man kann auf Zufall umbauen, aber dann kannst Du per WEbIF nur noch zugreifen, wenn Du zufällig mal zwischen den LED Loops aufrufst. –> Läuft also praktisch nicht.
            Man müsste das deutlich umbauen: LED Ansteuerung in einen Interrupt packen oder den Loop so umschreiben, dass er mit jedem Aufruf der Loop()-Hauptroutine einen Schritt ausführt. Dann den Modus per Random setzen, wenn nichts vom WebIF kommt.
            –> Größerer Umbau – ich würde vermutlich >1h sitzen, bis es wirklich rund ist. Ehrliche Antwort: Macht Dir vermutlich keiner kurz mal so ohne eigene Anwendung. Vielleicht findet sich ein Mitleser.

            Gruss Stefan

  2. Frank

    Ich habe mein Glück auch versucht, leider bekomme ich beim Kompilieren einen Fehlerhinweis:

    _1.6.4_ESP_Webserver_HTTP11.ino:23:25: fatal error: ESP8266wifi.h: No such file or directory
    compilation terminated.

    Es scheint mehrere Versionen der ESP8266wifi.h zu geben. Wo finde ich die richtige Version?

    Frank

    Antworten
  3. MacSteven

    Gibt es nicht in der ESP8266-Bibliothek die Möglichkeit, einen Watchdog-Timer zu aktivieren und zu nutzen? Das wäre doch auch eventuell eine Möglichkeit, einen abgestürzten oder nicht verbundenen Webserver wiederzubeleben.

    Antworten
    1. ST Beitragsautor

      Einen Watchdog habe ich auf dem ESP noch nicht benutzt. Abgebrochene (bzw nicht verbundene) WLAN Verbindungen stellt der gepostete Code bei mir wieder her.
      Meine praktische Erfahrung aus dem Markisenprojekt ist bisher, dass der ESP einige Wochen ohne Probleme am Stück lief.
      Hast Du Probleme mit der Stabilität? – Wenn ja, welche konkret? – Das einzige mir bekannte Stabilitätsproblem tritt ein, wenn man ein WLAN mit mehreren Accesspoints einsetzt. Die ESP Firmware ist nämlich aktuell nicht clever genug, sich mit dem stärksten Accesspoint zu verbinden. Der ESP nimmt einfach den mit der niedrigsten Kanalnummer…

      Antworten
  4. Ulli

    Moin,

    vielen Dank für den Post. Habe das Programm kompiliert und geflasht. Das klappt prima. Die Verbindung, d.h. der Abruf der Seite klappt auch. Leider aber nur i.d.R.

    Ich habe den Effekt, dass nach 2-10 Abrufen das System resettet, d.h. wieder mit setup() startet (habe zum Erkennen ein entsprechendes Serial.println() eingefügt). Das ist nicht das Wiederaufnehmen eine abgebrochenen Verbindung (WiFiStart() in deinem Code)! Wenn keine Request sind stürzt das Sysem nicht ab.
    WiFi connected
    Server started
    192.168.2.111
    belibt stundenlang stehen. Ohne das etwas passiert.

    Frage: hat jemand anderes dieses Effekt auch? Wenn ja, hat jemand eine Lösung?

    Antworten
    1. ST Beitragsautor

      Ich habe den Code in mehreren Varianten laufen und es ist bei mir absolut stabil.
      Eventuell liegt es an einer alten SDK Version von Espressif. Ich nehme aktuell die Version 1.0.1.

      Antworten
    1. ST Beitragsautor

      Die ESP8266WiFi.h (bitte die Groß/Kleinschreibung im Code beachten) liegt typischerweise hier:
      C:\Users\User\Documents\Arduino\hardware\esp8266-Arduino-master\esp8266\libraries\ESP8266WiFi\src
      (wobei User je nach Windows / Usereinrichtung anders heißen kann).

      Diese Datei kommt mit der ESP8266 Erweiterung mit, die man zu der Arduino IDE dazuinstallieren muss; siehe hier:
      https://blog.thesen.eu/esp8266-wlan-microcontroller-mit-der-arduino-ide-programmieren/

      Antworten
  5. Nik

    Danke für den Webserver, dieser funktioniert sehr gut. Könntest du noch eine Anzeige für den aktuellen Status einbauen? Sodass man sieht ob zum Beispiel Gpio2 gerade aktiv oder inaktiv ist.

    Antworten
    1. ST Beitragsautor

      Dein Wunsch ist recht einfach einzubauen. Da ich aktuell dienstlich unterwegs bin, kommt hier eine etwas abstraktere Beschreibung:
      1. Definiere Dir eine globale Variable (z.B. bool bGPIO2Status).
      2. Setze diesen Status in init() auf false (aus).
      3. Setze den Status auf true/false, dort wo der GPIO2 geschaltet wird.
      4. Baue Dir in dem Bereich zur Generierung der html Seite eine weiter Zeile ein, die Dir den Status auf die html Seite schreibt.

      Antworten
      1. Nik

        Hi,

        leider bin ich nicht ganz so drin in der Materie. Konntest du es bitte umsetzen, wenn du mal Zeit hast? Stelle es mir zum Beispiel so vor. Es gibt nur ein Button für An/Aus. Bei An leuchtet er zum Beispiel grün und bei Aus leuchtet er rot.

        Danke

        Antworten
          1. ST Beitragsautor

            Zur Niks Frage zur Instabilität des referenzierten Codes:
            Der von Dir referenzierte Code macht genau das nicht, was ich oben als Verbesserungen erwähnt und in den Code eingebaut habe:
            – keine Wiederverbindung bei abgebrochener Verbinung
            – kein Handling leerer Requests
            – kein sauberes http 1.1 mit der Länge der Nachricht im Header
            – kein Abfangen von Request auf nicht vorhandene URLs / Dateien

            Nun macht der referenzierte Code die selbe Zielsetzung wie der Code hier: Einen GPIO schalten. Probier doch einfach mal den Code hier aus. Wenn Du den Code nicht ändern willst, musst Du einfach nur GPIO0 zum Schalten nehmen. Diese Code läuft bei mir mittlerweile seit April ohne Reboot in einer Markisensteuerung stabil.

            Gruss Stefan

        1. ST Beitragsautor

          Zur rot/grün Frage:
          Vorschlag: du versuchst es und sagst wo Du nicht klar kommst. Du musst effektiv nur zwei Zeilen ändern, um nur einen Button zu haben (dort wo der html Code für die Buttons steht).
          Und wenn Du mit rot/grün zwei LEDs meinst, musst Du ja eigentlich nur GPIO0 oder 2 passend setzen.

          Gruss Stefan

          Antworten
          1. Nik

            Hi Stefan,

            danke für deine schnelle Antwort. Hab den Code jetzt angepasst, sodass sich die Hintergrundfarbe entsprechend rot für aus und grün für an ändert. Ebenso habe ich hinzugefügt, dass der Status beim aktualisieren angezeigt wird, sozusagen eine Rückmeldung ob zum Beispiel das Relais gerade an oder aus ist.
            Komisch ist nur, dass der Code bei meinem Netzwerk nur funktioniert, wenn ich den esp gerade geflasht habe. Unterbreche ich den Strom des esp kurzzeitig oder auch länger, so verbindet dieser sich nicht mit meinen vorher eingestellten Netzwerk. Ich muss ihn immer wieder neu flashen. Ist auch bei deinem originalen Code so. Hast da evtl. eine Idee woran es liegen könnte? Habe ca. 3 Verbindungen mit unterschiedlichem Namen getestet.

            Danke

          2. ST Beitragsautor

            Das Problem existiert in meinem Code nicht. Ich vermute mal stark, dass Du noch Codeanteile aus dem referenzierten Code an Bord hast. Dort wird SSID/Passwort aus dem EEProm gelesen. Könnte sein, dass beide Mechanismen in Konflikt kommen. Vorschlag: Bau mal eine Debug Ausgabe auf der Seriellen sein, die SSID und Passwort ausgibt direkt bevor die Strings an das SDK übergeben werden (also vor dem Kommando WiFi.begin(ssid, password); – und von dem Kommando sollte es auch nur eines geben 🙂 ).

            Viel Erfolg
            Stefan

  6. Markus

    Bin beim googeln auf diesen Beitrag gestoßen. Ich finde das Programm läuft sehr gut. Allerdings scheint der ESP beim booten die GPIO’s anzusteuern. Dies merkt man am flackern einer angeschlossenen LED oder am kurzen zucken eines Relais. Wenn man nun z.B. ein Garagentor mit dieser Schaltung öffnen möchte, kann es durch diesen Effekt nach einem Spannungsausfall beim wiederkehren der Spannung zu ungewollten Schaltfunktionen kommen. Hat hierzu jemand eine Lösung? Eine Wiedereinschaltsperre durch z.B. Selbsthaltung ist nicht erwünscht. Man müsste den ESP dann manuell wieder starten, was bei einem Garagentor ja unsinnig ist wenn ich es von Außen öffnen will.

    Antworten
    1. ST Beitragsautor

      Interessanter Hinweis. Ich hatte bisher noch keine Schaltung bei der das relevant war. Der Code für das Toggeln von GPIO2 muss im Bootloader sitzen.

      Spontan fallen mir folgende Möglichkeiten ein:
      1. Du nimmst zusätzlich einen Arduino wie in diesem Beispiel zur Markisensteuerung. Das geht definitiv:
      https://blog.thesen.eu/funk-wlan-markisensteuerung-mit-esp8266-und-arduino/

      2. Du baust Dir eine Einschaltverzögerung; z.B. mit einem NE555. Dann gehen nur Pulse durch, die nach einer gewissen Zeit nach dem Einschalten kommen. Die Lösung könnte aber fehleranfällig sein, falls der ESP abstürzen sollte und dann ggf in einen Reset läuft.

      3. Du nimmst einen Feinlötkolben und traust Dich, die weiteren GPIOs anzuschließen und zu nutzen
      http://www.notey.com/external/4711832/more-gpios-for-the-esp8266-hacking-esp-solder-microcontrollers-soldering-esp8266-gpio.html
      Ich kenne das Bootverhalten der anderen GPIOs nicht. Mich würde es aber wundern, wenn alle GPIOs beim Bootvorgang schalten.

      Antworten
      1. Markus

        Danke für die Vorschläge; ich habe mir ein paar ESP8266 E07 bestellt, bei denen alle GPIO’s nach außen geführt sind. Sobald diese eingetroffen sind werde ich es mit einem anderen GPIO versuchen.
        Über Erfolg oder Misserfolg werde ich dann an dieser Stelle berichten!
        Die Sache mit dem Timer hatte ich auch schon überlegt, bin aber auch der Meinung dies könnte Fehleranfällig sein ( Und das soll es ja nicht ).
        Sicherlich ist die Lösung mit dem Arduino eine gute Alternative; der Reitz liegt aber in der minimalen Größe eines ESP………

        Antworten
        1. Max

          Hallo Stefan,

          erst mal vielen Dank für diesen sehr gut arbeitenden Code. habe in jetzt erstmal zum testen laufen und er funktioniert super!

          @Markus:
          Hast du mitlerweile eine Lösung für das Problem gefunden? Mein Ziel ist genau diese Garagentorsteuerung und möchte halt auch ungerne das sich das Tor nach einem Stromausfall automatisch öffnet.

          Liebe Grüße

          Max

          Antworten
          1. ST Beitragsautor

            Nimm einen Arduino dazu – wie bei der Markisensteuerung im Blog. Oder gehe auf einen ESP8266-12. Der hat mehr GPIOs. Auf beide Methoden hast Du ein definiertes Einschaltverhalten und bist das Spezialverhalten von GPIO0&2 los.

            Gruss Stefan

          2. Andy

            für genau sowas bau ich mir ein lage (gyroskop) sensor mit ein. damit weis ich wie das tor steht.
            und bin auch am überlegen ob ich noch eine kollesionskontrolle via utraschallsensor mit verbauen soll. nicht das des tor zugeht obwohl was in der einfahrt ist

        2. Markus

          Hallo ;
          Ich habe versprochen mich noch einmal zu melden!
          Zunächst die schlechte Nachricht: Auch mit anderen ESP’s gibt es den gleichen Effekt. Egal welchen GPIO man nimmt (Habe es an ESP12/12e getestet) das kurze Ansteuern des Ausgangs auf High-Pegel bei der Spannungswiederkehr ist auch dort zu beobachten.
          Eine elektronische Lösung für das Problem könnte ich mir z.B. mit einem RS-Flip-Flop in der Spannungsversorgung des Relais vorstellen (der kurze Impuls setzt das Flip-Flop welches dann am Ausgang dauerhaft schaltet. Hier würde ich dann die Spannung für das Relais abgreifen das dann über den GPIO gesteuert wird. Bei Spannungsausfall würde zunächst wieder das Flip-Flop angesteuert und erst dann wäre ein Schalten des Relais möglich.)
          Da mich aber die Größe des ESP fasziniert suche ich nach Lösungen die keine große Zusatzbeschaltung nötig machen. Gibt es eventuell auch eine Softwarelösung ?

          Antworten
          1. ST Beitragsautor

            HI Markus,

            ich habe das mit einem ESP8266-12e und GPIO12 probiert. Die GPIOs scheinen beim Start als Input konfiguriert und offenbar hat der ESP einen hochohmigen internen Pullup. Ich habe eine LED mit einem 470Ohm Widerstand angeschlossen – man sieht, dass die LED beim Start ganz leicht glimmt und dann ausgeht, weil ich den GPIO12 in setup() auf low setze.
            Damit sollte sich Dein Problem doch lösen lassen: Probier mal einen Pulldown Widerstand von 1kOhm gegen Masse.

            Gruss Stefan

          2. Markus

            Hl Stefan
            Die Lösung scheint noch einfacher. Die GPIO’s des ESP haben nach dem Booten alle high-Level. Wenn man im Setup den benötigten GPIO auf high statt low setzt
            geht die LED erstmal nicht mehr aus. Dies ist nicht schlimm, da ein zwischengeschaltetes Relais jetzt anzieht.
            „Baut“ man sich im HTML-Teil nun einen Taster (einschalten, kurzes delay, ausschalten) wird das Relais beim ersten Tastendruck zwar nochmals eingeschaltet (bewirkt aber nichts da schon angezogen) und dann abgeschaltet.
            Ich werde diesen Versuchsaufbau nun einmal zusammenlöten und für einige Tage testen.

            Gruß Markus

          3. ST Beitragsautor

            Hi Markus,

            kannst Du so machen, wenn der Eingang des Relaisboards hochohmig ist. Bei den typischen Arduino Relaisboards ist das der Fall.
            Wenn man es richtig anstellt, ist aber sowohl high als auch low als Startzustand machbar.
            high: hochohmiger Eingang
            low: Pulldown ca 1kOhm mit hochohmigem Eingang oder niederohmiger Eingang.

            Mit dem hochohmigen Ansatz und einem default auf high ist auch GPIO0 verwendbar. Da bootet der ESP ja sauber und danach kann GPIO0 als Ausgang genutzt werden.

            Gruss Stefan

          4. Markus

            Hl Stefan
            Also meine Idee mit dem high-Status im Setup funktioniert zwar aber es gibt doch ein kleines Problem:
            Bis der ESP gebootet hat und das Relais anzieht vergeht ja eine gewisse Zeit im Millisekunden-Bereich. Leider ist mein Garagentor schneller „gebootet“ und es öffnet beim erstmaligen anziehen des Relais. 🙁
            Ich habe nun Deinen Vorschlag mit dem Pulldown-Widerstand probiert und die Schaltung funktioniert ohne Probleme. (Pulldown-Widerstand ca.15kOHM an ESP12e GPIO5)

            Gruß Markus

  7. Turte

    Hallo,

    die Kommentare hören sich ja alle viel versprechend an.

    Wenn ich das Beispiel richtig verstehe versucht sich der ESP 8266 in einem vorhanden Wlan Netz einzubinden.
    Ich würde das Modul jedoch gerne als Accesspoint benutzen.
    Ist das auch möglich?
    Wie muß die Software dann geändert werden?

    Herzlichen Dank

    Turtle

    Antworten
    1. ST Beitragsautor

      Hi Turtle,

      Dein Kommentar erinnert mich daran, dass ich das ja immer mal ausprobieren wollte. Hier mal ein Codestückchen ins „Blaue“. D.h. ich habe es nicht selbst probiert.

      Suche im Code folgende Stelle:
      // inital connect
      WiFi.mode(WIFI_STA);
      WiFiStart();

      Ersetze die Zeilen mit diesem Code:
      // AP mode
      WiFi.mode(WIFI_AP);
      WiFi.softAP("MyAccessPoint", "MyPassword");
      server.begin();

      Weiterhin suche in der Routine loop diese Zeilen:
      // check if WLAN is connected
      if (WiFi.status() != WL_CONNECTED)
      {
      WiFiStart();
      }

      und lösche sie komplett.

      Ich hoffe es klappt.

      Gruss Stefan

      Antworten
  8. User

    Hallo,
    vielen Dank für die ausführliche Beschreibung. Ich bin auf der Suche nach einem Wifi-WebServer der wirklich standalone ist, sprich sich keine IP von einem Router holt, sondern eine feste IP hat.

    Antworten
    1. ST Beitragsautor

      Hmm, willst Du das was der Vorredner auch haben wollte und wozu ich die Codefragmente gepostet habe? – Also einen Accesspoint – so klingt Teil 1 des Wunsches.
      Oder eine statische IP in einem Netzwerk? – So klingt Teil 2.

      Antworten
  9. Marcus

    Vielen Dank für diesen Artikel und den mit dem Server als AP!
    Der Server mit AP funktioniert prima. Erstaunt bin ich über die Reichweite dieser kleinen Module, trotz dieser primitiven Antenne.
    Nur mit dem Code für den ESP als WLAN-Client habe ich Probleme. Er will sich nicht mit meinem Netz verbinden. Wirkt die Funktion WIFI.localIP als DCHP-Client oder muss ich im Code noch eine IP-Adresse festlegen?

    Viele Grüße
    von
    Marcus

    Antworten
    1. ST Beitragsautor

      Hallo Marcus,

      das Beispiel hier verbindet sich mit einem WLAN und bekommt die IP per DHCP. Damit musst Du keine IP festlegen. Probleme hatte ich mit dem Code und ähnlichen Varianten bisher nicht. Konkret habe ich an mehrere Fritz Boxen, einen Archer C7 und einen Telekom 724V problemlos verbinden können.
      Passwort hast Du im Code gesetzt? – SSID ist sichtbar? (war bisher bei allen Routern so).

      Gruss Stefan

      Antworten
      1. Marcus

        Ich hatte meine SSID und das dazugehörige Passwort eingetragen. In der WLAN-Liste war der ESP auch dabei, hat aber keine IP-Adresse erhalten. In der Fritzbox gab es den Eintrag, WLAN-Anmeldung gescheitert, ungültiger WLAN-Schlüssel. Die Schlüssel waren aber identisch. WPA2 macht der ESP sicher auch?

        Marcus

        Antworten
        1. ST Beitragsautor

          Das klingt mir nach „wilden“ Sonderzeichen im Passwort. Wenn Du Sonderzeichen in der Arduino IDE eingibst, werden dieser mit UTF8 kodiert und so in das Binary übertragen. Das wiederum geht dann bei der Übertragung vom ESP and den Router schief. Es gibt im Internet längere Diskussionen darüber, welche Sonderzeichen im Passwort o.k. sind.
          Mach mal einen Test mit einem einfachen WLAN Passwort im Router. WPA2 geht definitiv.

          Gruss Stefan

          P.S.: Wenn Du das konkrete Problemsonderzeichen identifiziert hast, könnte man es ggf als Escape Sequenz in den Passwort String kodieren. Käme auf einen Versuch an.

          Antworten
          1. Marcus

            Entwarnung: Es hatte sich doch böser Fehler im Passwort eingeschlichen. Funktioniert jetzt wunderbar!

            Vielen Dank!

  10. Benjamin

    Hi!

    Ich wollte mal eben Danke sagen das du deinen Code veröffentlicht hast! Bin nicht wirklich weiter gekommen als ich einen Server aufbauen wollte. Danke deines Codes konnte ich mir ein tolles Automation System aufbauen.

    Weiter so!

    Gruß Benjamin

    Antworten
  11. Gerd

    Hallo,

    Dein Script läuft bei mir ohne Probleme, vielen Dank. Folgendes wollte ich realisieren, habe es aber nicht hinbekommen:

    mit dem HTML-Element input type=range wollte ich drei Schieberegler haben, die am Nodemcu 1.0 eine RGB-LED per PWM ansteuern. Die Anzeige im Browser kriege ich hin, aber ich habe nicht gefunden, wie ich die Werte am Server auslesen kann, am Besten, ohne einen Submit-Button im Browser zu drücken. Wo finde ich für sowas Dokumentation? selfhtml hat mir nur halb geholfen.

    mfg
    Gerd

    Antworten
    1. ST Beitragsautor

      Ich bin kein html/Javascript Experte. Ich meine aber, dass Du dafür html5 oder Javascript nehmen musst und dann die Daten z.B. per post schicken kannst.

      Antworten
        1. Gerd

          Hallo,
          folgendes habe ich eingebaut:

          sResponse += „ESP8266 MAINS Power Dimmer Controller\n“;
          sResponse += „\n“;
          sResponse += „\n“;
          sResponse += „ON \n“;
          sResponse += „OFF\n\n“;
          sResponse += „Dimmer Value: „;
          sResponse += „(status)“;
          sResponse += “ pts
          \n“;
          sResponse += „\n“;
          sResponse += „function outputUpdate(dim) {document.querySelector(\“#cmd\“).value = dim;“;
          sResponse += „document.forms[0].submit();}\n“;

          Das hab ich mir aus dem Lua-Script rauskopiert, welches Du mir verlinkt hattest. Sobald ich den Schieber bewege, läuft die Seite in einen Seiten-Ladefehler. Keine Ahnung… bin sowohl mit C++ als auch HTML eher unerfahren. Deshalb nochmal die Frage nach Dokumentation, wie ich in C++ das Post abfange (bzw. welche Parameter wie empfangen werden können, den String bekomme ich dann auseinander genommen).
          Und weshalb die Seite hängen bleibt, verstehe ich auch nicht.

          mfg
          Gerd

          Antworten
          1. ST

            Hi Gerd,

            da hast Du einfach Java Code mitten in den html Code gepackt. Das kann nicht klappen. Wie in dem Beispiel muss da ein Script Element angelegt werden. Schau nochmal in den Beispielcode.

            Gruss Stefan

          2. Gerd

            Hallo Stefan,

            ganz so schlimm sind meine Kenntnisse zum Glück doch nicht. Das Problem ist wohl beim kopieren in den Kommentar passiert, ich versuche mal den entstandenen HTML-Code zu posten: (direkt vom Quellcode aus dem Browser)
            —snip—
            ESP8266 MAINS Power Dimmer Controller

            ON
            OFF

            Dimmer Value: 50 pts

            function outputUpdate(dim)
            {document.querySelector(„#cmd“).value = dim;
            document.forms[0].submit();}

            —–snip——-
            Das ist nur der zusätzlich zu Deinem Code eingefügte Teil. Die Funktionalität Ein/Aus der LED funktioniert weiterhin. Die 50 kommt aus einer int status=50; Definition. Da beim Verschieben des Reglers der Seiten-Ladefehler auftritt, kann ich im Code nichts testen.

            mfg
            Gerd

  12. Juergen

    Hallo

    finde deinen Webserver sehr gut
    Ich habe da ein paar fragen
    Habe eine Haussteuerung auf dem Mega und moechte sie mit dem ESP 8266
    im Wlan haben nun kenne Ich mich mit dem Esp nicht aus
    habe einen Webserver auf dem Mega
    wie und wo kann Ich die HTLM-Befehle in deinen Webserver eintragen
    gibt es da eine Anleitung
    was bedeutet sResponse += ist das nur ein Stringname oder eine Funktion

    bye juergen

    Antworten
    1. ST Beitragsautor

      Die Programmierung des Esp mit der Arduino IDE lehnt sich ganz stark an die des WiFi Shields an.
      sResponse ist ein Standard Arduino String Objekt (genau genommen ist sResponse eine Instanz der Klasse String und damit weder Funktion noch Datentyp) . Mit += werden Daten zum String hinzugefügt. In dem entsprechenden Codeteil baue ich den HTML Code auf.

      Antworten
  13. Mario

    Hallo,
    erstmal vielen Dank für den Servercode.
    Den konnte ich für mein Projekt einsetzen und anpassen.

    Jetzt gibt es nur Probleme mit leeren Empfangsstrings wenn der anfragende Client ein Android-Gerät ist.
    Bei 70% der Anfragen bekomme ich einen Leerstring auf den Server und der Server schließt die Verbindung.
    Das sieht dann im Terminal so aus:

    new client
    — Start empfangener Daten—

    — Ende empfangener Daten—
    empty request! – stopping client

    Von meinen PCs im Netzwerk funktioniert jede Abfrage, egal welcher Client.
    Irgend jemand eine Idee?

    Viele Grüße,
    Mario

    Antworten
    1. ST Beitragsautor

      Hallo Mario,

      ich kenne den Effekt so nicht. Ich nutze den Code (bzw abgeleiteten Code) mit 4 Android Geräten (S5, Nexus 10, HTC One Mini, Xperia Mini Pro). Ich gehe also nicht davon aus, dass es etwas generell Android-spezifisches ist. Es ist auch egal, ob ich den mitgelieferten Browser oder Chrome für Android nehme.

      Eventuell hast Du eine altes Espressif SDK installiert. Die Arduino IDE sollte Dir im Boardmanager ggf ein Update anbieten. Eventuell hilft auch eine Deinstallation / Neuinstallation des ESP Supports.

      Manuell kannst Du die SDK Version hier nachsehen (Pfad nur ungefähr – hängt von Deinem Rechner ab):
      C:\Users\Dilbert\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\tools\sdk
      Dort die Datei version ansehen. Darin steht bei mir die SDK Version 1.2.0_15_07_03. Es gibt mittlerweile auch eine 1.4…

      Ansonsten schau mal mit Serial.println(sRequest); nach, was kommt (oder auch nicht :-).

      Gruss Stefan

      Antworten
      1. Mario

        Hallo Stefan,
        Danke für die schnelle Antwort.
        SDK-Version habe ich geprüft, ist die gleiche 1.2.0_15_07_03 die Du genannt hast.
        Es muss auch nicht am Android liegen, tritt aber bei mir nur bei mobilen Geräten auf.

        Bei den Anfragen kommt im ESP8266 nur ein leerer Request an.
        In Deinem Code hast Du eine Abfangroutine für leere Requests drin. Genau diese greift dann und trennt den Client.

        Ich werde mal das SDK 1.4 versuchen.

        bye
        Mario

        Antworten
        1. ST Beitragsautor

          Wie schon gesagt : das Sdk 1.2 ist bei mir absolut stabil. Ich habe damit u.a. eine Markisensteuerung realisiert. Die hat noch nie einen Reset gebraucht.
          Wenn es nur mit den Mobilgeräten auftritt, tippe ich auf die Netzkonfig (WLAN oder per Mobilfunk und Portforwarding?). Bei mir klappt das Ganze auch per VPN etc.

          Gruss Stefan

          Antworten
          1. Mario

            Hallo Stefan,

            habe jetzt das SDK 1.3.0_15_08_10_p1 installiert.
            Damit kommen bis jetzt keine leeren Requests mehr an.
            Die Ursache konnte ich, trotz Wireshark-Einsatz, nicht finden.
            Die HTTP-Anfragen waren immer korrekt.
            Mein Projekt ist übrigens eine Rolladensteuerung für 8 Fenster.
            Angeschlossen an die Ausgänge des ESP8266 sind die Tasten eines 16-Kanal-Funksenders von Jarolift.
            bye,
            Mario

  14. Mike

    Guten Abend alle zusammen…

    Als erstes muss ich mich für deinen tollen Blog bedanken. Dieser hat
    mir den nötigen Durchbruch bei meinem ESP8266-Projekt
    gebracht! Auch das implementieren der Status-Anzeige auf der
    Seite ist ohne Probleme kompiliert und geflasht worden.
    Doch jetzt versuche ich, noch eine Pin-Abfrage zu realisieren,
    welche praktisch den Ausgabeport toggelt. Die nötige Funktion
    hatte ich in der „void loop“-Schleife, doch der Code wird dabei nur
    beim Statuswechsel auf der Webseite mit ausgeführt.
    Könnt ihr mir weiterhelfen?
    Macht weiter so!!
    Fg
    Mike

    Antworten
  15. BT

    Hallo Stefan, danke für diesen Code. Ist echt hilfreich !!

    Warum hast Du bei ultimeout eigentlich 250 millisecs als timeout gewählt? Die Browser sind doch da eher im Sekundenbereich unterwegs.

    Laut Arduino-Doku springt millis() nach ca. 50 Tagen zurück auf 0. Ist zwar ein unwahrscheinlicher Fall genau da reinzulaufen, aber ich glaube dadurch kann die Stelle mit ultimeout bei einem overflow innerhalb der while-Schleife ihre Wirkung verfehlen. Was hältst Du von der Anpassung unten, um das zu umgehen?

    Du stoppst außerdem immer den client bevor Du aus der loop springst, nur dort nicht. Habe ich daher auch eingefügt. Sinnvoll?

    VG, bt

    // Anpassung
    unsigned long ulStartedWaiting = millis();
    while(!client.available()){
    delay(1);
    if(millis() (ulStartedWaiting + 250)) {
    client.stop();
    return;
    }
    }

    Antworten
    1. BT

      grrr. beim Hochladen hat es mir den code-vorschlag Erneuter Versuch:

      unsigned long ulStartedWaiting = millis();
      while(!client.available()){
      delay(1);
      if(millis() (ulStartedWaiting + 250)){
      client.stop();
      return;
      }
      }

      Antworten
  16. BT

    Hmm. der Code ist wieder beim Hochladen verhunzt. Vielleicht siehst Du den Upload trotzdem korrekt. Sonst hier die Idee als prosa:

    – millis vor der while schleife abfragen und als ulStartedWaiting speichern
    – in der while schleife
    * zunächst delay(1) ausführen
    *dann prüfen ob millis hier jetzt kleiner ist als ulStartedWaiting. Falls ja gab es einen Overflow, dann das neue millis auf ulStartedWaiting setzen
    * jetzt prüfen ob millis größer ist als ulStartedWaiting + 250. Falls ja, hat der timeout gegriffen, dann client.stop und return

    Antworten
  17. mistro

    Hallo und vielen Dank für den Klasse Code.
    Ich wollte einen Webserver mit dem ich zwei Relais schalten kann und das hat mit Deinem Code und einen kleinen Umbau auch gut funktioniert.
    Nun aber zu meinen Wunsch. Es wäre toll nicht nur über Web zu schalten sondern extra auch über mechanische Taster. Wie baut man die in den Code, bei gleichzeitig Zustandsanzeige über Web.
    VG

    Antworten
    1. ST Beitragsautor

      Wenn Du zwei Relais schalten willst und noch zwei Taster anschließen möchtest, dann brauchst Du 4 GPIOs: 2x Relais, 2x Taster
      Prinzipiell geht das auch mit dem kleinen ESP8266-01 Modul, wenn Du RX und TX als GPIOs nutzt. Das geht mittels pinmode. RX/TX sind als GPIO 1 und 3 nutzbar (z.B. pinmode(1,INPUT); ). Du musst den ESP dann aber sockeln und auf eine Programmierplatine umstecken, damit Du RX/TX zum programmieren korrekt angeschlossen hast.

      Der Code für die Taster geht dann analog zum Arduino Tutorial für Taster:
      https://www.arduino.cc/en/tutorial/pushbutton

      Wie im Beispiel deklarierst Du Dir zwei globale Variablen für den Zustand der Relais und initialisierst diese. Wenn Du den ein Relais über Taster oder Webif änderst, änderst Du auch die Variable. Den Wert der Variablen gibst Du im WebIF aus.

      Viel Erfolg
      Stefan

      Antworten
  18. Peter Kretschmer

    Hallo Stefan,
    zu nächst einmal herzlichen Dank für die Bereitstellung der Informationen – einfach Klasse!
    Habe mittlerweile den Blog ausführlich gelesen und mir ein paar ESP8266-01 Module zugelegt.
    Der Code mit ESP als Access Point funktioniert einwandfrei, doch bei der Einbindung als Webserver in das bestehende WLAN stoße ich an meine Grenzen. Es gelingt mir einfach nicht, das Modul an der Fritzbox 7490 anzumelden. Ich habe die SSID und das Passwort korrekt im Code eingetragen, doch es erscheint nach Programmstart die Meldung, Verbindung zu Fritzbox 7490 wird hergestellt, dann erscheinen die Punkte aber das Modul wird in der Fritzbox nicht aufgeführt.
    Evtl. gibt es eine triviale Erklärung dafür, ich würde mich jedenfalls sehr freuen, wenn jemand eine Antwort zur Lösung des Porblems hätte.

    Vielen Dank im Voraus
    Grüße, Peter

    Antworten
    1. ST Beitragsautor

      Hallo Peter,

      Schau bitte mal nach, was parallel im WLAN Eventlog auf der Fritzbox erscheint. Eventuell ist das aufschlussreich.
      Ich tippe auf zwei mögliche Ursachen:
      1. Du hast in der Fritzbox eingestellt, dass keine neuen WLAN Geräte erlaubt sind.
      2. Eventuell hast Du Sonderzeichen im WLAN Passwort. Vermutlich werden nicht alle Sonderzeichen über die Arduino IDE korrekt umgesetzt. Du müsstest ggf mit Esc Codes im String arbeiten. Die Fritzbox sollte dann ein falsches Passwort melden. Probiere dann bitte mal ein einfaches WLAN Passwort auf der Fritzbox aus. Damit kannst Du das Problem ggf einkreisen.

      Gruss Stefan

      Antworten
      1. Peter Kretschmer

        Hallo Stefan,

        danke für die schnelle Antwort.
        Ich habe die Einstellungen geprüft, soweit alles i.O., also keine Sonderzeichen im PW und neue Geräte werden auch in der Fritz!Box zugelassen.
        Ich habe parallel versucht, die Verbindung über einen Hotspot mit meinem Mobiltelefon herzustellen, doch da ist die gleiche Situation – Verbindungsversuch, aber keine Verbindung.
        Wenn ich den Code „WifiScan“ hochgeladen habe, dann werden alle meine WLAN Netzwerke angezeigt.

        Ich vermute, es liegt am Modul und werde zunächst ein anderes probieren.

        Grüsse, Peter

        Antworten
  19. Peter Kretschmer

    Hallo Stefan,

    ich komme leider nicht weiter.
    Hab mittlerweile 5 Module ESP8266-01 ausprobiert – ohne Verbindung zur Fritzbox. Hab es dann mit einem neuen ESP8266-E12 versucht, auch ohne Erfolg.
    Letztendlich habe ich versucht, mich mit dem WLAN meiner „alten“ Fritzboxen 7270 und 3390 zu verbinden, auch das hat nicht funktioniert. Andere Geräte können problemlos angemeldet werden.
    Bei allen Modulen habe ich den Code „ESP als AP“ probiert, alles i.O.

    Das PW der Fritzbox hat 16 Ziffern, also keine Sonderzeichen. Bei der SSID habe ich auch schon alles Mögliche probiert, ohne Leerzeichen, ohne Ausrufungszeichen oder nur den Typ eingetragen, leider ohne Erfolg.

    Würde mich freuen, wenn es eine Lösung für mein Problem geben würde. Evtl. eine versteckte Funktion, die ich nicht kenne?

    Trotzdem wünsche ich ein tolles Osterfest und alles Gute.

    Grüße,
    Peter

    Antworten
    1. ST Beitragsautor

      Hallo Peter,

      Das muss irgendeiner dieser blöden kleinen Fehler sein, die man einfach nicht sieht. Lass uns nochmal versuchen es einzukreisen: wenn sich der Esp versucht auf der Fritz.box einzuloggen, siehst Du dann auf der fritz.box irgendetwas im Log?
      Und nochwas: ch_pd Pin ist angeschlossen?
      Gruss Stefan

      Antworten
  20. Peter Kretschmer

    G E S C H A F F T !!!!

    Vielen Dank Stefan für die Hinweise und die Geduld!

    Ich bin alles noch einmal durchgegangen, und in der Tat war es „nur“ ein Anmeldeproblem.
    Der Fehler lag darin, dass ich bei der SSID anstelle von FRITZ!Box 7490, Fritz!Box 7490 eingetragen hatte.
    Vielleicht hilft diese Info anderen, die ebenfalls Schwierigkeiten bei der Anmeldung ins WLAN haben.
    Werde mich jetzt an die ersten Projekte ranmachen, und mich zu gegebener Zeit wieder melden.

    Grüße,
    Peter

    Antworten
  21. icke

    läuft 1a !! bestes beispielprogramm im netz ! habe echt ne woche lang probiert und gemacht und getan aber das hier hat mir echt gut weitergeholfen !

    wichtig zu wissen ist bei der Programmierung mit nem ESP 12e, dass mehr als 2 map befehle das ding schon zum absturz bringen können… werde mal die freememory library mit raufklatschen und gucken ob der map befehl so aufwendig speichert vollmacht…

    Antworten
    1. ST Beitragsautor

      Keine Ahnung, was Du da angelegt hast 🙂
      Bei meinen Webserver Sketches ist typischerweise mehr als 40kB RAM frei. Man kann sicherlich nicht alles allokieren ohne das Framework zu ärgern. Aber 20-30k sind locker noch drin.

      Antworten
  22. Günter Lintzmeyer

    Hallo Stefan
    betr.:
    HTTP 1.1 Webserver for ESP8266
    for ESP8266 adapted Arduino IDE
    Stefan Thesen 04/2015

    Ich habe diesen Code auf den ESP8266 geladen, ausprobiert und konnte mittels Web-Browser
    den Server aufrufen und die jeweilige Funktion anklicken.

    Jetzt habe ich mich sehr intensiv in den Code eingelesen…., habe zwar noch nicht alles verstanden
    (bin absoluter Newcomer auf diesem Gebiet) ; deshalb habe deshalb heute zunächst mal 3 Fragen:
    1.
    ich kann keine Stelle im Code finden, wo eine serielle Ausgabe (über den TX-pin) stattfindet
    bzw. ich konnte es evtl. auch (noch) nicht richtig interpretieren.
    2.
    ist es richtig dass im Code nur die FUNKTION1 (ON / OFF) ausgewertet wird ?
    Oder ich habe auch hier etwas überlesen… ?
    3.
    die blaue LED auf dem ESP8266 blinkt beim Anklicken einer Funktion jeweils 2 x
    wie wird das Blinken ausgelöst ?

    Für eine weitere erfolgreiche Einarbeitung wäre ich dir für eine Antwort sehr dankbar.

    Günter

    Antworten
    1. ST Beitragsautor

      Hallo Günter,

      dann versuchen wir mal unser Glück 🙂
      zu 1: die Ausgabe gehen per Serial.print bzw println raus. Genau so wie bei Arduino selbst.
      zu 2: Die Funktion 1 wird ausgewertet. Funktion 2 steht nur im seriellen Log. Erweitere den Code entsprechend.
      zu 3: die blaue LED wird von Libs in der Arduino IDE gesteuert. Was da blinkt kommt also nicht aus dem Code, den Du siehst. Auf dem ESP8266-12 kannst Du die blaue LED auch selbst kontrollieren; müsste eigentlich auch bei dem kleinen ESP gehen. pinMode(2, OUTPUT) und dann mit digitalWrite auf GPIO 2.

      Viel Erfolg
      Stefan

      Antworten
  23. Günter

    Hallo Stefan

    mit folgender Fehlermeldung wird die Compilierung in der Arduino-IDE abgebrochen

    exec: „C:\\Users\\Guenter\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\esptool\\0.4.9/esptool.exe“: file does not exist
    Fehler beim Kompilieren für das Board Generic ESP8266 Module.

    wo bekomme ich das fehlende File ?

    Kannst du mir weiterhelfen ?

    vielen Dank im Voraus

    Gruß
    Günter

    habe bereits die Arduinoi-IDE deinstalliert, neu „runtergeladen“ und installiert: >>>gleicher Fehler

    Antworten
    1. ST Beitragsautor

      Hallo Günter,

      ich kenne den Effekt nicht. Installiere mal die ESP Umhebung neu (nicht die Arduino IDE). Ggf mal unter packages den kompletten ESP8266 Verzeichnisbaum löschen.

      Gruss Stefan

      Antworten
  24. Holger

    Hi!
    Danke für die super Anleitung, aber ich erhalte einen Fehler beim kompelieren des Codes:

    In file included from C:\Users\USERNAME\OneDrive\Dokumente\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFiSTA.h:28:0,

    from C:\Users\USERNAME\OneDrive\Dokumente\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFi.h:34,

    from C:\Users\USERNAME\AppData\Local\Temp\Rar$DIa0.301\ESP_Webserver_HTTP11\ESP_Webserver_HTTP11.ino:23:

    C:\Users\USERNAME\OneDrive\Dokumente\Arduino\libraries\ESP8266WiFi\src/ESP8266WiFiGeneric.h:27:22: fatal error: functional: No such file or directory

    #include

    ^

    compilation terminated.

    exit status 1
    Fehler beim Kompilieren für das Board Arduino/Genuino Mega or Mega 2560.

    Hast du eine Idee, was da los ist? Danke vorab!

    Antworten
    1. ST Beitragsautor

      Hallo Holger,

      Der Code ist für einen Esp8266 und bindet Esp spezifische Header Dateien mit ein. Das kann nicht klappen.
      Mit dem Mega sollte es in ähnlicher Weise gehen, wenn Du ein WiFi oder LAN Shield ergänzt und die Libs umstellst. Habe ich aber noch nie gemacht.

      Gruss Stefan

      Antworten
  25. Lutz

    Hallo Stefan
    Ich komme gut mit Deiner Anleitung klar. Für mich ist es ein super Einstieg .
    Gibt es eine Möglichkeit, dass sich die Webseite aktualisiert wenn sich der Zustand eines Eingangs ändert.
    Den Zustand auf der Seite anzeigen kann ich, aber nur wenn ich F5 oder einen anderen Button drücke.
    Ich möchte den Status einer Waschmaschine (fertig LED) abfragen/anzeigen.

    Danke
    Lutz

    Antworten
    1. ST Beitragsautor

      Der Code läuft auch auf einem NodeMCU. Bei dem sind nur die Pins anders benannt. Such mal nach „esp8266 nodemcu pinmapping“ auf google.

      Gruss Stefan

      Antworten
  26. Günter

    Hallo Stefan
    folgende Situation
    1 Server (als AP) / 2 Clients (späterhin 4)

    Code_Snipsel (Client)
    client.print (String(„GET „) + „HTTP/1.1\r\n“ +
    „Host: “ + „178.168.4.1“ + „\r\n“ +
    „\r\n\r\n“);

    Server soll Daten (derzeit 1 Byte) an die beiden Clients senden;

    Code_Snipsel (Server)
    if (client.connected()) {
    test = test + 1;
    client.print (test);}

    Daten kommen teilweise unregelmäßig an; zwar manchmal in beiden Clients korrekt; aber vielfach nur in einem der beiden (abwechselnd)

    Welche Möglichkeiten der Steuerung (Absicherung) muss berücksichtigt werden, damit in beiden Clients die Daten korrekt ankommen (müssen nicht gleichzeitig ankommen — aber Übertragung muss sicher stattfinden !!!)

    vielen Dank im Voraus
    Günter

    Antworten
    1. ST Beitragsautor

      Hallo Günter,

      schau mal in den Code für das Telnet2Serial Interface. Da werden mehrere Clients „abgearbeitet“; die Code merkt sich dabei die verbundenen Clients in einem Array und sendet dann die Daten in einer Schleife an alle Clients. Das dürfte mehr dem entsprechen, was Du suchst.
      Die Webbrowser Code arbeitet einen Client ab und schließt die Verbindung. Das ist für Dein Problem vermutlich nicht der richtige Ansatz.

      Viel Erfolg
      Gruss Stefan

      Antworten
  27. Dominikus Koch

    Vielen Dank für diesen super Server 🙂 Ich hatte vorher das Licht in der Wohnung über Bluetooth geschaltet aber der HandShake hat mir zu lange gedauert. Es wurden mehrer BT Geräte beim Start der App verbunden, kein LowEnergy BT sondern das „alte billige“. Nach der Umrüstung auf WiFi ist mir der Esp aber immer nach ein paar Stunden abgeschmiert – jetzt läuft die Licht und Medien Steuerung sehr schnell und stabil — vielen Dank dafür. PS um möglichst viele Relais schalten zu können kommuniziert ein Esp mit einem Arduino Mini Clone über die serielle Schnittstelle – das klappt wunderbar und gibt keine ungewollten Zuckungen beim Reboot. Die alten Mediengeräte (Stereoanlage und Beamer) steuere ich über einen weiteren Esp an dem einfach eine IR Diode als Fernbedienungsersatz hängt. Somit habe ich mein Smarthome mit App Steuerung für unter 15€ 🙂

    Antworten
  28. Jan

    Hallo Stefan,

    fürs erste einen lieben Dank für das Beispiel. Hat Prima geklappt das ganze zu verändern und einzubinden.
    Ich habe das Bespiel für einen Lichtwecker mit RGB LED-Stripes benutzt und es klappt temporär sehr gut.
    Mein Problem ist, dass ich die HTTP Oberfläche des Nodemcu nach dem Starten mit dem Android-Smartphone erreichen kann,
    diese immer wieder unterschiedlich nach 12 bis 36 Stunden nicht mehr ansprechbar ist.
    Anhand der programmierten LEDs und der UART Schnittestelle kann ich feststellen, dass der ESP noch läuft und die localIP() funktion
    gibt mir die passende IP, die ursprünglich vom DHCP des Technicolor-Routers (Unitymedia) vergeben wurde.
    In der Oberfläche des Routers taucht der ESP unter „DHCP Clientgeräte“ allerdings nach besagtem Zeitinterval nicht mehr auf (vorher schon – 192.168.0.19).
    Wirklich absurd finde ich, dass Mozilla und Chrome auf einem Laptop im gleichen Netz noch in der Lage sind den Webserver zu finden.
    Auf dem Androiden sind weder Chrome, Mozilla noch der Hauseigene Cyanognemod Browser in der Lage.
    Leider bin ich in Sachen Netzwerktechnik nicht fit genug um das Problem genauer zu lokalisieren (Die LOGG-Einträge im Router geben leider gar nichts her).
    Sobald ich den ESP resette ist er nach wenigen Sekunden wieder im Router eingetragen und auch am Smartphone erreichbar.
    Hast du (oder igendjemand sonst) eine Idee, woran das liegt oder ob ich irgendwie vom ESP abfragen kann, ob er noch vernünftig im DHCP registriert ist?

    Beste Grüße und vielen Dank, Jan

    Antworten
    1. Jan

      Nachtrag:
      Nachdem neue Hardware von Unitymedia kam kann der Fehler auf den alten Wlan-Router eingegrenzt werden – woran es genau lag weiß ich nicht, mit dem neuen klappt alles Einwandfrei.

      Jan

      Antworten
  29. Andreas

    hallo,
    wenn ich den Sketch übertragen habe,was ohne Fehler klappt,
    kommt im seriellen Monitor zuerst das er connected ist mit der ip adresse
    aber dann bei funktion on erscheint
    client disconnected

    kann mir da jemand helfen es hat mal funktioniert und einen tag später nicht mehr

    Antworten
    1. ST Beitragsautor

      Die Frage kann ich Dir so nicht beantworten. Deine Beschreibung ist zu knapp und interpunktionslos. Es kann an allem möglichen liegen. Am wahrscheinlichsten ist eine fehlerhafte Stromversorgung des Esp. Es kann auch ein Reset Problem sein; dazu habe ich einen anderen Blogbeitrag geschrieben.

      Gruss Stefan

      Antworten
    2. Dirk

      Genau das ist auch mein Problem. Andere Webserver gehen, nur dieser nicht. Ich sitze seit drei Stunden davor und versuche den Fehler zu finden. Stromversorgung geht über USB (D1 mini Board). Sag Bescheid, wenn Du eine lösung hast 🙂

      Antworten
      1. ST Beitragsautor

        Hallo zusammen,

        ich habe das Ganze jetzt nochmal nachgestellt. Das Problem liegt nicht an den ESP8266 Hardware Varianten. Es liegt an der neuen SDK Version 2.4.1. Die macht Ärger. Ich weiss noch nicht warum, aber jede Version davon funktioniert.
        Abhilfe: Zurück auf 2.4.0.
        Das geht so: In der Arduino Umgebung Menü -> Werkzeuge -> Board –> Boardverwalter ..
        Dort ganz nach unten: esp8266 by …
        In den Kasten klicken, Version auswählen, 2.4.0 –> Installieren.
        Danach läuft alles wieder. Ich vermute mal, dass irgendeine zentrale API inkompatibel geändert wurde.

        Gruss Stefan

        Antworten
        1. Peter

          Hallo Stefan,
          vielen vielen Dank für den Hinweis mit der V2.4.1!!!
          Genau das Problem hat mich heute zwei Stunden gekostet. Jetzt läuft mein Funk-Datenlogger.

          Antworten
  30. Martin

    Hallo ,

    möchte mich für den besonders gelungenen Beitrag bedanken!
    Ich bin 67 Jahre alt und jetzt ca 2 Jahre im Ruhestand. Habe erst vor einem halben Jahr mit Arduino Uno/Nano V3 begonnen zu programmieren. Vor kurzem habe ich mir dann 2 „Wemos D1 mini Pro“ boards aus China zugelegt und mich im Internet über die bereitgestellten Möglichkeiten Sie zu programmieren informiert.
    Dabei bin ich auf den Webserver Beitrag gestoßen. Kann nur sagen alles hervorragend beschrieben! Habe den Webserver aufs Wemos D1 mini pro Bord bekommen, obwohl dieses Bord einen 16MB Flash hat. Und voller Spannung am meinem Laptop die (vom Router vergebene DHCP) Adresse eingegeben! Wup
    stand das Interface auf meinem Laptopschirm und die blaue LED ein und ausgeschaltet!!
    Jetzt der Griff zum meinem Android Smartphone das gleiche: Browser gestartet Adresse eingegeben und wow das selbe Interface auf meinem Android Smartphone. Dasselbe nochmal mit einem Windows Smartphone. Ich bin begeistert! Nur ich möchte jetzt mehr Funktionalität auf dem Schirm haben sprich ich würde gerne mehr über die webserver Programmierung auf dem ESP8266 wissen wollen. Kann mir da jemand Tutorials oder sonstige Lektüre empfehlen?
    Gruß Martin

    Antworten
  31. Daniel Süsstrunk

    Hi Stefan

    Dein Code/Webserver-Beispiel funktioniert wunderbar, vielen Dank. Ich habe eben versucht, per ESP8266 eine aus mehreren Dateien bestehende Webseite auszuliefern. Die einzelnen Dateien sind zwischen 5 (index.html) und 50kB gross.

    Für die verschiedenen Dateien habe ich entsprechend Abfragen erstellt wie folgt:

      if(sPath == "/css/foundation.min.css"){
        Serial.println("fondation.min.css wanted");    
        sHeader  = "HTTP/1.1 200 OK\r\n";
        sHeader += "Content-Length: ";
        sHeader += "51215"; // Manuell im BBedit herauslesen. Der Code zu gross, um in Variablen gespeichert zu werden und um die Grösse im RAM des ESP8266 bestimmen zu können.
        sHeader += "\r\n";
        sHeader += "Content-Type: text/html\r\n";
        sHeader += "Connection: close\r\n";
        sHeader += "\r\n";
    
        // Send the response to the client
        client.print(sHeader);
        client.print(F("@charset \"UTF-8\";\nhtml{font-family:sans-serif; [viel CSS-Code]
      }
    
    

    … und liefere die Daten per F() direkt aus dem Flash-Speicher aus.

    Nun lädt die Webseite aber nicht korrekt, weil es Timeouts gibt. Mit dem Netzwerkmonitor betrachtet kommen nur etwa 500 Bytes pro Sekunde vom ESP8266 zum Client und der Browser scheint die Verbindung vor Erhalt des Inhalts aufzugeben.

    client.print() scheint also zu langsam zu sein.
    Kann ich das irgendwie ändern?

    Danke für deine Ideen,
    liebe Grüsse,
    Dani

    Antworten
    1. ST Beitragsautor

      Hallo Daniel,

      ich habe in einem Code eine lange Tabelle in Chunks von 2k ausgeliefert. Das funktioniert recht performant mit client.print().
      Versuche ggf mal die Effekte zu trennen. F Macro raus; dafür einige Bytes selbst erzeugen. Chunks von einigen kB vs alles an einem Stück.

      gruss Stefam

      Antworten
  32. Daniel Süsstrunk

    Hi Stefan

    Danke dir für deine Antwort – ich habe unterdessen eine noch bessere Variante gefunden, die sehr schnell ist und dabei die Webseiten-Dateien mit pgmspace ins Flash lädt und von dort an den Client liefert. Ich habe alles zusammengestellt unter http://wunderwald.ch/esp/. Funktioniert echt super, wenn man die Webseite auf eine oder zwei Dateien reduziert, kann man so richtig tolle Webseiten providen.

    Liebe Grüsse, Dani

    Antworten
    1. ST Beitragsautor

      Hallo Dani,

      gute Sache. Kann man für große Seite definitiv so machen. Etwas schwieriger wird es dann, wenn man die Webseiten dynamisch aufbauen will – oder man löst alles in Javascript. Schick wäre es, wenn man die Konvertierung von .html -> .h in den Übersetzungsprozess reinbasteln könnte. Müsste eigentlich gehen; ich habe mich aber noch nie so tief in die Arduino IDE eingegraben.

      Gruss Stefan

      Antworten
    2. Dominikus

      Moin,
      cooler Ansatz. Ich hatte auch immer das Problem das ich eine Webseite komplett in einem String ausgeben wollte. Das stößt dann natürlich schnell an die Grenzen des Strings. Ein bisschen Optimierung hat dann gereicht um grade so alle Funktionalität ab zu bilden.

      Wenn jetzt aber mehr Platz zur Verfügung steht könnte man ja die Bilder über Data URIs einfügen. Dann sollten doch beliebig viele Bilder verwendet werden können. Hier habe ich dazu Infos gefunden https://blog.kulturbanause.de/2013/03/grafiken-mit-data-uris-base-64-erzeugen/
      Die Seite ist nicht von mir.

      Antworten
  33. Pingback: Electric Vehicle Charging Stations / Schnarchlader mit Handbremse – www.unifox.at

  34. Luette

    Hallo,
    mein Wunsch ist es eine Fensterrollade über das Internet, per WLAN und Taster oder Funk zu steuern.
    Programmieren kann ich schon fehlerfrei schreiben, dann hört’s aber auch schon auf. Vom Lesen und meinem Verstädnnis könnte ich mit deiner Anleitung schon ein Stück weiter kommen. Aber da sind noch einige Unklarheiten.
    Deswegen schreibe ich meine Fragen und Gedanken mal frei runter:

    1. Ich würde gerne deine Aufteilung ESP und Arduino auf einen ESP zusammenlegen. Kann ich die beiden Programmteile dafür einfach zusammenkopieren. Würde das gehen?

    2. Für mein Vorhaben müssten zwei Relais mit dem ESp gesteuert werden, wobei eine gleichzeitige Schließung beider Relais ausgeschlossen sein muss.

    Mistro schrieb in 2016 bei den Antworten:

    „Hallo und vielen Dank für den Klasse Code.
    Ich wollte einen Webserver mit dem ich zwei Relais schalten kann und das hat mit Deinem Code und einen kleinen Umbau auch gut funktioniert.“
    Hätte er den kleinen Umbau mal kundgetan, so wäre diese meiner Fragen hinfällig.

    3. Ich würde gerne auf eine statische IP des ESP aus dem Internet zugreifen. Nach meinem auf Ahnugnslosigkeit basierendem Verständnis werden die dynaischen IPs z.Bsp. nach einem Stromausfall
    neu vergeben. Wenn ich dann aus der Ferne über Dyndns.org und der alten IP versuche auf den ESP zuzugreifen müsste das zum Scheitern veruteilt sein. Bei einer statischen IP dürfte das dann aber nicht passieren.

    Wäre schön Antworten hierauf zu bekommen. Dafür meinen Dank

    Antworten
    1. ST Beitragsautor

      Hallo Luette,

      zu 1: Nein. EInfach zusammenkopieren geht definitiv nicht. Du musst ersthaft programmieren. Technisch geht es.
      Zu 2: Schau Dir das Beispiel mit der Markisensteuerung an. Das löst exakt diese Problem. https://blog.thesen.eu/funk-wlan-markisensteuerung-mit-esp8266-und-arduino/
      Zu 3: Du brauchst für einen Remote Zugriff keine lokal statischen IPs. Ich vermute ein Mißverständnis. Wie man ein Portforwarding einrichtet und das im Detail zu konfigurieren ist, hängt aber vom Router ab. Bei einer Fritzbox gibst Du bei einem Forwarding das Zielgerät an. Die Fritz sorgt dafür, dass es am Ende passt. Bei einer Easybox geht es über die Festlegung der dynamischen IP über eine MAC Tabelle. Das musst Du Dir für Deinen Router er-googlen. Die Lösung dazu liegt nicht im ESP Code 🙂

      Gruss Stefan

      Antworten
  35. Andy

    Hallo
    Ich würde gerne ihr Beispiel nutzen, um ein Relais an einen GPIO schalten zu wollen. Allerdings sollte das auch von einen weiteren ESP8266 der als Client sich am Server anmeldet funktionieren. Der eine ESP soll praktisch im AP-Modus laufen und den Webserver stellen und ein zweiter ESP soll als Client laufen und wenn sich an diesen ein GPIO von 0 auf 1 ändert, das dem Server mitteilt und entsprechend das Relais ein- bzw. ausschaltet. Haben sie vielleicht für so einen Fall auch Code für den Client-ESP. Ich weiß nicht so recht, wie ich das realisieren kann.

    MfG
    Andy

    Antworten
  36. Sebastianb

    Hallo,

    ich habe deinen Webserver als Vorlage für ein Programm genommen, welches mittlerweile ganze 1000 Zeilen lang ist, dabei habe ich vor ein paar Wochen erst mit dem Programmieren angefangen! Vielen Dank dafür.

    Ich habe jedoch ein Problem:
    Ich kann nicht aus dem Internet auf den Wemos D1 Mini zugreifen.
    Ich kenne mich mit Netzwerktechnik aus (mein Job), es funktioniert weder per Portfreigabe, noch per Fritzbox VPN vom iPhone aus.
    Wenn ich jedoch in meinem lokalen Netz angemeldet bin, funktioniert alles wie gewollt.
    Ich habe es mit dynamischer Vergabe und statischer Zuweisung der IP versucht, keine Änderung.

    Pingen lässt er sich von außerhalb, nur bei Seitenaufrufen lädt sich der Browser zu Tode.

    Mir ist auch aufgefallen, solange ich von außerhalb die Seite „laden“ lasse, können lokale Geräte auch nicht auf die Seite zugreifen. Sobald ich den Zugriff von außen stoppe, laden diese lokalen sofort.

    Antworten
      1. Sebastianb

        Die Wireshark Paketanalyse hat ergeben, dass der Befehl „connection: close \r\n\r\n“ nur bis zum zweiten \r übertragen wird.
        Danach bricht die Übertragung abrupt ab, deswegen erwartet der Browser noch weitere Infos im Header und bricht irgendwann ab, während der Wemos sich derweil mit irgendwas beschäftigt, die die Übertragung unterbricht.

        Antworten
        1. ST Beitragsautor

          Hallo Sebastian,

          muss ich mir mal ansehen. Es kann am ESP Framework liegen. Prüfe zunächst mal, dass Du neueste ESP SDK Version installiert hast. Ggf bekommst Du auch eine Update Aufforderung des Arduino IDE.
          Wenn das nix bringt, padde doch mal testweise 128 oder 256 Bytes mit Nullen hinten dran.

          Gruss Stefan

          Antworten
          1. Sebastianb

            ich schau mal, ein bekannter von mir hat mich auf max-framelenth hingewiesen, da schau ich morgen mal

          2. Sebastianb

            Hallo nochmal,

            Lösung des Problems war, dass ich aus Versehen das ESP Boardwerkzeug 2x installiert hatte, und Arduino auf eine veraltete Version zugegriffen hat. Zusätzlich musste ich danach aber die client.print() Funktion mit mehreren Strings übertragen, da es da wohl eine maximale Größe gibt (Quelltext meiner Seite wurde abgeschnitten).

  37. LOKO

    Vielen Dank für das tolle Beispiel.
    Großartig. Läuft bei mir auch sehr stabil.
    Ich versuche Vergebes eine Eingabefeld zu kreieren , und den Wert dann weiter zu verarbeitn. Irgendwienmuss ich statt button, den befehl input verwenden, aber irgendwie hat der input befehl noch mehr paramete?

    Wo kann ich dazu was finden?

    Viele liebe Grüße.

    Antworten
  38. ST

    Hallo Loko,

    suchst Du sowas hier? – Erzeugung eines Parameters D1 mit anhand eines Eingabefeldes. Verarbeitung des Parameters dann wie im Code gezeigt.

    <label for="D1">Parameter 1:</label><input type="text" id="D1" " name="D1" " value="10">
    

    Gruss Stefan

    Antworten
    1. LOKO

      Hallo Stefan,

      vielen Dank für Deinen Tip,
      Habe mir erstmal in der Zwischenzeit, einen Plus und Minus-Schalter eingebaut, mit dem man schrittweise die Einschaltdauer einstellen kann. Deinen Vorschlag werde ich mal probieren.

      Eine neue Herausforderung ist für mich, wie ich die Aktualisierung der Seite automatisieren kann, also das der Wert von z.Bsp. millis() ständig neu angezeigt wird, ohne dass ich selbst immer im Browser auf aktualisieren drücken muss.

      MfG un noch ein schönes WE.

      Antworten
      1. ST

        Wenn Du dauernd Teile der Website aktualisieren willst, wirsts Du um Javascript auf der Website und eine passenden Funktion im Backend (ESP) nicht drumherum kommen.
        Also html und Javascript pauken.

        Gruss Stefan

        Antworten
          1. ST Beitragsautor

            @LOKO: ich habe die Korrekturen zusammengefasst. WordPress filtert sehr stark und kann da nervig sein.
            Du kannst C++ Code so posten.
            Beginn: Eckige Klammer auf, dann cpp, dann eckige Klammer zu
            Ende: Eckige Klammer auf, dann /cpp, dann eckige Klammer zu

            Zu Deiner Lösung: Das lädt die komplette Website per Refresh neu. Geht natürlich und ist eine einfache Lösung. Wenn man nur Teile der Website neu laden will oder auf Geschwindigkeit aus ist, geht das nicht mehr. Man könnte mit Frames arbeiten, aber auch das erreicht Limits. Am Ende wird es an etwas Javascript nicht vorbei gehen. Gerade für +/- Taster etc ist die Usability am Ende sehr beschränkt, wenn Du für jeden Mausklick die Website komplett neu aufbauen läßt.

  39. Thomas Reisinger

    Hallo Stefan,
    super ding ….läfut perfekt.

    Wollte nun noch eine 2. seite einbauen.
    und den HTTP Updater.

    Habe das aber nicht hinbekommen.

    Hast du da einen Tipp.

    Danke Thomas

    Antworten
  40. Martin

    HI, ich wollte einfach mal DANKE sagen !
    Toller Code!
    War wie geschaffen für mein eigenes kleines Projekt.
    Habe den zweiten Button weggemacht und beim Aufrufen des ersten Buttons ein Delay mit eingebaut, welches nach einer gewissen Zeit den Ursprungszustand „HIGH“ des GPIO Pins wiederherstellt.

    Aber ansonsten läuft echt alles toppi.
    Hat mir echt geholfen, dass ich deine Seite nach der ewigen Sucherrei im Netz gefunden habe.

    Antworten
    1. Martin

      Ich wieder: ironischer Weise ist diese Nacht (nach meinem Kommentar), der Webserver nicht mehr erreichbar 😀 Der ESP ist pingbar, allerdings ist der Webserver nicht ansprechbar. Ich bekomme von mehreren Geräten einen timeout, wenn ich die ip wie gewohnt aufrufe. Hast du eine Idee für mich ?

      Mit freundlichen Grüßen
      Martin

      Antworten
      1. ST Beitragsautor

        Hallo Martin,

        ich habe auf Basis dieses Codes ESPs laufen, die Monate am Stück stabil sind. Markisensteuerung, Anwesenheitserkennung Mähroboter in seiner Garage etc. Ich würde also erst mal nicht im Code suchen.
        Vielleicht kommst Du so dahinter:
        Ist die Spannungsversorgung stabil?
        Seriell am ESP mitloggen. Kommt nach 24h noch etwas? – Kommen Ausgaben, wenn eine Website abgerufen wird?
        Version des ESP SDKs in der Arduino IDE prüfen und ggf aktualisieren (Boardverwalter; lange war 2.3 aktuell und ist für meine realisierten Projekte im Einsatz; mittlerweile gibt es 2.4).

        Good Luck
        Stefan

        Antworten
        1. Martin

          Ich werde dem Ganzen heute Abend noch mal auf den Grund gehen.
          Ich werde erst einmal alles aktualiseren und dann noch mal berichten, ob sich was tut.
          Danke erst mal für die Tipps zum Prüfen 🙂

          Grüße Martin

          Antworten
          1. Martin

            Moin ich wieder.
            Also habe das Teil inzwischen seit 16.1 am Laufen und bisher keine Probleme 🙂
            Habe ein Firmwareupdate des NodeMCU gemacht und einfach noch mal den selben Code genommen und siehe da es funktioniert 🙂
            Vielen Dank nochmals 🙂

          2. Martin

            Hi Stefan,

            hatte nach einer Woche wieder einen Hänger und dann immer öfter. Hab jetzt den Watchdog genutzt der zählt in dem Loop des Webservers hoch. Wenn er nicht mehr hochzählt macht er einfach einen reset.

            Gruß Martin

  41. Polo

    Hi Stefan,
    Danke für diese interessante Seiten (Entschuldigung deutsch ist nicht meine Muttersprache)

    Einigen Fragen:
    – Wenn ist die Html lang sein mit „sResponse +=…“ die String sResponse ist zu kein und die Programme funktioniert nicht mehr.
    Wie machen ?

    – Wie diese Beispiel ändern mit Radio button ? (“ ON“). Die Zeichnung des Schalter sind da aber wie lesen diese Schaltern ?

    Danke

    Gruss

    Antworten
    1. ST Beitragsautor

      Hi Polo,

      can you write in English? – Might be easier? – I guess the first question is, what you do if SResponse allocates to much memory. Change code to send out multiple substrings. You need to keep in mind that the http header needs the length of the bytes to come. If you cannot calculate this, there is no other way than constructing the strings two times. First time to get the length and add up. Second time to send out.
      I did not get the meaning of the second question.

      Regards Stefan

      Antworten
  42. Polo

    Thanks Stefan,

    For the first question I tried to send sometimes “ client.print(sResponse);“ but the next part will be no ok. What’s wrong ?
    Where you define the http header length ?

    The 2nd question was:

    I tried to replace the standard button with radio button
    “ ON“;
    “ OFF“;

    With both lines you can see the „radio buttons“ but how to read the states button ?

    Thanks

    Regards

    Antworten
  43. Polo

    Sorry it seems that the code is not show…

    input type=\“radio\“ name=\“RedLEDState\“ value=\“RED_ON\“> ON“
    input type=\“radio\“ name=\“RedLEDState\“ value=\“RED_OFF\“ checked=\“checked\“> OFF“

    Antworten
    1. ST Beitragsautor

      Try adding ID=“radio1″ etc. Lookup somt html tutorials. I am certainly not the greatest html reference 🙂
      For the the frist qeustion: Look up the code for the sections where the http header is created. It creates a http 1.1 header. This needs to contain the number of bytes sent. To get this number, the code gets the nuber of bytes in sResponse and puts this into the header.

      Antworten
  44. Helmut

    Hallo,
    viele interessant Projekt und Ideen.
    Bei dem Webserver habe ich das Problen, dass zwar alles gut komiliert wird und im Router auch der ESP mit IP auftaucht, jedoch kann ich mittels Web Browser die Seite nicht aufrufen. (time out)
    Kann mir jemand helfen, was mache ich falsch?
    Gruß & Dank
    Helmut

    Antworten
  45. Helmut

    Hallo,
    habe meine (n) Fehler selbst gefunden.
    ( Auch kleine Fehler kosten viel Zeit ! ; sehr viel ! )
    1. Hauptnetzwerk ( kl. Tippfehler [ Leerzeichen ]
    2. ( f. Zielbetrieb) GastzugangsNetzwerk Freigabe Geräte dürfen auch untereinander kommunizieren
    { also richtig angemeldelt ,aber Router verbot die Kommunikation }
    Andere müssen nicht das gleiche Fettnäpfchen nochmals nutzen..

    Gruß
    Helmut

    Antworten
  46. Hermann

    Hallo,

    ich bin absoluter Anfänger im Bereich „NodeMCU ESP8266“ und habe dein Sketch ausprobiert. Das Kompilieren und Übertragen funktionierte fehlerfrei.

    Wenn ich aber die IP des ESP8266 eingebe, erschein für einen Bruchteil einer Sekunde die Webobefläche und dann die Meldung „Fehler: Verbindung unterbrochen. Die Verbindung zum Server wurde zurückgesetzt, während die Seite geladen wurde.“

    Im seriellen Monitor erscheint:
    WiFi connected
    Server started
    192.168.xxx.xxx
    new client
    client disconnected

    Leider weiss ich nicht wo ich das Problem suchen soll.

    LG
    Hermann

    Antworten
    1. ST Beitragsautor

      Hallo Hermann,

      das ist so schwer aus der Ferne zu sagen. Funktioniert denn die NodeMCU Demos? – Das klingt irgendwie nach einem Routerproblem / Routereinstellung. Bei diversen Routern kann man Netzwerkverbindungen zwischen den WLAN Geräten unterbinden. Klingt nach Sicherheit und wird gerne mal aktiviert und vergessen 🙂

      Gruss Stefan

      Antworten
      1. Hermann

        Hallo,
        welche NodeMCU Demos meinst du?
        Ich habe schon einige Beispiele mit der Arduino IDE installiert z.B.:
        https://www.sweetpi.de/blog/1562/nodemcu-esp8266-wifi-led oder http://esp8266-server.de/IP-Steckdose.html. Sie verwenden alle einen Webserver und funktionieren gut. Deshalb denke ich nicht, dass es sich um ein Routerproblem handelt.
        Mit der originalen LUA Firmware und den Programmen ESP8266Flasher und ESPlorer habe ich aber so meine Probleme.

        LG
        Hermann

        Antworten
        1. ST Beitragsautor

          Das ist ja schon etwas mehr Info, um evtl das Problem einzukreisen. Bisher hatte ich mit dem Code keine Probleme und das Feedback aus den Kommentaren war auch positiv. Welchen Browser nimmst Du? Ich nehme hauptsächlich Chrome und manchmal den Intern Explorer.
          Ich glaube jetzt nicht, dass es sich um eine Nodemcu Spezifikum handelt, obwohl ich so ein Board nie benutzt habe.

          Gruss Stefan

          Antworten
          1. Paker

            Hatte den gleichen Code schon am laufen gehabt jedoch jetzt nach über einem Jahr mal wieder aufgespielt läuft es nicht mehr.

            Arduino „IDE“: 1.8.5
            ESP Core:
            2.4.1 client disconected
            2.4.0 verbindet sich nicht mit dem wifi
            2.3.0 connection timed out

            2.0 funktioniert ohne probleme

            Hast du eine idee was da geändert wurde das es nicht mehr läuft? Meine anderen Sketche mit MQTT zeigen keine Probleme mit 2.4.1.

          2. Paker

            Hab es jetzt noch mal mit 2.4.0 und einem zweiten ESP8266 als AP (als fritzbox Ersatz) probiert. Verbindung klappt jedoch kommt jetzt wider:

            new client
            Client disonnected
            und im browser verbindung zurückgesetzt.

            Wäherend die uralt version 2.2 ohne probleme läuft.
            Gibt es eventuell andere firmware versionen auf den esp’s und deshalb läuft es bei dir?

        2. gundel

          Hallo Hermann,
          Hast du schon für dein Problem eine Lösung gefunden? Hab das gleiche Problem. Bei den Kommentaren hab ich nun einen richtigen Lösungsansatz gefunden.
          natürlich auch die lg gundel

          Antworten
  47. Dirk

    Vielen Dank für die tollen Anleitungen. Ich habe aus Versehen ein ESP8266MOD D1 Mini Board bestellt. Hilfreich wegen des USB-Anschlusses aber der Sketch funktioniert nicht. Können Sie mir sagen, was ich für das Board abändern muss ?
    Viele Grüße,
    Dirk

    Antworten
  48. ottelo

    Wen man über den Boardmanager ESP8266 V.2.4.1 installiert geht die Webseite nicht. V2.4.0 funzt aber.

    Allerdings habe ich ein Problem mit deinem Code. Ich habe im loop() noch meinen eigenen Code eingebaut. Der Code funzt und der ESP verbindet sich mit meinem Netzwerk. Jedoch verliert er nach einigen Sekunden die Verbindung und kann sie anschließend nicht mehr wieder aufbauen (unendlich viele ……… auf dem Debugoutput). Kennst du das Phänomen?

    Antworten
  49. Flaves

    Hallo ,
    ich habe das gleiche Problem, was Hermann am 28. April 2018 geschildert hatte. Meine Versuche ergaben, dass die vorletzte Zeile client.stop(); gestrichen werden muss, dann funktioniert alles.

    Meine Frage: Welche Bedeutung hat client.stop(); ? Kann/darf man darauf so ohne weitere Probleme verzichten? Wer kennt sich da aus?

    Danke für Hilfe
    Flaves

    Antworten
    1. ST Beitragsautor

      Das ist ein interessanter Hinweis. Es könnte sein, dass die Übertragung bzw Send asynchron läuft und der stop die Übertragung in den neueren Versionen killt.
      Ob man stop weg lassen kann, weiß letztlich nur der Sdk Programmierer. Ich würde das symptomatisch machen. Client.stop raus und schauen, ob nach vielen Zugriffen das freie Ram weniger wird. Wenn ich Zeit finde, schaue ich es an.

      Gruss Stefan

      Antworten
  50. frecker

    Hallo,
    Ich habe einen Wemos Mega 2560 mit einem ESP8266 onboard, die AP Version läuft bestens(Kommunikation Atmega ESP hab ich noch nicht ins Spiel gebracht).
    Ich benötige jedoch die Webserver Variante, und diese will sich einfach nicht ins WLAN einloggen….
    Ich hab jetzt schon diverse Fritzboxen getestet, die SSID extra abgeändert dass keine Sonderzeichen enthalten sind….
    In der Fritzbox werden auch keine gescheiterten Anmeldeversuche angezeigt.
    Was mache ich Falsch?
    Ich habe ebenfalls schon:
    – Stromversorgung geprüft
    – Abstand zur Fritzbox zwischen 1m und mehreren Zimmern variiert
    – Fritzbox resettet

    Danke 🙂

    Antworten
    1. ST Beitragsautor

      Hi frecker,
      was kommen denn für Ausgaben auf dem seriellen Monitor? – Ich habe den Webserver schon x-Mal an diversen Routern eingesetzt und hatte keine Probleme.
      Gruss Stefan

      Antworten
      1. frecker

        Hallo,

        vielen Dank für die Antwort, ich bin leider erst heute dazu gekommen dannach zu schauen.
        Allerdings hat heute – warum auch immer – der Webserver Problemlos Funktioniert. Lediglich die Serielle Kommunikation funktioniert nicht. Vielleich können sie kurz über die zwei Codeschnipsel schauen.

        Sender(Atmega 2560):
        Serial.print(„S ,“);
        Serial.print(Soll);
        Serial.println(„,“);
        Serial.flush();
        Serial.print(„I ,“);
        Serial.print(Ist);
        Serial.println(„,“);
        Serial.flush();
        Dieser Sendet, wie er es auch soll, immer wieder den I und S wert auf den Seriellen Bus (darf man das Bus nennen?)

        Empfänger(ESP8266):
        if(Serial.available()>0){
        zeichenStart = Serial.read();
        switch(zeichenStart){
        case ‚I‘ : Ist = Serial.parseInt();
        break;
        case ‚S‘ : Soll = Serial.parseInt();
        break;
        default: break;
        }

        Beide Schnipsel befinden sich in der loop funktion, werden auch aufgerufen.
        Bei bedarf stelle ich gerne den Kompletten Code zur verfügung, jedoch ist dieser für dieses Antwortfenster zu groß.

        Gruß Leo

        Antworten
        1. ST Beitragsautor

          Ich kenne den Wemos nicht und offen gesagt kapiere ich gerade nicht, was Du da treibst. Der ESP selbst gibt bei dem geposteten Code ein paar Infos beim Verbinden ins WLAN an. Es wäre spannend zu wissen, ob überhaupt der initiale Connect klappt. Die Codes da oben implementieren eine Kommunikation zwischen ESP und ATMega von der ich nicht genau weiß, was es sein soll. Ich würde an Deiner Stelle erst mal versuchen den ESP ins WLAN zu bringen und den Beispielcode zu nutzen. Danach kannst Du dann den ATMega mit ins Spiel bringen.

          Gruss Stefan

          Antworten
          1. frecker

            Hallo,

            ich habe mich leider etwas Undeutlich ausgedrückt.
            Das Projekt läuft soweit – habe nur noch eine Frage:
            Was muss ich noch einfügen, wenn mein WLAN aus SSID, Passwort und Benutzernamen(Zahlen+Buchstaben) besteht?

  51. Udo Heinke

    Hallo,
    komme mit dem Stabilen Server nicht so recht weiter.
    Server startet meiner Meinung einwandfrei.
    Nach betätigen des Resettasters erhalte ich folgende Anzeige auf dem Seriellen Monitor:
    1. Zeile: unlesbare Hieroglyphen
    2. Zeile: connekting to: ( meine SSID )
    3. Zeile: . . . . . . . . . .. . usw.

    in Zeile 1 sollte soll bestimmt die interne iID vom ESP8266 stehen, um diese im Browser einzugeben.

    1. Frage: was kann ich tun um an diese ID zukommen? Habe schon alles versucht, mit Baudrate gespielt usw.

    2.Frage kann man dem ESP8266 eine feste IP zuteilen ?

    Vielen Dank im Voraus.
    Udo

    Antworten
    1. ST Beitragsautor

      Hallo Udo,
      der „Müll“ am Anfang ist uninteressant. Das kommt aus dem Startprozess des ESP. Teils ist das echter Müll, teils Ausgaben auf einer anderen Baudrate aus den Untiefen der Frameworks. Was Du brauchst ist die IP Adresse des ESP. Diese wird in den Ausgaben mitgeteilt. Dann gibst Du im Browser http://hier.kommt.die.ip.hin ein.
      Du kannst dem ESP auch einen Netzwerknamen zuweisen, so dass die Adresse vom Router aufgelöst werden kann. Das habe ich z.B. in dem Code für die Markisensteuerung gemacht (klick). Such ggf mal nach WiFi.hostname(„name hier rein“).
      Feste IP usw.: Das hat alles nichts mit dem ESP zu tun. Dazu musst Du Dir ein paar Grundlagen zu Netzwerken anlesen. In very short: typische Konfiguration der WLAN Router ist eine dynamische IP Vergabe durch den Router. Um die IP zu fixieren, musst Du entsprechend im Router konfigurieren. Alternativ kann man auch auf eine statische IP Vergabe umstellen; das bringt aber für jedes Gerät im Netz Administrationsaufwand. Ich glaube nicht, dass Du das eigentlich willst. Du willst den ESP erreichen können, ohne die IP zu kennen. Die Lösung dafür ist der Name.

      Good luck
      Stefan

      Antworten
  52. Udo Heinke

    Hallo Stefan,
    Danke für deine Anregungen. Als erstes hatte ich einen Erfolg mit dem Accesspoint . Danach mit ein wenig mehr Hirnschmalz und Ausdauer funktioniert auch der Server.
    Vielen, vielen Dank und einen schönen Gruß aus der Heide
    Udo

    Antworten
  53. Tim

    Hallo,

    vielen Dank für das wertvolle Programm.
    Kannst du noch sagen, wie man eine Eingabe (String) vom Client an den Server übergibt?

    Danke.

    Antworten
  54. Jonas

    Hallo Stefan,
    Vielen Dank erst mal für deinen Beitrag. Ich bin gerade dabei einen Webserver zu verwenden, um mein Bewässerungssystem uber Relais mit meinen Netzwerkgeräten schalten zu können. Ich habe den Server soweit aufgesetzt und er funktioniert auch. Mit den Buttons auf dem Webserver lassen sich die einzelnen Beregnungskreise super schalten.
    Leider gibt es noch ein Problem. Wenn ich mit meinem Smartphone auf den Server zugreife aber die Verbindung abbricht (Empfang, Router-Repeater Wechsel, Smartphone hat keine WLAN-Verbindung mehr und geht in mobile Daten, parallele Verbindung mit dem Tablet,…), so kann ich nicht mehr auf den Webserver zugreifen und muss den WEMOS erst resetten. Ich habe deinen Code gefunden und diesen bei mir eingefügt. Ich muss dazusagen, dass ich absoluter Anfänger auf dem ESP8266 bin und den Webserver aus einem anderen Beispiel durch minimales Verstehen der Zusammenhänge und der HTML-Sprache zusammengebastelt habe.
    Wenn ich nun deinen Code einfüge, ist das Problem behoben, dass ich bei Verbindungsverlust den WEMOS neu starten muss. Leider passiert aber weiter nichts, also meine Ausgänge werden nicht geschalten. Beim drücken meiner Buttons wird zwar in die Browserzeile meine gewünschte URL eingetragen, wenn ich den Button betätige, aber der Client disconnected sich durch folgende Schleife. Ich hänge dann in der Abfrage if(sRequest==““)… fest und der Client wird gestoppt.
    Was mache ich da falsch?
    Angehängt der Code.
    Vielen Dank!
    Jonas

    Antworten
    1. ST Beitragsautor

      Hallo Jonas,

      ich habe mal die 770 Zeilen „Spaghetticode“ (sorry) aus dem Kommentar herausgenommen. Bitte verstehe, dass ich hier nicht Codefragmente von anderen Quellen debuggen kann. Ich würde Dir empfehlen, mal auf einen Basiscode zurückzugehen, der funktioniert. Dann solltest Du Funktionen für Teilfunktionalitäten des Codes einführen. Das wird sonst zu unübersichtlich. Der Code ist letztlich für keinen mehr lesbar. Es fällt Dir dann auch leichter, Teilfunktionen herauszunehmen, um den Fehler zu suchen.

      Gruss Stefan

      Antworten
      1. Jonas

        Hallo Stefan,
        ich habe deinen Rat beherzigt und den meinen Code auf deinen stabilen Webserver Schritt für Schritt eingefügt. Jetzt funktioniert es auch und der Webserver funktioniert einwandfrei. Vielen Dank für dein Beispiel!
        Gruß
        Jonas

        Antworten
  55. Jonas

    Hallo Stefan,
    ich habe jetzt schon verschiedene Projekte (Bewässerungssteuerung, Türöffner über Smartphone, Steckdosensteuerung mit 433MHz Modulen, Emailversand beim auslösen eines Rauchmelders im Haus, und Einschalten einer Sauna über einen Anruf ) mit deinem WebServer ausprobiert und die klappen alle ziemlich gut. Jetzt würde ich noch gerne bei einem Projet ein Eingabefeld erstellen, in welches ich die Minuten eintragen kann. Das Feld habe ich so weit zusammengebracht. Mir fehlt aber, wie man das Eingabefeld beim Servertyp „WifiServer“ auslesen kann, wenn man einen Button drückt und dieser eingegebene Wert dann weiter im Programm verwendet werden kann. Beim Typ „ESP266WebServer habe ich da schon verschiedene Funktionen gesehen. Beim WifiServer leider noch nicht. Hast du so etwas schon einmal gemacht? Wäre super wenn du mir da paar Tipps geben könntest.
    Vielen Dank!
    Viele Grüße
    Jonas

    Antworten
    1. ST Beitragsautor

      Hallo Jonas, vermutlich verstehe ich das Problem nicht richtig. Ob Du einen WiFi Server oder Client hast, ändert an der HTML Kodierung und dem Auslesen der Parameter nichts.
      Gruss Stefan

      Antworten
      1. Jonas

        Hallo Stefan,
        hier ein Beispiel, wie ich es gefunden habe (ein paar Codeschnipsel):
        ESP8266WebServer server(80);

        void handleRoot() {
        String message = „“;
        // message += „Set up the RF code and press on/off to generate and call the corrensponding url:“;
        message += „“;
        message += „Output pin D „;
        //message += „pulseµs „;
        //message += „ID „;
        //message += „“;
        //message += „channel „;
        //message += „function send(on){ document.getElementsByName(‚on‘)[0].value = on; document.getElementById(‚data‘).submit();}; function loaded(){ var a = document.getElementById(‚target‘); a.innerHTML = a.href = document.getElementById(‚response‘).contentWindow.location; };“;
        message += „“;
        message += „“;
        message += „URL constucted and called: „;
        message += „have fun –test„;
        server.send(200, „text/html“, message);
        }

        Mit Folgender Funktion wird dann das jeweilige Eingabefeld ausgelesen:

        int getArgValue(String name)
        {
        for (uint8_t i = 0; i < server.args(); i++)
        if(server.argName(i) == name)
        return server.arg(i).toInt();
        return -1;
        }

        Die Methoden args() und argName() sind bei dem Webserver vom Typ "WifiServer" in der Lib nicht vorhanden. Habe auch schon nachgelesen über bestehende Funktionen von WifiServer aber dabei nichts passendes (sprich Funktionen, die auf den Inhalt über die Felddernamen des Webservers zugreifen können) gefunden.
        Wie kann ich da zum Beispiel über HTML die Parameter aus den Eingabefeldern erhalten?

        Hast du eventuell ein kleines Beispiel damit ich mich mit dem Thema auseinandersetzen kann und weiter mit Projekten experimentieren kann?

        Vielen Dank für deine Bemühungen!
        Gruß
        Jonas

        Antworten
        1. ST Beitragsautor

          OK – dann hat die Frage nicht wirklich was mit dem hier geposteten Codes zu tun, richtig? – Du nutzt da den ESP8266WebServer. Da sind einige convenience Features drin, die es zum Zeitpunkt des Posts noch gar nicht gab. Der ESP8266WebServer instanziiert seinerseits wiederum einen WiFiServer, den Du dann aber nicht mehr direkt bedienst. Der hier gepostete Code realisiert den Webserver auf Basis des WifiServers selbst. Deshalb kannst Du die Codes nicht mixen. Ich habe den ESP8266WebServer nie selbst genutzt. Es sollte für Deinen Fall langen, einen Accesspoint aufzubauen und dann ganz normal mit der ESP8266WebServer Klasse den Webserver zu instanziieren.
          Good luck, Stefan

          Antworten
  56. Harry

    Hallo Stefan,
    Update!
    Letztlich hat sich herausgestellt, dass ein Codefragment aus einem anderen WEB-Server Projekt, das ich nach und nach auf deinen „stabilen“ Code umgebaut habe, das Schweinderl war.
    Nach deiner Abfrage auf „client connection time-out“ kam nochmal (hier fälschlich) eine Abfrage auf den Client mit while{ !client.available() delay(1); } OHNE Abbruchbedingung! in der sich der Code dann sporadisch aufgehängt hat.
    Ohne diesen Codeabschnitt läuft der Server jetzt stabil.

    Nochmals Danke!
    Harry

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert