Pages: [1]   Go Down
Author Topic: Serial.println, String und der Fehler  (Read 835 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Servus,
vor kurzem hatte ich einen sehr seltsames Problem mit meinem Arduino:
Das Ausführen der Methode ReadIDs() funktionierte zwei Mal, und beim dritten mal nicht mehr. Danach hängt sich der Arduino auf oder resetet.
Code:
String ReadID(int index){
  String ID;
  for (int j = 0; j < 8; j++){
    //ID += char( EEPROM.read(index * 8 + j + 1));
    //ID += char( 65);
    ID += 'A';
    //ID = ID + 'A';
  }
  return ID;  
}

String ReadIDs()
{
  int cnt = getcount();
  Serial.println(cnt);  
  for (int i = 0; i < cnt; i++){
    //Serial.println("loop");
    //ReadID(i);
    Serial.println(ReadID(i));
  }
}

Quote
Serial Ready

1
AAAAAAAA
1
AAAAAAAA
1

Nach stundenlangen rumprobieren glaube ich, die Fehlerquelle gefunden zu haben. Der Fehler taucht nur auf, wenn ich den zurückgegebenen String über println ausgeben möchte, nicht wenn ich die Funktion ReadID(index) aufrufe ohne den Wert auszugeben.
Habe ich etwas übersehen oder könnte das Problem tatsächlich bei der println-Methode, bzw. dem String-Objekt selbst liegen?

Viele Grüße
Werni
« Last Edit: January 04, 2013, 06:30:28 pm by Werni » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3071
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

String und unerklärliches Verhalten hat eine einfache Lösung: Keine Strings verwenden !

ID += 'A'; // GANZ BÖSE

Dass es nur 3*8 mal geht, wundert mich zwar etwas, ( 200*8 wäre klarer )  aber vielleicht hast du ja in den nicht gezeigten Code Zeilen noch mehr Speicherfresser, oder du machst es so schnell, dass die eigentliche serielle Ausgabe nicht mitkommt, bevor es knallt.

Um acht 'A' auszugeben brauchst du kein String Objekt, klar. 
Aber auch sonst kommt man sehr gut ohne aus.

Quote
Mehrspaltige Anzeige hab ich
noch nicht oft gesehen
smiley-grin smiley-grin
trés chic
Logged

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

Quote
Mehrspaltige Anzeige hab ich
noch nicht oft gesehen
smiley-grin smiley-grin
trés chic

Ja, ich bin eben ein praktisch denkender Mensch smiley-grin Deshalb fande ich Strings auch so toll  smiley-sad
Wenn du mir jetzt noch sagen könntest was diesmal falsch ist, wäre ich dir sehr dankbar:


Code:
char* ReadID(int index){
  //String _ID;
  char ID[9];
  for (int j = 0; j < 8; j++){
    char c = char( EEPROM.read(index * 8 + j + 1));
    Serial.print(c);
    ID[j] = c;
    //ID[j] = '0';
  }
  ID[8] = '\0';
  Serial.println("");
  return ID;  
}

String ReadIDs()
{
  int cnt = getcount();
  Serial.println(cnt);  
  for (int i = 0; i < cnt; i++){
    Serial.println(ReadID(i));
  }
}

Quote
Serial Ready
h-1.0.0
1
003D640D
 Ç  Ç  
(konnte nicht CopyPaste machen, enthält also irgendwelche stoppzeichen)
Quote
Man dafür müsste es echt einen Button im Editor geben
(Ich bin so ein Formatierungskünstler smiley-grin)
« Last Edit: January 05, 2013, 11:38:44 am by Werni » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3071
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

char ID[9]; // am einfachsten mit einer globalen Variable
char* ReadID(int index){

  // char ID[9];  // eine lokale Variable ist weg, wenn die Funktion zu Ende ist
  for (int j = 0; j < 8; j++){
    char c = EEPROM.read(index * 8 + j + 1);
    Serial.print(c);
    ID[j] = c;
  }
  ID[8] = '\0';
  Serial.println();
  return ID; 
}


Bitte sehr ...  smiley-wink

Wer der Philosophie "keine globalen Variablen" zuneigt, kann natürlich einer Funktion einen Puffer und dessen Länge mitgeben.

byte ReadID(byte index, char* buf, byte bufsize); // liefert die tatsächlich geschriebene Länge zurück, falls das interessant sein sollte.
Logged

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

Aber ich brauch die Variable doch gar nicht mehr.
Der Wert wird doch mit return übergeben. Oder etwa nur ein Pointer auf die variable im Speicher?
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3071
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Oder etwa nur ein Pointer auf die variable im Speicher?
Natürlich ist ein char* ein Pointer.
Ob du diesen Pointer auf eine globale Variable als Rückgabewert lieferst oder nicht, ist eigentlich Geschmackssache.

Ich finde (Motto: "Vermeide globale Variablen") es schön, wenn man einer Funktion ansieht, was sie an Daten benutzt und was sie verändert, mehr oder weniger.
ReadID sollte also eigentlich jetzt void SetIDFromEPROM(byte index); heissen...


Ein String Objekt wird übrigens bei c++, java oder c# auch nur als Pointer bzw. Referenz übergeben, aber es wurde dynamisch auf dem heap erzeugt, öfters umkopiert als man glaubt, und alle nicht mehr benötigten Kopien warten auf die Müllabfuhr. Arduino ist aus Italien, und da ist die Müllabfuhr ein Problem. smiley-wink

(SCNR,  Hoffentlich liest Uwe nicht mit, oder stellt fest dass 1. er aus Südtirol ist, 2. Arduino aus Turin, 3. diese blöden Klischees sich, wenn überhaupt, nur auf Neapel und weiter südlich beziehen) 

Auf jeden Fall sind die 2048 Byte RAM eines Ardiuno Uno für solchen Schnickschnack zu schade.
Zumal eine Fehlerbehandlung auch nicht wirklich stattfindet.  (Kostet erstens Programmcode-Platz und zweitens, was soll ein µC auch groß machen ... )
Schön, dass einige c++ Features trotzdem gehen, z.B. dass print() so schön vererbt wird.
Logged

Pages: [1]   Go Up
Jump to: