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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren