Gibt es bei file.read() eine MaxFileSize?

Hey Leute,

ich bin gerade genervt von einem "Fehler" ... Ich habe auf einer SD Karte eine Datei S.TXT eine Liste von Datumsangaben:

7.2.2019,
7.3.2019,
4.4.2019,
2.5.2019,
25.5.2019,
2.5.2019,

Diese Liste lässt sich sauber auslesen, in Variablen speichern oder im SerialMonitor anzeigen. Sobald ich aber an die Liste ein weiteres Datum anhänge, zeigt der SM nichts mehr an. Er überspringt die Zeile mit dem AusgabeBefehl ohne Fehlermeldung einfach.

Daher stellt sich mir die Frage: Ist die Datei bei bereits einem weiteren Datum zu groß???

Hi

Versuch macht kluch.
Erstelle die .txt Datei mit WENIGER Einträgen, füge Einen hinzu und bekomme den Fehler erneut.
Zumindest, wenn die gezeigten 6 Zeilen 'die Datei' sind, ist es sehr unwahrscheinlich, daß Da etwas zu groß geworden ist.
Folglich machst Du irgend etwas falsch - wenn Dich das WAS interessiert, gib uns mehr Informationen - z.B. Dein aktueller Sketch, Der den Fehler zeigt.

MfG

Die TXT-Datei erstelle ich am Computer. Sie besteht nur aus genau diesen 6 Zeilen. Kopiere ich bspw. die letzte Zeile und setze sie als 7. Zeile ans Ende der Datei, gibt es keinen Fehler, sondern er macht einfach nichts. Habe ich ja bereits geschrieben.

 if (!SD.begin(chipSelect)) { 
        Serial.println("SD-Karte konnte nicht initialisiert werden."); 
  } else {
    Serial.println("SD-Karte initialisiert.");
  }



      
  if (SD.exists("S.TXT")) {
    Serial.println("Daten gefunden.");
  } else {
    Serial.println("Daten nicht gefunden.");
  }
  
  file = SD.open("S.TXT", FILE_READ);


  
  if (file) {
    Serial.println("Lese Daten ...");
    
    while (file.available()) { 
      daten_schwarz += (char)file.read();;
    }
    Serial.println(); Serial.print("Die Daten lauten: " + daten_schwarz);
    file.close();
    Serial.println(); Serial.println("Daten eingelesen.");
  } else {
    Serial.println("Datei kann nicht gelesen werden.");
  }

Welcher Datentyp ist denn daten_schwarz?

Aber irgendwie schreit diese Zeile nach Speicherfragmentierung: daten_schwarz += (char)file.read();;

Es ist ein String. Es ist übrigens auch egal, ob ich den String mit Zahlen, Symbolen oder Buchstaben fülle.

Gibt es denn eine bessere Methode den Inhalt einer Textdatei in eine String-Variable zu speichern?

recognite:
Gibt es denn eine bessere Methode den Inhalt einer Textdatei in eine String-Variable zu speichern?

AFAIK nein. Nimm für sowas besser ein char-Array.

Gruß

Gregor

Naja, Ziel ist eigentlich ein Array in diesem Format:

String pruef_schwarz[] = {"27.1.2019","25.2.2019","21.3.2019"};

recognite:
Naja, Ziel ist eigentlich ein Array in diesem Format:

String pruef_schwarz[] = {"27.1.2019","25.2.2019","21.3.2019"};

Nimm dafür besser ein zweidimensionales char-Array.

Ich finde Strings ja auch handlicher, zumal ich mit den ganzen C-Funktionen à la strlen() auf Kriegsfuß stehe. Ich habe halt „direkt“ C++ gelernt und habe fast keine Erfahrungen mit char-Arrays.

Gruß

Gregor

Las dir mal in einem Editor anzeigen, ob die eingefügte letzte Zeile auch ein Zeilenendezeichen hat. Oder mach bewusst einen Zeilenumbruch dran.

recognite:
Naja, Ziel ist eigentlich ein Array in diesem Format:

String pruef_schwarz[] = {"27.1.2019","25.2.2019","21.3.2019"};

Das ist meiner Ansicht nach ein sehr ineffizientes Ziel.

Das obige Konstrukt benötigt:

3 * 6 Byte für den Array und 3 * 10 (bei anderen Daten 11) Byte für die Daten, ergibt 48 Byte.

struct Datum {
  byte tag;
  byte monat;
  byte jahr; // Offset zu 2000
} dListe[] = { {27, 1, 19}, {25, 2, 19}, {21, 3, 19}, };

verbraucht nur 9 Byte und ist wesentlich leichter zu verarbeiten.
Wenn du Daten vor 2000 brauchst könntest du das Offset auf z.B. 1900 festlegen.
Einige Bits in tag und monat sind da noch unbenutzt, da könntest du noch weitere Infos unterbringen.

Hallo,

lass Dir doch die Filegrösse mit anzeigen, und in der while schleife die einzelnen eingelesen Zeichen.

ich vermute in Deiner Datei steht was drin das Du nicht sehen kannst, mal mit einen Hexeditor öffne und ansehen.

Auf was für einem Arduino soll das ganze denn laufen?
Ein 328-basierter kann zwar SD-Karten lesen, braucht aber dafür schon mal (SD.h) einen großen Teil des RAM. So luxuriöser String-Firlefanz wie

s  +=(char) file.read();

ist dann leicht zuviel.

Ah okay. Der RAM ist also das Problem.

Ich möchte per SD Karte eine Liste von Daten (Plural von Datum) einlesen. Das o.g. Array durchleuchte ich dann mit dem heutigen Datum (RTC). Bei Treffer leuchten LEDs.

Es wird ein kleines Helferlein, das ich mir neben die Wohnungstür hängen möchte. Es erinnert mich an die Mülltonnenabholung. Ich habe es schon zig mal vergessen und bin im Müll erstickt. (Einmal monatlich)

Es funktioniert eigebtlich alles hervorragend. Außer das Einlesen. Das Array mit den Daten hatte ich testweise einfach vorm setup definiert. Gestern habe ich dann das mit dem SD Modul versucht.

Bin blutiger Anfänger.

Wenn die Daten in der Datei zeitlich sortiert sind, musst du nur zeilenweise lesen, auswerten, und prüfen, ob heute was besonderes ist, oder ob ďu schon in der Zukunft bist.

Außer den paar Buchstaben deŕ aktuellen Zeile brauchst du keine Arrays und keine Strings.

Und kannst beliebig große Dateien lesen.

Die Frage nach MaxFileSize ist damit erstmal vom Tisch.

Hallo,
Die Daten in der Datei müssen doch gar nicht sortiert sein . Einfach zeilenweise auslesen und wenn eine Zeile mit dem aktuellen Datum gleich ist geht die Lampe an .

Eine Zeile ist dann etwa 10 Byte lang .

Heinz

Das klingt interessant. Könnt ihr mir mal ein Schlagwort geben, damit ich mich dahin schlau machen kann? Also wie kann ich nur bis zu einem bestimmten Punkt auslesen? Und vor allem dann da wieder ansetzen?

Wenn Du das File nicht schließt, kannst Du beim nächsten Read an der aktuellen Position weiter lesen.
Wenn Du es zwischendurch schließen willst, musst Du Dir die Anzahl der Bytes, die Du bereits gelesen hast, merken und mit fp.seek(position) darauf positionieren.

Gruß Tommy