Forum: Mikrocontroller und Digitale Elektronik ESP8266 Textfeld für Post zu groß


von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

Hallo, war schon lange nicht mehr hier... ;-)

Bastle gerade an einem Webserver mit dem ESP8266, genauer gesagt mit dem 
ESP-12F Modul. Dahinter hängt ein MC, der über die Web-Schnittstelle 
parametriert wird.
Programmierung über die Arduino IDE (per VS-Code) Bord Librarys V2.4.1.

Funktioniert so weit auch ganz gut.

Ich verwende die ESP8266WebServer Klasse. Nun habe ich festgestellt, 
dass wenn ich Daten vom Browser per Post zurück schicke, dass diese ab 
einer gewissen Größe nicht oder nicht vollständig beim ESP ankommen.
Zum Testen schreibe ich einfach die Daten wieder zurück.

Code:
if(webserver.hasArg("config7"))
      { sHTML.replace("~config7~",webserver.arg("config7"));

So bald das Argument mehr wie ca. 2,3kByte hat ist der String entweder 
"" oder unvollständig. Speicherprobleme mit dem String sHTML gibt es 
nicht, vorher ersetze ich die ~config7~ mit dem Parameterdatensatz aus 
dem Controller, der wird in der HTML Seite korrekt angezeigt 
(webserver.send(200, "text/html", sHTML);).

Kennt jemand das Problem? Kann man es evtl. umgehen?

Ich hatte festgestellt, dass wenn ich meinen 4k Text auf zwei textboxen 
aufteile, dass er vollständig ankommt. Nun habe ich aufwändig alles auf 
8 Textboxen aufgeteilt aber da kommen die letzten nicht vollständig an. 
War also fast umsonst.

Jetzt könnte ich die Daten per Javascript komprimieren (geht eigentlich 
nur um 128 Byte) aber ich kann nicht ausschließen, dass ein Kunde 
Javascript deaktiviert hat. Von daher kann ich es also nicht verwenden.

Gruß und danke schon mal für alle Antworten.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

POST-Daten müssen vollständig im RAM gehalten werden,
statischer Seiteninhalt darf auch aus Flash oder so kommen.

Wenn dem Controller schlicht das RAM ausgeht, kannst du nichts machen.

von TestX (Gast)


Lesenswert?

Dann schau dir doch mal den Quellcode des verwendeten Webservers an.
Die Buffer für GET/POST Variablen werden zu klein sein

von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

RAM ist ausreichend vorhanden.

Dachte evtl. kennt jemand das Problem. Habe ein paar Threads dazu 
gefunden, sind aber alle schon mindestens zwei Jahre alt, ohne Lösung.

Bin ja schon dabei die Quellen zu durchforsten aber noch nicht fündig 
geworden.

Gruß
BlackGuest

Nachtrag:

Es funktioniert. :-)
Irgendwie behakt sich das Ganze mit meinen Debugausgaben über die 
serielle Schnittstelle (Hardware, Serial1). Debugausgaben abgeschaltet 
und es geht.

War auch nur in handleConConfig() die Ausgabe, dass die HTML Datei 
ConConfig geöffnet wurde. Kleine Ursache, große Wirkung...

: Bearbeitet durch User
von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

Noch ein Nachtrag, falls jemand mal das gleiche Problem hat.
Es lag nicht an der Debugausgabe in dem Bereich.
Habe noch etwas rumgespielt und die Debugausgaben in dem Bereich 
deaktiviert. Wärend der Bearbeitung des Requests erfolgen keine Ausgaben 
und trotzdem habe ich das Problem mit den fehlenden Daten. Schalte ich 
alle Debugausgaben ab, dann geht es.

Scheint irgendwo ein Bug im Speicherhandling zu sein.

Hoffe mal der schlägt nicht zu, wenn das Programm weiter wächst...

von Michael U. (amiga)


Lesenswert?

Hallo,

wenn die Funktionen der Stringklasse leere oder uvollständige Strings 
zurückgeben ist der Ram zur Laufzeit entweder voll oder zu stark 
fragmentiert.
Ich bin da allerdings erst bei Ca. 6k Stringgröße gegen die Wand 
gelaufen.
html-Datei aus dem SPIFFS in einen String geladen und mehrere 
Platzhalter durch aktuell Sensorwerte ersetzt. Bei ca. 6kB Größe des 
html-Strings kamen die .replace nicht mehr klar.
Allerdings hatte ich solche Größen real dann nie und die Sache ist bis 
heute stabil.

Das Problem ist wohl auch weniger die Größe des Replaces sondern die 
Kombination der Größe von sHTML und dem Replace.
Es gibt wohl auch keine Fehlermeldungen der Stringklasse in solche einem 
Fall, es gibt auch ein Speicherleak, offenbar kann nur der temporäre 
Buffer nicht alloziiert werden.

Gruß aus Berlin
Michael

von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

Hallo Michael,

das dumme ist halt, ersetze ich die Platzhalter mit dem Text, den ich 
aus den vom MC gelesenen Parametern generiere, funktioniert alles. Größe 
ist ca. 8,75kB. Beim Replace mit den per Post zurückgelieferten 
Argumenten gibt es Probleme (so fern die Debugausgaben aktiviert sind, 
die ja auch Speicher brauchen).

Zur Not muss ich die Page dann doch aus kleineren "Häppchen" 
zusammenstückeln. Weiß jetzt auf jeden Fall, worauf ich achten muss.

Danke auch für Deinen Beispielcode hier. Damit habe ich angefangen. ;-)

Gruß
Steffen

von Stefan F. (Gast)


Lesenswert?

Ich kann Dir nur raten, auf die String Klasse zu verzichten. Sie ist 
komfortabel aber auch speicher-hungrig. Mit der String Klasse kann man 
ratz fatz ein mehrfaches des RAM belegen, als eigentlich nötig wäre, 
ohne dass es einem bewusst ist. Außerdem provoziert sie fragmentierten 
Speicher.

Benutze lieber Arrays von chars und die Funktionen der Standard C 
Library, um Zeichenketten zu manipulieren. Das ist viel umständlicher, 
aber dann weißt du wenigstens, was im Speicher passiert.

Lies diese Hinweise: 
http://stefanfrings.de/esp8266/index.html#fallstricke

von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

Danke für den Link.

Bin geraded dabei alles auf feste Char Arrays umzubauen.
Alles andere bringt nichts. Auch wenn es momentan unter bestimmten 
Umständen geht, irgendwann geht es nicht mehr.

Gruß
Steffen

von Michael U. (amiga)


Lesenswert?

Hallo,

Stringklasse vs Char-Arrays audfe dem ESP...
Das ist so meine Lieblingsdiskussion mit meinem Bekannten. ;-)
Er Char-Arrays, ich Stringklasse, ncht als Dogma sondern als 
persöhnliche Vorliebe. Ich baue auch um wenn es kanpp wird, oft aber nur 
teilweise. Für ständig zu bearbeitetende Strings macht es meiner MEinung 
nach auch Sinn, maximal große Char-Arrays global zu erstellen und 
passend zu nutzen. Der Speicher muß ohnehin da sein und man ahnt schon 
am Anfang, wo es kritisch wird. Beim ESP kommt noch dazu, daß in den 
Bibliotheken je nach Vorliebe des Programmieres Char-Arrays oder 
Stringklasse oder eine bunte Mischung genutzt wird...
Für mich sind die ESP in erster Linie recht gut ausgestattete kleine µC 
mit WLAN.
Mein Amiga 4000 mit 68040/40MHz bekam z.B. MP3-Decoding gerade noch 
irgendwie hin, ein Pentium 75 versagte kläglich, ein ESP32 macht das als 
Webstream per WLAN ohne Probleme. Ist irgendwie schon beachtlich die 
Entwicklung der letzten rund 30 Jahre.

Gruß aus Berlin
Michael

von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

