Go Down

Topic: [Solved] String einlesen funktioniert nicht (Serial.read()) (Read 3531 times) previous topic - next topic

uthred

Jul 08, 2013, 03:31 pm Last Edit: Jul 24, 2013, 10:18 am by uthred Reason: 1
Hi,

Ich versuche gerade einen String einzugeben und anhand dieses eingegebenen Strings dann unterschiedliche Funktionen aufzurufen.
Damit versuche ich einen verarbeitbaren String zu erzeugen (Ziel war es solange Daten vorhanden sind den String zu ergänzen, solange bis keine Daten mehr vorhanden sind und 90 Zeichen nicht überschritten sind):
Code: [Select]
char* readline;
   int i=0;
   if (Serial.available() > 0||flag==true) {
     while( Serial.available() && i< 90) {
       readline[i++]+= (char)Serial.read();
    }
    readline[i++]+='\0';

Wenn ich nun "LCD" eingebe und das mit strcmp vergleiche kommt meist ein Wert größer als 0 raus:
Code: [Select]
char str[]="LCD";
   Serial.println(strcmp(readline,str));

Das gleiche Problem auch beim vernachlässigen der Groß und Kleinschreibung:
Code: [Select]
Serial.println(strcasecmp(readline,str));  

Mithilfe des folgenden Codes habe ich herrausgefunden das readline (trotz Eingabe) leer ist:
Code: [Select]
Serial.print("String readline: \"");
Serial.print(readline);
Serial.print("\" ist");
if(strcmp(readline,str)!=0){
Serial.print(" nicht");  
}
Serial.print(" gleich \"");
Serial.print(str);
Serial.print("\"");

Ausgabe:
Code: [Select]
String readline: "" ist nicht gleich "LCD"
Das kann ich mir nicht erklären...
Wahrscheinlich ist es irgendein kleiner Anfängerfehler, ich würde mich freuen wenn ihr mir den Fehler aufzeigt, eine Verbesserung oder alternative Lösung zeigt und am besten auch erklärt was mein Code falsch macht   :~

jurs


Das kann ich mir nicht erklären...


Haufenweise Fehler, da weiß ich gar nicht, wo ich anfangen soll.

Nur mal zwei herausgepickt:
char* readline

Das ist ein Pointer, aber es fehlt ein Speicher, wo Du was reinpacken kannst. Wenn Du Zeichen in einem Puffer sammeln möchtest, dann brauchst Du sowas:
char readline[91];
Das wäre ein Puffer von 91 Zeichen Größe, der insgesamt einen String von 90 Zeichen Länge plus abschließendes Nullzeichen aufnehmen kann.

Andere Sache:
   if (Serial.available() > 0||flag==true) {
     while( Serial.available() && i< 90) {
       readline[i++]+= (char)Serial.read();

Damit versuchst Du unmittelbar nach dem Empfang des ersten Zeichens alle Zeichen aus dem Puffer herauszulesen. Aber wenn erst ein Zeichen im Puffer ist, kannst Du auch nur ein Zeichen herauslesen.

Wenn Du den "Seriellen Monitor" der Arduino-Software verwendest, dann sendet der zwar immer die Zeichen einer ganzen Zeile auf einmal, aber auch das dauert Zeit. Zusammen mit dem Seriellen Monitor funktioniert es beispielsweise, nach dem Empfang des ersten Zeichens kurz auf die übrigen Zeichen zu warten:
   if (Serial.available() > 0||flag==true) {
      delay(100);
     while( Serial.available() && i< 90) {
       readline[i++]+= (char)Serial.read();

Oder so ähnlich.

uthred

Danke, das hat schonmal weitergeholfen  :)
Jetzt gibt es schonmal eine Ausgabe: "String readline: "L??JL" ist nicht gleich "LCD""
Die delay-Zeit habe ich auch schon hochgeschraubt, daran liegt es nicht...

Serenifly

readline[i++] += (char)Serial.read(); <--- damit addierst du etwas auf den Inhalt von readline[i++]

Das würde theoretisch funktionieren, wenn der Puffer auf 0 gesetzt wäre, aber du willst doch das, oder?:
readline[i++] = (char)Serial.read()

uthred

#4
Jul 08, 2013, 04:26 pm Last Edit: Jul 08, 2013, 04:38 pm by uthred Reason: 1
Danke, jetz bin ich nahe an der Lösung ;)
Derzeitige Ausgabe:(Umbruch ist noch drin)
String readline: "LCD
" ist nicht gleich "LCD"

Code: [Select]
while( Serial.available() && i< 90) {
       if((char)Serial.read()=='\n'){
       }
       else if((char)Serial.read()=='\r')
       {
       }
       else
       {
        readline[i++]= (char)Serial.read();
       }
     }
     readline[i++]='\0';


Ausgabe: "D"

TERWI

#5
Jul 08, 2013, 05:04 pm Last Edit: Jul 08, 2013, 05:11 pm by TERWI Reason: 1
.... nun liest du dir ja schon alle Zeichen vorher aus Serial aus, um auf CR oder sonstwas zu prüfen.

Lies doch erst mal reihenweise ein und über prüfe das letzte jeweile gelesene Zeichen in readline.
Wenn CR & Co. dann brech das einlesen ab und wirf das letzte Zeichen in readline raus, bzw ersetze es duch 0,

Du wirst sehen, dann steht da auch irgendwann "LCD" !

Also in etwa so:
Code: [Select]

while( Serial.available() && i< 90)
{
 readline[i++]= (char)Serial.read();
 if ((readline[i] == '\n') || (readline[i] == '\n'))
 {
   readline[i]='\0';
   break;
 }
}  
Serial.println(readline);

.... falls noch mehr Zeichen kommen sollten, bleiben die bei diesem Beispiel im Serial-Puffer hängen ....
To young to die - never to old for rock'n roll

uthred

Danke sehr ;)
Jetzt funktioniert es, zumindest Bei jeder 2. Eingabe :D
Mit Serial.flush() und delete[] readline versuche ich den Speicher zu löschen, aber Wenn ICH LCD Eingebe, erhalte ich zunächst das  gewünschte Ergebnis, dann aber folgt noch ein D oder ein CD, welches ich nicht eingegeben habe.

Aber das Problem werde ich auch alleine lösen können ;)

Vielen Dank nochmal für die Hilfe

Serenifly

delete[] brauchst du nur wenn du das array mit new angelegt hast. Ansonsten musst (und darfst!) du dich nicht darum kümmern Speicher freizugeben.

Wenn du den Inhalt des Arrays löschen willst (und nicht das Array selbst) verwende memset. Damit kannst du alle chars auf 0 setzen.

uthred

Ok danke, man merkt eben an jeder Ecke das ich ein absoluter Frischling bin ;) , aber es ist noch kein Meister vom Himmel gefallen und ich gebe mir Mühe
jetzt funktioniert es auch immer beim ersten Mal :D

Go Up