Strings verketten?

Hallo Leute ich werde wahnsinnig.
Mein Quellcode ist so lang das ich diesen nicht komplett posten kann. Da findet sich niemand zurecht, deswegen poste ich nur die Ausschnitte.
Ich habe drei Variablen, welche mit ein paar hundert Zeile Quellcode beschrieben sind:

String HTML_FOOTER = R"=====( ... )=====";
String HTML_HEAD = R"=====( ... )=====";
String HTML_DEV = R"=====( ... )=====";

Lasse ich mir jetzt zur Laufzeit die drei Strings EINZELN in die Konsole schreiben klappt alles wunderbar und ich bekomme die Ausgabe im Seriellen Monitor. Hierfür habe ich folgende Code verwenden:

  Serial.println(HTML_HEAD);
  Serial.println(HTML_DEV_EDIT);
  Serial.println(HTML_FOOTER);

Nun habe ich mir über dem Setup eine Globale String Variable erstellt:

String LOAD_UI;

und verknüpfe die 3 Strings zu einem.

  LOAD_UI = HTML_HEAD + HTML_DEV_EDIT + HTML_FOOTER;

Versuche ich die Variable auszugeben, passiert einfach gar nichts, bzw. es wird ein "" ausgegeben.

  Serial.println(LOAD_UI);

Was mache ich falsch?

Speicherüberlauf?

Ich glaube, Dir ist schon ziemlich am Anfang mal gesagt worden, das String auf Arduino irgendwann schief geht, weil es (grob gesagt) den Speicher zumüllt.

Das scheint Dich aber nicht interessiert zu haben und jetzt könnte es sein, dass Dir der Arduino die Quittung dafür gibt.

Gruß Tommy

magie004:
Hallo Leute ich werde wahnsinnig.
...
[F] Was mache ich falsch?

[A] Du wirst wahnsinnig.

Ich vermute das Gleiche wie Tommy. Evtl. einen (Voodoo-)Versuch wert: Initialisiere LOAD_UI mit "".

Gruß

Gregor

Tommy56:
Ich glaube, Dir ist schon ziemlich am Anfang mal gesagt worden, das String auf Arduino irgendwann schief geht, weil es (grob gesagt) den Speicher zumüllt.

Das habe ich auch nicht aus Ignoranz übergangen. Einige meiner verwendeten Library's benötigen nunmal einen String als Input und ich hab nicht jeden Tag und auch nur sehr begrenzt Zeit für mein Projekt, somit muss ich mit dem Arbeiten was da ist :slight_smile:

Danke für eure Hilfe, aus irgend einem Grund hat sich das Problem gerade von selbst gelöst. Sollte es nochmal auftreten, versuche ich es mal mit dem Initialisieren

Probleme, die sich von selbst lösen, haben die unangenehme Eigenschaft sich im unpassenden Moment wieder zu melden.

Gruß Tommy

Weiser Tommy56,
das Problem ist wieder da. Diesmal noch komischer.
Nach dem Verketten:

UserInterface = HTML_HEAD + HTML_DEV_EDIT + HTML_FOOTER;

ist die String Variable "UserInterface" = HTML_FOOTER
Der Rest fehlt. Ich könnte kotzen -.- Meinst du echt das Problem liegt am String?

Was zeigt den der Speicherverbrauch beim compilieren ? Ram wäre wichtig.

Zum Speicher:

Der Sketch verwendet 258373 Bytes (24%) des Programmspeicherplatzes. Das Maximum sind 1044464 Bytes.
Globale Variablen verwenden 47492 Bytes (57%) des dynamischen Speichers, 34428 Bytes für lokale Variablen verbleiben. Das Maximum sind 81920 Bytes.

Ich müsste einiges Umstricken.
Einmal bräuchte ich die Möglichkeit “lange” Zeichenketten (wie ein HTML Code) mit Anführungszeichen etc ähnlich wie hier in einer Variable abzulegen:

String HTML_FOOTER = R"=====(

    </div>
      
  <center><img onclick='alert("Diese Funktion steht noch nicht zur Verfügung")' src='images/add_icon.svg' style='margin-top:35px; margin-bottom:35px; width:50px; height:50px' ></center>

</body>

</html>

)=====";

und die Replace Funktion bräuchte ich auch! Lässt sich das so auf ein Car überführen?

Der RAM-Speicher auf einem Arduino ist arg begrenzt. Die Klasse String geht mit dem Speicher sehr frevelhaft um und ist nach einigen Aussagen zudem fehlerhaft implementiert.

z.B. String t1 = "Text";
t1 = t1+"Text2";

erzeugt 3 Strings (t1, "Text2" und neuen t1) und räumt die nicht mehr benutzten nicht wirklich auf. Der Heap (der Speicher für dynamische Speicherstrukturen) wird dadurch fragmentiert (vulgär: zugemüllt)

Da der Speicher zur Laufzeit dynamisch belegt wird, kann der Compiler den auch nicht in die Speicherberechnung mit einbeziehen.

Das die Klasse String auf Arduino ein Fehler ist, wird eigentlich jedem, der damit ankommt klar gesagt. Es interessiert manche nur nicht, weil es ja so bequem erscheint.

Wenn die Lib einen String s1 zurück liefert, kann man mit s1.c_str() auf das char-Array zugreigen und damit weiter arbeiten.

Mehr zu Zeichenketten in C habe ich in dem Tutorial zusammen geschrieben.

Evtl. kannst Du noch konstante Zeichenketten in den PROGMEM verlagern. Das geht aber nicht mit Strings.

Gruß Tommy

Ich habe Dir den Link zum Tutorial nicht umsonst rein geschrieben. Das solltest DDu durcharbeiten und verstehen.
So ohne Plan umstellen, das wird nix.

Gruß Tommy

Okay, wird gemacht :slight_smile:

Dein Tutorial lässt leider einen für mich sehr wichtigen Bereich aus und glaube auch nicht das es so eine Funktion für Chars gibt.

In meinen Variablen steht ein HTML Code in dem gewissen Details im Setup dynamisch angepasst werden. z.B. das Einfügen einer IP Adresse, welche zum Zeitpunkt des Kompilieren noch nicht fest steht.

Dies löse ich aktuell wie folgt:

HTML_HEAD.replace("|IP|",IP_String);

Im HTML Code sind alle unbekannten Inhalte mit Platzhaltern belegt, welche ich später ersetze. Ich habe nun meinen String HTML_HEAD.replace in ein char* überführt, aber leider funktioniert dadurch dann natürlich die Replace Funktion nicht mehr. Was kann man hier anstelle machen?

Stimmt, die Funktion gibt es nicht. Die kann man aber bauen.
Mit strstr den Teilstring suchen und dann mit strcat den Ersatz einfügen und mit strcat den Rest anhängen. dazwischen etwas Pointerrechnung.

Wird nicht schwer werden, wenn Du den Rest verstanden hast..

Gruß Tommy

magie004:
... Was kann man hier anstelle machen?

Dir wird nichts Anderes übrig bleiben, als Deinen Code auf klassische C-Strings umzustricken. Immerhin gibt es Standardfunktionen für das, was Du erreichen möchtest.

Gruß

Gregor

Ich werfe mal meine Meinung ungefragt einfach hier in den Ring.
Muss das sein, das du den armen Kerl mit HTML quälst?
Muss der Arduino wirklich die Webseite anzeigen?
Kannst du nicht einen *Pi oder Cubie verwenden für HTML und denen dann nur deine Werte senden, z.B. MQTT?
Ich habe das auch mal ne Weile probiert, am Ende war einfach alles zu groß bzw. der Arduino zu klein, was man an HTML und Co da machen kann.
Ich setze nun MQTT ein, lasse mir den Kram senden und verarbeite das an einer Stelle die dann z.B. mit PHP den Quatsch in Sekunden programmieren läßt.
Das entbindet dich aber nicht davon die Strings und co zu verstehen … bin auch noch etwas entfernt davon :slight_smile:

just my 2 cents.