Forum: Mikrocontroller und Digitale Elektronik Arduino UIPEthernet: client.read() geht nicht in String


von Frank E. (Firma: Q3) (qualidat)


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.

: Bearbeitet durch User
von Sebastian W. (wangnick)


Lesenswert?

Frank E. schrieb:
> String buf(cbuf);

cbuf ist nicht nullterminiert. Versuch mal
1
String buf(cbuf,min(cnt,sizeof(cbuf)));

LG, Sebastian

von Frank E. (Firma: Q3) (qualidat)


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

: Bearbeitet durch User
von Michael U. (amiga)


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

von Εrnst B. (ernst)


Lesenswert?

Frank E. schrieb:
> String buf="";
...
>     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);

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.