Pages: [1]   Go Down
Author Topic: String über TCP bekommen  (Read 757 times)
0 Members and 1 Guest are viewing this topic.
Berlin
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Leute,

ich bin gestern abend fast verzweifelt. Ich habe ein Mega Board mit einem Ethernet shield. Auf dem habe ich einen Server laut Referenz programmiert. An einem Windows-Rechner habe ich einen Client (mit Autoit) geschrieben. Die Datenübertragung läuft auch super.
ABER:
Wenn ich vom Windows-Client ein "hallo" sende und mir das, was ich empfange über den serial.println() am SerialMonitor anzeigen lasse, dann bekomme ich nur die Zahlen, entsprechend dem ASCII Code.
Das Umwandeln habe ich auch hinbekommen mit char(variable), aber dann bekomme ich die einzelnen Buchstaben heraus, also h a l l o. Also dachte ich, ich reihe die Characters, die ich erhalte einfach zusammen. Aber dann kommt nur noch nen Rechteck heraus, das ich angezeigt bekomme, ähnlich wie sie in einem Word-Dokument angezeigt werden, wenn nicht das richtige kantonesische Sprachpaket installiert ist.

Ich möchte also am Client "hallo" senden und am Server "hallo herausbekommen. Wo ist mein Fehler? Ist char() gar keine Variable sondern nur ein Pointer?

Die Suche hab ich bemüht, gestern abend schon stundenlang, aber ich bin auf nichts gestoßen, dass mit helfen konnte.
Vielen Dank für eure Hilfe.




Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1397
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Poste doch mal den Code von Client und Server. Hellsehen kann hier, außer Uwe, keiner und der ist Mittwochs immer rodeln  smiley-mr-green
Ich vermute mal, aber das ist NUR eine Vermutung ohne Code, das Du schon das richtige bekommst, aber vermutlich ein int oder byte aus dem TCP-Strom liest und das auch als Zahl im Serial Monitor ausgibst.
Am einfachsten definiert man sich einen Empfangspuffer (char buffer[50]; ) und zählt mittels einer Index-Variable den Index im Array hoch, während man die gelesenen Bytes gleich in den Puffer schreibt (buffer[index++] = client.read(); )
Dabei aufpassen, das man maximal 49 Zeichen liest, also sinnvolle Abbruchbedingung setzen und dann noch das letzte byte auf den Wert 0 (nicht fas Zeichen '0') setzen. (buffer[index]=0;)
Dann kannst Du mit dem C-String "buffer") weiterarbeiten. Z.B. Serial.println(buffer);
Mario.

« Last Edit: February 27, 2013, 09:09:04 am by mkl0815 » Logged

Berlin
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah OK, das klingt logisch. Leider bin ich auf Arbeit und kann gerade nicht den Quelltext posten, aber so ungefähr hab ich verstanden was du meinst.
Bin eben ein Absoluter Neuling in C. In Basic hätte ich den Fehler wohl gefunden.
Aber wenn ich später zu Hause bin, dann poste ich den Text mal, wahrscheinlich wird dann deutlich wo mein Fehler ist.

Aber vielen Dank trotzdem schonmal für den Hinweis. smiley-cool
Logged

Berlin
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, ich poste mal das was ich geschrieben habe.
Code:
#include <Ethernet.h>
#include <SPI.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x97, 0x0B };
byte ip[] = { 192, 168, 1, 241 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

EthernetServer server = EthernetServer(23);

void setup(){
  Serial.begin(9600);
  // initialize the ethernet device
  Ethernet.begin(mac, ip, gateway, subnet);
  // start listening for clients
  server.begin();
}
void loop(){
  char type;
  int t = 1;
  // if an incoming client connects, there will be bytes available to read:
  EthernetClient client = server.available();
  if (client == true) {
    Serial.println("readstart");
    t = client.read();
    do{
      type = char(t);     
      Serial.println(type);
      t = client.read();
    }
    while (t != -1) ;
  }   
}

und das, was ich ausgeworfen bekomme.
Aber ich möchte doch gerne das "hallo" als "ein Wort" haben.

Unter Basic kann ich einfach Strings mit "&" zusammenfügen, geht das unter C mit char nicht? Oder was fehlt?


* Com64.JPG (13.9 KB, 414x374 - viewed 9 times.)
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2743
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Unter Basic kann ich einfach Strings mit "&" zusammenfügen, geht das unter C mit char nicht? Oder was fehlt?

In C geht das viel einfacher ...

Code:
static char text[80];
byte pos = 0;
while (client.available())
   text[pos++]= client.read();  // Text übertragen, pos wird hochgezählt
text[pos] = 0; // Endekennung, fertig ist der String

Serial.println(text);
und in deinem Fal noch einfacher:

Code:
if (client.available() ) {
  char t = client.read();
  Serial.write(t);
}
Logged

Berlin
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vielen Dank, das hat schonmal weiter geholfen. ABER, klar krieg ich das im Serial Monitor dann hintereinander aber ich will doch erreichen, dass der Wert "hallo" in einem String steht, mit dem ich dann weiter arbeiten kann. smiley

Ende vom Lied soll sein, dass der Client eine Message sendet, die aussieht wie: "ID|Name|Messwertname|Messwert", also "127|TAB1|TempWZ|513", womit mein Arduino dann weiss: aha, der Teilnehmer mit der IP 192.168.1.127 ist das Tablet TAB1 und schickt mir die Temperatur im Wohnzimmer und der Wert am Analog in ist 513.

Hoffe so ist es bißchen logischer nachzuvollziehen. smiley
Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 721
42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dann halte dich an michael_x's lösung mit dem Chararray - was nichts anderes als ein String ist. Vielmehr ist jeder String ein Chararray.

Code:
static char text[80];
byte pos = 0;
while (client.available())
   text[pos++]= client.read();  // Text übertragen, pos wird hochgezählt
text[pos] = 0; // Endekennung, fertig ist der String

jetzt kannst du mit "text" weiterarbeiten
Logged


Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2743
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
jetzt kannst du mit "text" weiterarbeiten

Das geht sicher etwas anders als in Basic und anderen, aber deutlich Speicherplatz-sparender.
Wenn du den client (bzw. was er sendet) selbst im Griff hast, würde ich empfehlen dass die Texte immer gleich lang sind, dann hast du es super einfach:

Ersetze die '|' durch eine 0 (Endekennzeichen) schon hast du lauter Teilstrings, die du leicht in Zahlen wandeln kannst (atoi) ,  oder mit strcmp vergleichen kannst.

Mit unterschiedlich langen Teilen musst du halt zunächst durch den ganzen Text gehen und dir die Trennpositionen merken.
Code:
char text[] = "127|TAB1|TempWZ|513" ; // als Beispieltext
char* p[4]; // Die vier Teile als Array von Textzeigern
int i=0;
p[i++] = text;  // Der erste ist immer am Anfang
for (int j = 0; text[j] != 0; j++)
{
   if ( text[j] == '|' )
   {
       text[j] = 0; // Endekennung
       p[i++] = & text[j]+1; 
    }
}

// Zur Demo:
for ( i=0; i < 4; i++)
   Serial.println (p[i]);

float temp = atoi(p[3]) / 25.5;
Serial.println(temp);
Logged

Berlin
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ja ich hatte auch schon überlegt das immer gleich lang zu machen aber das Problem da ist schon, dass wenn ich einen Analogeingang an einem Board einlese und den Wert zum Server schicken will, dann ist der Bereich von 0 bis 1024, das heisst, das kann ein- oder eben vierstellig sein.

Aber ich probier eure Lösungsansätze aus und dann schau ich wie das am besten passt.

Vielen Dank für eure Postings. Ich frag sonst nochmal, falls ich nicht weiter komme. smiley-grin
Logged

Berlin
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sauber, hat funktioniert.

Vielen Dank den freundlichen Helfern...
Logged

Pages: [1]   Go Up
Jump to: