Code speichert nur manche Strings auf SD Karte

Hey Leute,

ich möchte gerne arraydaten mit ID in einer .csv datei auf meiner SD Karte speichern.
Dazu bekomm ich einen pointer *array_pointer auf die erste Zelle des arrays.

Hab schon viele Tutorials gesehen und auch schon nachgeschrieben. Da hat das speichern auch geklappt. Jetzt hab ich aber den Code mit zu dem kompletten Programm zugefügt (wir arbeiten zu dritt an dem Code) und jetzt klappt natürlich gar nichts.

Das Ding ist nur der header String wird gespeichert, aber nicht der datastring. Ist doch voll komisch? Wenn ich wieder auf meinen alten Code zurück ruder klappt natürlich alles.

Danke für die Hilfe schon mal

void setup() {
  Serial.begin(115200);

  p_EKG_state_1 = &EKG_state_1;

  pinMode(CS_Pin, OUTPUT);
  if(!SD.begin(CS_Pin))
    {
      Serial.println("Card failed or not present");
    }

  EKG_data_transmision.matrixData = SD.open("/data.csv", FILE_APPEND);  //erstelle data.csv datei

  if(EKG_data_transmision.matrixData)
    {
    String header = "ID; Value;";
    EKG_data_transmision.matrixData.println(header);
    EKG_data_transmision.matrixData.close();
    Serial.println(header);
    Serial.println("card init sucess");
    }
  else
    {
    Serial.println("Couldnt open vector data file");
    }
  

}

Here is the function where everything should go down.

bool  EKG_data_transmision::write_matrix_to_SD(unsigned short *array_pointer) 
{

   if(!SD.begin(CS_Pin))
  {
    Serial.println("Card failed or not present");
    return 1;
  }
  matrixData = SD.open("/data.csv", FILE_APPEND);  //erstelle data.csv datei
  
  if(matrixData)
  {
    //sd karte immer noch da und schau ob data.csv exisitiert
    
    while(matrix_coloum < 3070)
    {
      if(matrix_coloum == 1024 || matrix_coloum == 2048)
      {
          header = "ID; Value;\n";
          matrixData.println(header);   
      }
      dataString = String(matrix_coloum) + "; " + "\n"; // + String(*array_pointer) 
      matrixData.println(dataString);
      //Serial.println("This is datastring:");
      Serial.println(dataString);
      array_pointer++;
      matrix_coloum++;
    } 
    
  }
   
  else{
    Serial.println("Error writing to file !");
}
  matrixData.close(); // close the file
  
  return 0;
}

Here is the class

#include "Arduino.h"
#include <WiFi.h>
#include "SD.h"
#include "SPI.h"
#include <vector>
#include <string>


class EKG_data_transmision
{
  private:
    
    String dataString;
    String header;
    unsigned short matrix_coloum = 0;
    
    
    
  public:
    EKG_data_transmision();

    File matrixData;

    //Def Funktions:
    bool write_matrix_to_SD(unsigned short *array_pointer);
    bool delete_matrix_from_SD(unsigned int record);
    bool send_record_to_DB(unsigned int record);
    bool connect_wifi(char* ssid, char *password);
    unsigned int count_record_from_SD();
    unsigned int get_last_record_from_SD();

    void set_sendingprogress(unsigned int record);
    unsigned int get_sendingprogress(unsigned int record);
    void set_wifi_password(char* password);
    char* get_wifi_password();
    void set_wifi_ssid(char* ssid);
    char* get_wifi_ssid();

};

Wenn ich anstatt matrixdata.println(), matrixdata.write() schreiben will bekomm ich diesen Fehler:

sketch\EKG_data_transimission.cpp: In member function 'bool EKG_data_transmision::write_matrix_to_SD(short unsigned int*)':

EKG_data_transimission.cpp:32:34: error: no matching function for call to 'fs::File::write(String&)'

           matrixData.write(header);   

                                  ^

In file included from C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SD\src/SD.h:17:0,

                 from sketch\EKG_data_transmision.h:3,

                 from sketch\EKG_data_transimission.cpp:2:

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:54:12: note: candidate: virtual size_t fs::File::write(uint8_t)

     size_t write(uint8_t) override;

            ^

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:54:12: note:   no known conversion for argument 1 from 'String' to 'uint8_t {aka unsigned char}'

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:55:12: note: candidate: virtual size_t fs::File::write(const uint8_t*, size_t)

     size_t write(const uint8_t *buf, size_t size) override;

            ^

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:55:12: note:   candidate expects 2 arguments, 1 provided

EKG_data_transimission.cpp:35:34: error: no matching function for call to 'fs::File::write(String&)'

       matrixData.write(dataString);

                                  ^

In file included from C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SD\src/SD.h:17:0,

                 from sketch\EKG_data_transmision.h:3,

                 from sketch\EKG_data_transimission.cpp:2:

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:54:12: note: candidate: virtual size_t fs::File::write(uint8_t)

     size_t write(uint8_t) override;

            ^

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:54:12: note:   no known conversion for argument 1 from 'String' to 'uint8_t {aka unsigned char}'

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:55:12: note: candidate: virtual size_t fs::File::write(const uint8_t*, size_t)

     size_t write(const uint8_t *buf, size_t size) override;

            ^

C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS\src/FS.h:55:12: note:   candidate expects 2 arguments, 1 provided

Multiple libraries were found for "WiFi.h"
 Used: C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFi
 Not used: C:\Program
Multiple libraries were found for "SD.h"
 Used: C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SD
 Not used: C:\Program
 Not used: C:\Users\Valentin\Documents\Arduino\libraries\SD
Multiple libraries were found for "FS.h"
 Used: C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\FS
Multiple libraries were found for "SPI.h"
 Used: C:\Users\Valentin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\SPI
exit status 1
no matching function for call to 'fs::File::write(String&)'

Ich hab anscheinend viele SD libraries, aber wenn ich die SD library von arduino benutzen will bekomm ich auch einen Fehler die architektur oder das esp32 board nicht supported wird

Was willst du hier überhaupt mit der String Klasse? Total überflüssig und ohne das wird es gehen

Naja ich muss doch die daten in strings umwandeln damit ich sie speichern kann. Das macht man doch mit String().

Oder wie stellst du dir das vor?

ich muss doch die daten in strings umwandeln damit ich sie speichern kann. Das macht man doch mit String().

Du musst zwischen Text und String-Objekten unterscheiden.Letztere braucht man nicht. Die sind für Leute erfunden worden, die von anderen Sprachen an Strings gewohnt sind.

statt

   dataString = String(matrix_coloum) + "; " + "\n"; // + String(*array_pointer)
   matrixData.println(dataString);

geht genauso gut

   matrixData.print(matrix_coloum); 
   matrixData.println(";\n");

String + Text sieht nur einfach aus, ist es aber nicht: hinterlässt Müll auf dem Heap!
Eine Zahl in einen Text wandeln macht übrigens schon print

Danke für deine schnelle Antwort.
Grad ausprobiert und es hat kurz geklappt wie du es geschrieben hast. Einfach den String weglassen.

Hab dann versucht den pointer da mit reinzubringen und jetzt klappts gar nichts mehr. Selbst wenn der pointer nicht mit dabei ist. :confused:

matrixData.print(*array_pointer);

Würde das theoretisch so gehen oder muss ich erst den pointer in einer variablen speichern damit es klappt?

Wenigstens weiß ich das es nicht unmöglich ist, nur warum das manchmal klappt und manchmal nicht versteh ich nicht wirklich.

Wieso dereferenzierst du den Zeiger? print() möchte ein Array oder einen Zeiger, welche in diesem Fall äquivalent sind

Xenoshell:

matrixData.print(*array_pointer);

Würde das theoretisch so gehen oder muss ich erst den pointer in einer variablen speichern damit es klappt?

Dein Kode entspricht einem

matrixData.print(array_pointer[0]);

ist also wahrscheinlich nicht das was du willst.

Deine Schnipsel helfen nicht dir zu helfen.

Wo wird matrix_coloum initialisiert? (Ist überhaupt ein merkwürdiger Name)
Warum findest du hier while besser als for?

