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.

99 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
  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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

            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 Artikelautor

          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 Artikelautor

            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 Artikelautor

      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 Artikelautor

            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 Artikelautor

            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 Artikelautor

            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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

          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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

          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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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 Artikelautor

      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
  26. Anonym

    Geht dass auch am ESP8266 NodeMCU und wie kann man das so umschreiben dass man die Temperatur des DHT22 oder DHT11 auslesen kann.

    Antworten
    1. ST Artikelautor

      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
  27. 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 Artikelautor

      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
  28. 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
  29. 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
  30. 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 Artikelautor

      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
  31. 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
    1. ST Artikelautor

      Hallo Martin,

      prima, dass die ersten Schritte geklappt haben. Vielleicht kannst Du mit dem ESP8266 Buch etwas anfangen, das es im Netz gibt:
      http://neilkolban.com/tech/esp8266/
      Ansonsten kannst Du auch Anleitungen über den Arduino Wifi Shield lesen. Die Programmierung ist analog.

      Gruss Stefan

      Antworten
  32. 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 Artikelautor

      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
  33. 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 Artikelautor

      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

Schreibe einen Kommentar

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