Ich habe jetzt mal einen Teil umgebaut.
Meine Meinung im Moment ist, für kurze Strings die String Klasse, evtl. 
OK aber nicht für den Aufbau komplexer HTML-Seiten.

Mein Beispiel ist ja ein HTML Quellcode, der knapp 9KB groß ist. So fit 
bin ich in der Hinsicht auch nicht aber der Post Request mit meinen 
Textfeldern muss ja auch vollständig im Ram bleiben. Damit sind wir 
schon bei evtl. gut 20kB...

Kein Wunder, das das irgendwann crasht.

Ich habe mit meinem Quellcode mal etwas herumexperimentiert.
Da gibt es eine Funktion, die bei einem neuen Modul, was noch nicht in 
Betrieb war eine Minimalversion der browser.html im Flash anlegt.
Einfach sHTML+=Quelltext Zeile für Zeile...
Laut Compilermeldungen braucht die Routine knapp 1,5kB Ram.
ca. so viel, wie die fertige Datei hat.
Das alles auf einen global definierten Puffer umgesetzt und die Routine 
braucht zusätzliche 32 Byte Ram!!!

Bin weiter am Basteln. ;-)

Gruß
Steffen

von Sascha W. (sascha-w)


Lesenswert?

Es gibt doch auch den Async-Webserver, dort kannst du die Daten auch 
Häppchenweise übergeben damit habe ich bisher gute Erfahrungen gemacht. 
Problem ist mit deinem Ersetzen von Daten nur das du die Paketlänge 
warscheinlich nicht vorab bestimmen kannst.

Sascha

von Stefan F. (Gast)


Lesenswert?

Es ist auch nicht so trivial, eine HTML Vorlagen-Datei, die Platzhalter 
für Variablen enthält, so in Häppchen zu schneiden, dass dabei nicht die 
Platzhalter zerlegt (und somit nicht gefunden) werden. Aber darauf wird 
es wohl hinaus laufen müssen. Diese Methode habe ich auch mit einem 
ATmega644 angewendet.

von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

Die Dateien lassen sich schon häppchenweise übergeben.
Ich lese die HTML Vorlage byteweise ein und schaufle die Daten in einen 
2k Puffer. Ist der voll, dann wird er gesendet und neu beschrieben. 
Kommt ein Platzhalter (~Platzhalter~) dann wird Platzhalter nicht in den 
Puffer sondern in eine Variable geschrieben, die ich dann auswerte und 
je nach Wert die richtige Ersetzung einfüge. Dabei auch Byte für Byte in 
den gleichen Puffer.

Das funktioniert problemlos auch mit unterschiedlich langen Ersetzungen 
und Platzhaltern. Ist halt etwas aufwändiger wie string.replace...

Habe noch nicht alle Formulare umgearbeitet. Sehe allerdings bei jedem, 
dass zum einen der RAM Bedarf immer geringer wird und zum anderen die 
Größe des compilierten Codes bei gleicher Funktionalität extrem 
schrumpft...

Gruß
Steffen

von Stefan F. (Gast)


Lesenswert?

Na siehst du, geht doch.

von Steffen T. (Firma: Elektec) (blackguest)


Lesenswert?

Ich gebe es auf....
Der Post ist einfach zu groß. Ich bekomme es nicht stabil zum laufen.

Die Änderungen haben aber trotzdem Sinn gemacht. Jetzt kann der HTML 
Code so groß werden, wie es der Flash zulässt. :-)

Die Texte bilde ich mir aber jetzt doch per Javascript auf dem Endgerät. 
Für die Rückgabe der geänderten Daten werde ich ein verstecktes 
Formularfeld verwenden. Dort kommen die Binärdaten als ASCII-Hex Werte 
rein. Damit habe ich statt 7kB nur 256 Byte, die zum ESP zurück müssen. 
Damit gibt es keine Probleme mehr.

Ein weiterer Vorteil ist, kommen neue Parameter hinzu(es werden noch 
nicht die vollen 128Byte genutzt), dann muss ich nur die Scripte 
anpassen und brauche die Firmware im ESP nicht zu ändern.

Gruß
Steffen

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.