SD Datalogging maximale speicherzahl

Hallo Zusammen

mit dem Nachfolgenden Codebausteinen schreibe ich Daten aus einem String in die .txt Datei auf einer SD Karte. Im Anschluss printe ich die Daten als Graph auf einen TFT Bildschirm.

String dataString = "M1,";                      //Schreibt String der Messwerte  [Messstelle, Zyklus, Messuhr 1, Luftfeuchtigkeit, Temperatur]
    dataString = dataString + Zyklus_1;
    dataString += ",";
    dataString += value;
    //dataString += ",";
    //dataString += LF;
    //dataString += ",";
    //dataString += TP;

    SD.begin(chipSelect);                           //SD begin an Pin Chip Select
    dataFile = SD.open("wdh_data.txt", FILE_WRITE); //öffnet Datalog.txt
    dataFile.println(dataString);                   //Schreibt String auf SD KARTE
    Serial.println(dataString);                     //Debugging
    dataFile.flush();                               //Beendet Schreibvorgang auf SD-KARTE


    x = Zyklus_1;
    y = value;

    Graph(tft, x, y, 50, 290, 390, 260, 0, 1000, 100, 0, 13, 0.5, "Abweichung", "Zyklus", "mm", DKRED, RED, YELLOW, WHITE, BLACK, display3);

  }

Das ganze funktioniert auch, allerdings ist es jetzt bei jedem Versuch vorgekommen, dass nach dem 212ten Durchlauf keine Daten mehr auf die SD-Karte geschrieben werden. Der Graph wird allerdings korrekt weiter geschrieben.

Meine Frage: Warum beendet mein Programm das beschreiben der SD karte genau beim 212ten Zyklus?
Im Anhang ist eine Txt Datei und ein Foto vom meinem Bildschirm

IMG-20200113-123233 — ImgBB

WDH_DATA.TXT (2.59 KB)

SD.begin sollte ins setup.
Du öffnest immer das File, prüfst es nie und schließt es aber nie.

Mehr ist aus dem Fragment nicht rauszulesen.

Gruß Tommy

Wenn der Arduino ein Uno oder Nano ist, liegt es an

dataString += ","; (oder ähnlichem)

Das + ist eine sehr aufwendige Operation, zu kompliziert für den begrenzten RAM.
Und im Fehlerfall kann alles mögliche passieren, nur keine eindeutige Fehlermeldung.

Hattest Du nicht mal geschrieben, dass die Implementation von String verbessert wurde? Dann dürfte das doch kein Problem mehr sein oder doch?

Gruß Tommy

Tommy56:
Hattest Du nicht mal geschrieben, dass die Implementation von String verbessert wurde? Dann dürfte das doch kein Problem mehr sein oder doch?

Verbessert, ja, mag sein, aber die dynamische Speicherverwaltung existiert weiterhin.
Das Fragmentierungsproblem kann durch String::reserve() gemildert werden.

Ansonsten:
Wenn verstümmelter Code gepostet wird, ist davon auszugehen, dass der Fehler im geheimen Teil zu finden ist.
(Darum ignoriere ich solche Threads meistens.)

Hi

Dabei sollte das ganze String-Zusammenkleben komplett egal sein - wenn man die Happen selber den .print vorwirft, sollte exakt das Gleiche hinten ankommen - ganz ohne zusätzliche Strings.

MfG

Wenn verstümmelter Code gepostet wird, ist davon auszugehen, dass der Fehler im geheimen Teil zu finden ist.

Da hilft auch der Tip, das Problem in einem Demo-Testsketch zu zeigen, der vollständig ist, aber nur das Problem und seine minimale Umgebung enthält.

Das bedeutet sinnvolle weil lehrreiche Arbeit für den Fragenden, und das Problem löst sich oft selbst.

Sage mal in blaue daß zuwenig RAM auf dem Controller ist.
Grüße Uwe

Hier der gesamte Coder der die SD-Karte betrifft:

#include <SPI.h>                // SPI Library
#include <SD.h>                 // SD-Shield Labrary

const int chipSelect = 10;      //PIN SD-Shield

File dataFile;