bool  EKG_data_transmision::write_matrix_to_SD(unsigned short *array_pointer) {
   if(!SD.begin(CS_Pin))

SD.begin sollte nur einmal (meist in setup) aufgerufen werden.

Würde das theoretisch so gehen oder muss ich erst den pointer in einer variablen speichern damit es klappt?

Wenigstens weiß ich das es nicht unmöglich ist, nur warum das manchmal klappt und manchmal nicht versteh ich nicht wirklich.

Eine Hilfsvariable vom richtigen Typ hilft manchmal dem Menschen beim Verständnis dessen, was er da ausprobiert oder gefunden hat. Der Compiler braucht es jedenfalls nicht.

Was bei deinem print(*array_pointer); das Problem ist, kann keiner sagen, wenn der Datentyp von array_pointer unbekannt ist. (Evtl. ist auch der Wert interessant.)

In diesem Beispiel ist jedenfalls alles OK:

unsigned short array[] {10,20};
unsigned short *array_pointer = array;
Serial.println(*array_pointer); // "10"

Generell kann da wo ein pointer verlangt wird, immer auch der Name eines Arrays desselben Datentyps eingefügt werden. Und es gibt natürlich auch Pointer auf Arrays, das ist dann äquivalent zu einem Zeiger auf einen Zeiger.

Serenifly:
Wieso dereferenzierst du den Zeiger? print() möchte ein Array oder einen Zeiger, welche in diesem Fall äquivalent sind

Kenn mich leider echt nich gut mit Zeigern aus. Wie soll ich denn sonst den Zeiger aufrufen wenn nicht so?

michael_x:
Eine Hilfsvariable vom richtigen Typ hilft manchmal dem Menschen beim Verständnis dessen, was er da ausprobiert oder gefunden hat. Der Compiler braucht es jedenfalls nicht.

Was bei deinem print(*array_pointer); das Problem ist, kann keiner sagen, wenn der Datentyp von array_pointer unbekannt ist. (Evtl. ist auch der Wert interessant.)

In diesem Beispiel ist jedenfalls alles OK:

unsigned short array[] {10,20};

unsigned short *array_pointer = array;
Serial.println(*array_pointer); // "10"



Generell kann da wo ein pointer verlangt wird, immer auch der Name eines Arrays desselben Datentyps eingefügt werden. Und es gibt natürlich auch Pointer auf Arrays, das ist dann äquivalent zu einem Zeiger auf einen Zeiger.

array_pointer hat den datentyp unsigned short, weil wir Speicher sparen wollen.

Whandall:
Dein Kode entspricht einem

matrixData.print(array_pointer[0]);

ist also wahrscheinlich nicht das was du willst.

Deine Schnipsel helfen nicht dir zu helfen.

Wo wird matrix_coloum initialisiert? (Ist überhaupt ein merkwürdiger Name)
Warum findest du hier while besser als for?

bool  EKG_data_transmision::write_matrix_to_SD(unsigned short *array_pointer) {

if(!SD.begin(CS_Pin))



SD.begin sollte nur einmal (meist in setup) aufgerufen werden.

Ich will schon als erstes array_pointer[0] speichern, dann array_pointer[1], dann array_pointer[2] und so weiter. Deswegen mach ich am ende array_pointer ++

Ist es so viel besser eine for-schleife zu nehmen anstatt while? Ist doch auch nur ne schleife die irgendwann aufhört. Oder gibt es einen tollen Trick den ich damit machen kann.

Matrix_coloum wird in dem klassencode initialisiert der in meinem anfangspost steht.

Im Anhang ist der ganze Code. Die loop ist genau so eingestellt das es nur in meinen Case (3) geht. Ist mehr dazu gedacht, das ihr alles anschauen könnt. Ich bin nur für die data_transmission.h und data_transmission.cpp zuständig also werde ich wohl eher nur Fragen zu diesen zwei Dateien beantworten können.

EKG_Main_2.zip (7.58 KB)

Ah, ok. Jetzt sehe ich das. Das würde theoretisch gehen.

Aber gerade wenn du Zeiger nicht richtig verstehst, solltest du das nicht tun. Selbst wenn du zufällig was eintippst das kompiliert kannst du dir da extrem viele Fehler bauen. Sowas braucht man manchmal, aber C++ hat genug syntaktischen Zucker damit es in vielen Fällen überflüssig ist. Vor allem hier. Da macht man einfach sowas:

void print(unsigned int* values, size_t size)
{
    for(unsigned int = i; i < size; i++)
    {
       Serial.print(values[i]);
       Serial.print(';');
    }
}

Merke: Array-Variablen zerfallen bei der Übergabe in Zeiger auf das erste Element

Aber nur weil das Zeiger sind heißt das nicht dass den Subskript-Operator [] nicht mehr verwenden kannst

Ok ich hab jetzt ne for loop draus gemacht.

for(array_row = 0;array_row >100; array_row++)
    {
      if(array_row == 0 || array_row == 1024 || array_row == 2048)
      {
          matrixData.println(header);   
      }
      
      matrixData.print(array_row);
      matrixData.print(";");
      matrixData.print(array_pointer[array_row]);
      matrixData.print("\n");

    }

Hab auch den setup code von mir in ne eigene funktion gepackt.

Ich finds halt so komisch das immer nur der header von dem setup gespeichert wird und nicht die daten in der funktion. Eigentlich sollte doch println() oder print() keinen Unterschied machen.

Xenoshell:
Ich finds halt so komisch das immer nur der header von dem setup gespeichert wird und nicht die daten in der funktion.

for(array_row = 0;array_row >100; array_row++)

Da diese Schleife niemals betreten wird, wundert mich das nicht.

Hallo,

ich fühle mich berufen den Syntaxlapsus for (unsigned int = i von #9 zu korrigieren :wink: und damit auch optisch der Zeiger verschwindet eine weitere Variante des Funktionsrumpfes. Das beide Varianten absolut gleichwertig sind erkennt man auch daran, dass der Compiler mit einer Redefinition meckert, wenn man die Funktionsnamen gleich benennt, denn er kann die Funktion nicht überladen, auf Grund von vermeintlicher unterschiedlicher Signatur.

byte values[] = {1,9,2,8,3,7,4,6,5};

const byte anz = sizeof(values)/sizeof(values[0]);
 
void setup(void)
{
  Serial.begin(9600);
  foo1(values, anz);
  Serial.println();
  foo2(values, anz);
}

void loop(void)
{
  
}


// ****** Funktionen ******
void foo1 (const byte *data, const byte size)
{
  for(byte i = 0; i < size; i++)
    {
       Serial.print(data[i]);
       Serial.print(';');
    }
}

void foo2 (const byte data[], const byte size) // Zeiger optisch verschwunden                     
{
  for(byte i = 0; i < size; i++)
    {
       Serial.print(data[i]);
       Serial.print(';');
    }
}

Ansonsten sollte der TO auch über den ODER Vergleich nachdenken im Zusammenhang des Schleifenrumpfes. Irgendwas wurde vergriesgnaddelt.

for(array_row = 0;array_row >100; array_row++)
    {
      if(array_row == 0 || array_row == 1024 || array_row == 2048)

Whandall:

for(array_row = 0;array_row >100; array_row++)

Da diese Schleife niemals betreten wird, wundert mich das nicht.

oh ja stimmt, ich hab des ein bisschen falsch gemacht. Es sollte natürlich array_row < 100 sein.
Ich habe diese for schleife erst gerade eben eingebaut. Davor hab ichs mit einer while schleife gemacht. Ihr könnt den code mit der while schleife in dem Anhang vom vorherigen Post begutachten.
Ändert nicht desto trotz an der tatsache das der header gespeichert wird und der Rest nicht.

Doc_Arduino:
Hallo,

ich fühle mich berufen den Syntaxlapsus for (unsigned int = i von #9 zu korrigieren :wink: und damit auch optisch der Zeiger verschwindet eine weitere Variante des Funktionsrumpfes. Das beide Varianten absolut gleichwertig sind erkennt man auch daran, dass der Compiler mit einer Redefinition meckert, wenn man die Funktionsnamen gleich benennt, denn er kann die Funktion nicht überladen, auf Grund von vermeintlicher unterschiedlicher Signatur.

byte values[] = {1,9,2,8,3,7,4,6,5};

const byte anz = sizeof(values)/sizeof(values[0]);

void setup(void)
{
  Serial.begin(9600);
  foo1(values, anz);
  Serial.println();
  foo2(values, anz);
}

void loop(void)
{
 
}

// ****** Funktionen ******
void foo1 (const byte *data, const byte size)
{
  for(byte i = 0; i < size; i++)
    {
      Serial.print(data[i]);
      Serial.print(';');
    }
}

void foo2 (const byte data[], const byte size) // Zeiger optisch verschwunden                   
{
  for(byte i = 0; i < size; i++)
    {
      Serial.print(data[i]);
      Serial.print(';');
    }
}



Ansonsten sollte der TO auch über den ODER Vergleich nachdenken im Zusammenhang des Schleifenrumpfes. Irgendwas wurde vergriesgnaddelt.




for(array_row = 0;array_row >100; array_row++)
    {
      if(array_row == 0 || array_row == 1024 || array_row == 2048)

Ok ich schätze ich weiß ein bisschen besser wie Pointer funktionieren. Danke für die Erklärung.

Also diese if(array_row == 0 || array_row == 1024 || array_row == 2048) -abfrage wollte ich machen, weil wir drei kanäle haben die daten hergeben. Der Anfang dieser Kanäle ist 0,1024 und 2048.
Ist jetzt nicht sonderlich wichtig für das Problem das ich mit der Speicherung hab. Manchmal wird selbst die SD Karte nicht erkannt. Muss dann immer resetten bis es erkannt wird.

Hallo,

wenn du bestimmte Werte im Array suchst musste mittels Index des Arrays vergleichen.
Vergleicht alle Werte im Array.

byte values[] = {31,39,32,38,33,37,34,36,35};

const byte anz = sizeof(values)/sizeof(values[0]);
 
void setup(void)
{
  Serial.begin(9600);
  foo(values, anz);
}

void loop(void)
{
  
}


// ****** Funktionen ******

void foo (const byte data[], const byte size) // Zeiger optisch verschwunden                     
{
  for(byte i = 0; i < size; i++)
    {
       if(data[i] == 33)
       {
          Serial.println(F("Wert 33 gefunden"));
       }
       Serial.println(data[i]);
    }
}

Oder vergleichst nur eine ganz bestimmte Indexpostion.
Du musst unterscheiden zwischen der Anzahl der Werte eines Array und der Inhalte des Array.
size steht stellvertretend für die Anzahl der Werte im Array und i steht für den Zähler bzw. Indexposition eines Arrays. i darf nur nur bis size zählen. Sonst liest oder schreibst du wild im RAM rum.

Mmmh Nein. Ich glaube du missverstehst mich.

Ich werde 3 unterschiedliche ADC datensätze bekommen. Diese drei Datensätze werden alle in das gleiche Array gespeichert.

Erster Datensatz : array[0] - array[1023]
Zweiter Datensatz: array[1024] - array[2047]
Dritter Datensatz: array[2048] - array[3071]

Am Ende würde ich gerne die drei Datensätze in unterschiedliche .csv dateien aufteilen. Dazu muss dann ganz am Anfang jeder Datei der header eingetragen werden.

Die Zeitpunkte wo der header reingeschrieben sein soll ist eben am einfachsten mit dieser if-Abfrage zu erfragen.

Hallo,

dafür wird es unterschiedliche Lösungsansätze geben. Entweder du unterscheidest die 3 in der for Schleife. Diese läuft dann eben bis 3071. Oder du übergibts das Array mit dem gewünschten Index-Range an eine Funktion die den Rest erledigt. Oder ... tausende Möglichkeiten tun sich auf. Davon die Sinnvollste wählen ist die schwerste Aufgabe. Mammutfunktionen sollte man meiden.

Hi

Für verschiedene Dateien solltest Du dann dort auch eben eine 'Neue' aufmachen.
Auch ist die Oder akut fragwürdig, da nur bis 100 gezählt wird (siehe for-Schleife) - dort ist eine Abfrage auf 4096 ... sagen wir Mal ... optimierungswürdig.

Den Sketch schon mit Serial.print gefüllt, um zu sehen, wo Der falsch abbiegt?

MfG

@Doc_Arduino
Das stimmt es gibt echt viele Möglichkeiten das zu machen. Bevor ich mich aber der Aufteilung in unterschiedliche Dateien widme, möchte ich gerne die die Daten überhaupt in einer .csv Datei speichern können

@postmaster-ino
Ich weiß das die Zahlen nicht stimmen. Wollte nur das Gerüst aufbauen damit ich danach nur noch die Länge der Schleife anpassen muss.

Der Sketch biegt leider gar nicht falsch ab.

Er geht genau wie vorgesehen in die EKG_data_transmission::write_matrix_to_SD() funktion. Geht dort in die For-Schleife rein in der matrixData.print(array_row); ausgeführt wird.

Speichert trotzdem nichts in die .csv Datei außer den header.

Ich weiß nicht wer von euch so ein SD-Karten Modul zu Hause hat. Wenn jemand es ausprobieren will, wäre das natürlich echt hilfreich :wink:

Hallo,

Kartenleser zum testen habe ich keinen mehr.
Aber in meinem mittlerweile sehr alten Code verwende ich nur
myFile = SD.open(Dateiname, FILE_WRITE)
und nicht die Option FILE_APPEND.

Dann habe ich eine Funktion nur zu beschreiben der Karte.
Darin prüfe ich vorm schreiben überhaupt ob die Karte noch da ist.
Ansonsten wird die Funktion gleich abgebrochen.
Sprichst du die Karte mittels SPI und dem CS Pin richtig an?

if (!SD.begin(pinCS))
{
    Serial.println(F("Write SdCard Init Fehler!"));
    return error = true;            
}

Wenn alles ok gehts los.

    myFile = SD.open(Dateiname, FILE_WRITE);
    if (myFile)
    {
        Serial.print(F("writing ... "));  
                 
        myFile.print(" ; ");              // 1. DS1820 Temperaturwert
        myFile.print(_Temp_Dallas_1);
        myFile.print(" ; "); 
        ...
        ...
        myFile.println();

        myFile.close();
        Serial.println(F("done"));
    } 
    else
    {
        Serial.println(F("SD error writing file"));  // if the file didn't open, print an error:
        return error = true;                         // Fehlerstatus setzen, es gab ein Problem
    }
bool ReadSdFileToSerial ()          
{
    bool error = true;                    
    if (!SD.begin(pinCS))
    {
     Serial.println(F("Read SdCard Init Fehler!"));
     return error = true;                 // mit Fehlerstatus abbrechen
    }
     
    myFile = SD.open(Dateiname);
    if (myFile)
    {
        Serial.println(F("open file ... "));  
        while (myFile.available())    // read from the file until there's nothing else in it:
        {
            Serial.write(myFile.read());
        }
        myFile.close();         
        Serial.println(F("file closed"));
      
        return error = false;             // Fehlerstatus setzen, alles fehlerfrei
    } 
    else
    { 
        Serial.println(F("error reading file"));  // if the file didn't open, print an error:
        return error = true;                      // Fehlerstatus setzen, es gab ein Problem
    } 
}

und wenn du deine Arraywerte wegschreiben möchtest, dann musste eben mittels Index zugreifen, weil das machst leider nicht. Schau dir dazu nochmal die Beispiele der SD Lib genauer an.

    myFile = SD.open(Dateiname, FILE_WRITE);
    if (myFile)
    {
        Serial.print(F("writing ... "));  
        
        for(byte i = 0; i < size; i++)
        {
            myFile.print(data[i]);
            myFile.print(";"); 
        }
    
        myFile.println();

        myFile.close();
        Serial.println(F("done"));
    } 
    else
    {
        Serial.println(F("SD error writing file"));  // if the file didn't open, print an error:
        return error = true;                         // Fehlerstatus setzen, es gab ein Problem
    }