Arduino UIPEthernet: client.read() geht nicht in String

OP (Firma: Q3) #7673991
Lesenswert?
• ▲
▼

In dem folgenden Code-Schnipsel steht eine Lese-Routine (im Loop), um einen HTTP-Request in einen String einzulesen. Auf dem Uno mit der Lib "Ethernet" funktioniert das, auf dem Nano mit UIPEthernet (wegen des anderen Ethernet-Chips), bekomme ich das einfach nicht hin. Bitte mal draufsehen:

1
...
2
if(client){
3
  char cbuf[64];
4
  int cnt = 0;
5

6
  while(client.available()>0){
7
    char c = client.read();
8
    if(cnt<64){
9
      cbuf[cnt]=c;
10
      Serial.println(c); // <-- das wird lesbar ausgegeben
11
    }
12
    cnt++;
13
  }
14
  String buf(cbuf);
15
  Serial.println(buf); // <-- das ist immer leer
16
}

Bei der Ausgabe oben in Zeile 10 ist schön der Anfang des HTTP-Request vom Browser zu sehen, aber buf ist immer leer, nicht etwa verkrüppelter Text, nein, gähnende Leere. ... warum?

Danke für Tips.

OP (Firma: Q3) #7674105
Lesenswert?
• ▲
▼

Sebastian W. schrieb:

cbuf ist nicht nullterminiert. Versuch malString buf(cbuf,min(cnt,sizeof(cbuf))); LG, Sebastian

Moin. Danke für den Tip, hat aber leider auch nichts gebracht. Nach endlosen Versuchen funzt nun dieser Code stabil. Es geht darum, aus dem HTTP-Request des Browsers einen GET-Parameter heraus zu fummeln, z.B. http://192.168.10.70/?cmd=on

Da klappt jetzt damit zuverlässig:

1
...
2
String buf="";
3
int cnt=0;
4
while(client.available()>0 && cnt<64)
5
{
6
  int b = client.read();
7
  if(b>31 && b<128)
8
  {
9
    buf.concat(char(b));
10
    cnt++;
11
  }
12
  int anf = buf.indexOf(F("/?cmd="));
13
  int end = buf.indexOf(F(" HTTP"),anf);
14
  buf = buf.substring(anf+6,end);
15

16
  Serial.println(buf); // <-- temporäre Kontollausgabe
17
}

Möglicherweise hat es auch geholfen, konsequent alle String-Konstanten mit F("bla bla") in den Flash zu packen. Obwohl vorher 93% belegt, bzw. 350 Byte im RAM frei waren, ging es nicht. Jetzt mit fast 600 Byte kein Problem mehr ...

#7674135
Lesenswert?
• ▲
▼

Hallo,

ich nutze die String-Klasse sehr gern, allerdings auf ESP8266/ESP32. Wenn nicht genug freier Ram verfügbar ist, habe ich diesen Zustand selbst da schon erreicht. Es gibt keine Fehlermeldungen, es kommt nur ein leerer String zurück, wenn irgendein interner Buffer innerhalb einerStringfunktion nicht angelegt werden konnte. Auf den kleinen AVR vermeide ich String eigentlich generell und nutze die C-Stringfunktionen.

Gruß aus Berlin Michael

#7674415
Lesenswert?
• ▲
▼

Frank E. schrieb:

String buf="";

...

1
buf.concat(char(b));

Gerade sowas ist bei wenig Speicher ungünstig. Jedesmal wenn du den String um ein Zeichen verlängerst, muss potentiell neuer Ram ge-malloc-ed werden, der bisherige String umkopiert, und der alte Speicherplatz freigegeben werden.

Braucht also doppelte RAM-Menge, und fragmentiert den freien Speicher evtl. ungünstig.

der Arduino-String hat eine "reserve(bytes)"-Methode, damit kannst du vorher deine vermutliche String-Länge kundtun, und dieses wiederholte re-alloc verhindern.

String buf; buf.reserve(128-31);

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.