void setup() {


  //pinMode(SS, OUTPUT);                //SD-SHIELD

  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1) ;
  }
  Serial.println("card initialized.");

  // Open up the file we're going to log to!
  dataFile = SD.open("wdh_data.txt", FILE_WRITE);
  if (! dataFile) {
    Serial.println("error opening datalog.txt");
    // Wait forever since we cant write data
    while (1) ;

  }

void loop() {

 String dataString = "M1,";                      //Schreibt String der Messwerte  [Messstelle, Zyklus, Messuhr 1, Luftfeuchtigkeit, Temperatur]
    dataString = dataString + Zyklus_1;
    dataString += ",";
    dataString += value;
    //dataString += ",";
    //dataString += LF;
    //dataString += ",";
    //dataString += TP;

    
SD.begin(chipSelect);                           //SD begin an Pin Chip Select
    
    dataFile = SD.open("wdh_data.txt", FILE_WRITE); //öffnet Datalog.txt
    dataFile.println(dataString);                   //Schreibt String auf SD KARTE
    Serial.println(dataString);                     //Debugging
    dataFile.flush();                               //Beendet Schreibvorgang auf SD-KARTE


    x = Zyklus_1;
    y = value;

    Graph(tft, x, y, 50, 290, 390, 260, 0, 1000, 100, 0, 13, 0.5, "Abweichung", "Zyklus", "mm", DKRED, RED, YELLOW, WHITE, BLACK, display3);
}

Mein erster Versuch wird es sein, SD.Begin ins Setup zu schreiben und dataFile.flush() mit dataFile.close() zu ersetzen.

Hatte SD begin im Loop damit ich die SD karte im laufenden Betrieb des Arduinos jeder Zeit entnehmen kann und der Code nach erneuten Einstecken der SD-Karte dennoch weiterhin funktioniert.

Tommy56:
SD.begin sollte ins setup.
Du öffnest immer das File, prüfst es nie und schließt es aber nie.

Mehr ist aus dem Fragment nicht rauszulesen.

Gruß Tommy

Hab im Schnelldurchlauf getestet die Datei mit dataFile.close(); zu schließen!

Hat für >300 Schreibvorgänge funktioniert.

Jetzt teste ich das Ganze noch am Prüfstand mit >1000 Schreibvorgängen.

Vielen Dank.

GELÖST! DANKE

Hi

Ist für 'GELÖST!' auch eine Lösung rausgesprungen, oder hast Du akut einfach nur keine Probleme mehr damit?
Also wirft der Sketch, Der mit SD.begin() in setup() 1000 Schreibvorgänge schafft, beim zurücksetzen nach loop() wieder den vorherigen Fehler?
(was ich mir durchaus vorstellen kann, da SD-begin() wohl etwas Speicher für die File-Verwaltung brauchen wird)

Dann hätten wir nämlich wirklich den Sorgenbringer gefunden und nicht nur das Problem umschifft.
NUR dann ist das Problem gelöst!

MfG

SD.Begin() steht wie gehabt im Loop

Das Problem wurde durch ersetzen von dataFile.Flush() mit dataFile.Close() gelöst.
Heißt für mich, erneutes öffnen von Dateien verbraucht RAM der nach 212x Öffnen der Datei dann voll war. Dadurch dass ich die Datei jetzt jedes mal wieder schließe wird der RAM nicht voll.

Ob SD.Begin() Auch Speicher belegt, was dann einen ähnlichen Effekt auslösen würde, weiß ich nicht.
Ich Teste das gerade und bin bei >3000 Speichervorgängen.

Aber SD.begin hat in der loop nichts verloren.
Das kann nicht vorhersagbare Ergebnisse bringen !

Ulli

beeblebrox:
Aber SD.begin hat in der loop nichts verloren.
Das kann nicht vorhersagbare Ergebnisse bringen !

Ulli

hast du denn sonst eine Idee wie ich die SD-Karte während der Loop läuft auswechseln kann?
einen Button der SD.begin(); auslöst?
SD ausstecken -> Daten sichern -> SD einstecken -> Button drücken?

Dann solltest Du SD.begin nur dann aufrufen, wenn Du die SD gewechselt hast.
In der Zeit solltest Du auch nicht auf die SD schreiben.

Gruß Tommy