SD-Kar­ten-Modul

Lese­zeit: 7 Minu­ten

Das SD-Kar­ten­mo­dul wird mit einer Micro-SD-Kar­te bestückt. Es kön­nen Ver­zeich­nis­se und Datei­en erstellt und gelöscht wer­den. In eine Datei kön­nen fort­lau­fend Daten geschrie­ben wer­den, die Daten kön­nen zei­len­wei­se auch wie­der gele­sen werden. 

Benö­tig­te Bibliothek:

Sketch → Biblio­thek ein­bin­den → Biblio­the­ken verwalten

Ach­te auf die Pin-Bele­gung des SD-Kar­ten-Moduls!
Die SD-Kar­te muss mit FAT32 for­ma­tiert sein!

Schlüs­sel­wortPara­me­terAkti­on
begin(Datenpin)Modul star­ten

int DatenPin = 4;
begin(DatenPin);
exists(Dateiname)Vor­han­den­sein einer Datei prüfen

exits("Lottozahlen.txt");
remove(Dateiname)Datei ent­fer­nen

remove("Lottozahlen.txt");
clo­se()Datei schlie­ßen

Datei.close();
open(Dateiname, Para­me­ter)
print()
println()
O_CREAT -> Datei erstel­len, wenn sie nicht existiert
O_WRITE -> in die Date schreiben
O_AT_END -> Start­po­si­ti­on zum Schrei­ben an das Ende der Datei setzen
Daten in Datei schreiben

open("Lottozahlen.txt", O_CREAT | O_WRITE | O_AT_END);

println("1 15 8 21 37 16 34");
open(Dateiname)
available()
read()
O_RDONLY nur lesenDatei öff­nen und Daten lesen

Datei = SD.open("Lottozahlen.txt", O_RDONLY);
// solange sich Zeilen in der Datei befinden ...
while (Datei.available())
{
  // ... werden sie gelesen und im Seriellen Monitor ausgegeben
  Serial.write(Datei.read());
}
mkdir(Verzeichnisname)Ver­zeich­nis erstellen

mkdir("Zahlen");
rmdir(Verzeichnisname)Ver­zeich­nis löschen

rmdir("Zahlen");
ls(Parameter)LS_R Inhalt rekur­siv anzeigen
LS_SIZE Datei­en mit Grö­ße anzeigen
LS_DATE Datei mit Datum anzeigen
Die Para­me­ter kön­nen auch kom­bi­niert werden:
ls(LS_DATE | LS_SIZE | LS_R);
Inhalt der SD-Kar­te anzeigen

openNext(Dateiname, Grö­ße)isDir() -> auf Vor­han­den­sein eines Ver­zeich­nis­ses prüfen
get­Na­me() -> Datei­na­me und -grö­ße ermitteln
file­Si­ze() -> Grö­ße der Datei in Bytes
File Verzeichnis;
File Datei;
char Dateiname[20];

Verzeichnis.open("/");

while (Datei.openNext(&Verzeichnis, O_READ))
{
  Datei.getName(Dateiname, sizeof(Dateiname));
  Serial.print(Dateiname);

  if (Datei.isDir())
  {
    Serial.println("/");
  }
  else
  {
    Serial.print('\t');
    Serial.print(Datei.fileSize());
    Serial.println(" Bytes");
  }
  Datei.close();
}

Jeder Funk­ti­on muss der Name des SD-Kar­ten-Moduls mit abschlie­ßen­den . vor­an­ge­stellt werden!

Das Bei­spiel­pro­gramm liest, schreibt oder löscht eine Datei mit Zufallszahlen.

# include "SdFat.h"

// Name des SD-Karten-Moduls
SdFat SD;

// Name der Datei, die geschrieben werden soll
File ZahlenZeigen;

// Datenpin für das SD-Kartenmodul
int DatenPin = 4;

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

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);

  // Zufallsgenerator starten
  randomSeed(analogRead(A0));

  /*
     SD-Karte mit Angabe des Datenpins starten
     wenn die Intialisierung fehlschlägt
     - keine SD-Karte vorhanden
     - falsche Pinbelegung
     -> es wird eine Fehlermeldung angezeigt
  */
  if (!SD. begin(DatenPin))
  {
    Serial.println("Initialisierung fehlgeschlagen!");
  }
  else Serial.println("Initialisierung abgeschlossen");

  // Menü
  Serial.println("-----------------------------");
  Serial.println("Datei schreiben mit 's', Dateien entfernen mit 'l'");
}

void loop()
{
  while (Serial.available() > 0)
  {
    // solange lesen, bis return \n = return eingegeben wurde
    char Eingabe = Serial.read();
    
    // Datei löschen
    if (Eingabe == 'l')
    {
      // wenn die Datei Zahlen.txt existiert -> Datei löschenn (remove)
      if (SD.exists("Zahlen.txt"))
      {
        SD.remove("Zahlen.txt");
        Serial.println("Datei Zahlen.txt entfernt!");
      }
      else
      {
        Serial.println("Datei Zahlen.txt existiert nicht!");
      }

      // Menü
      Serial.println("-----------------------------");
      Serial.println("Start mit 's', Dateien entfernen mit 'l'");
    }

    // Daten in Datei schreiben
    if (Eingabe == 's')
    {
      /*
        O_CREAT -> Datei erstellen, wenn sie nicht existiert
        O_WRITE -> in die Date schreiben
        O_AT_END -> Startposition zum Schreiben an das Ende der Datei setzen
      */
      ZahlenZeigen = SD.open("Zahlen.txt", O_CREAT | O_WRITE | O_AT_END);

      // wenn die Datei vorhanden ist
      if (ZahlenZeigen)
      {
        Serial.println("Schreibe Zahlen in Zahlen.txt ...");
        Serial.println("-----------------------------");

        // Zufallszahlen in die Datei schreiben
        for (int i = 0; i < 7; i++)
        {
          ZahlenZeigen.println(random(1, 100));
        }

        // Datei schließen
        ZahlenZeigen.close();
        Serial.println("Abgeschlossen.");
        Serial.println("-----------------------------");
      }

      else
      {
        Serial.println("Datei Zahlen.txt konnte nicht gelesen werden");
      }

      // Datei öffnen
      ZahlenZeigen = SD.open("Zahlen.txt");
      if (ZahlenZeigen)
      {
        Serial.println("Lese Datei Zahlen.txt ...");
        Serial.println("-----------------------------");

        // solange sich Zeilen in der Datei befinden ...
        while (ZahlenZeigen.available())
        {
          // ... werden sie gelesen und im Seriellen Monitor ausgegeben
          Serial.write(ZahlenZeigen.read());
        }

        // Datei schließen
        ZahlenZeigen.close();
        Serial.println("-----------------------------");
        Serial.println("Abgeschlossen.");
        Serial.println("-----------------------------");
      }

      else
      {
        Serial.println("Zahlen.txt konnte nicht gelesen werden");
      }
    }
  }
}

Das Bei­spiel­pro­gramm zeigt die Funk­tio­nen Ord­ner und Datei­en erstel­len und löschen, schreibt Daten in eine Datei und liest sie wie­der aus. 

So sieht es aus:

# include "SdFat.h"

// Eingabe fragt die Buchstaben ab
char Eingabe;

// Strings für die Dateioperationen
String Ordner;
String DateinameAbfragen;
String DatenSchreiben;

/*
  Anschlussbelegung:
  CS   -> Pin 4
  SCK  -> Pin 13
  SDI -> Pin 12
  SDO -> Pin 11
  VCC  -> 5V
  GND  -> GND
*/

// Name der SD-Karte
SdFat SD;

// Datenpin für das SD-Kartenmodul
int DatenPin = 4;

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

  // auf serielle Verbindung warten
  while (!Serial);
  delay(1000);
  /*
     SD-Karte mit Angabe des Datenpins starten
     wenn die Intialisierung fehlschlägt
     - keine SD-Karte vorhanden
     - falsche Pinbelegung
     -> es wird eine Fehlermeldung angezeigt
  */
  if (!SD.begin(DatenPin)) 
  {
    Serial.println(F("Initialisierung fehlgeschlagen!"));
  }
  else Serial.println(F("Initialisierung abgeschlossen"));

  // Menü
  Serial.println(F("-------------------------------------------------"));
  Serial.println(F("Verzeichnis lesen 'v', Verzeichnis erstellen 'n'"));
  Serial.println(F("Verzeichnis entfernen 'l', Datei erstellen 'e'"));
  Serial.println(F("Datei entfernen 'd', Befehle anzeigen 'b'"));
  Serial.println(F("Datei lesen 'a'"));
  Serial.println(F("-------------------------------------------------"));
}

void loop() 
{
  File Datei;
  File Verzeichnis;
  char Dateiname[20];
    
  while (Serial.available() > 0) 
  {
   // einzelnes Zeichen lesen
    Eingabe = Serial.read();

    // Inhalt der SD-Karte lesen
    if (Eingabe == 'v') 
    {
      Serial.println(SD.ls(LS_DATE | LS_SIZE | LS_R));
    }

    // Menü anzeigen
    if (Eingabe == 'b') 
    {
      Serial.println(F("-------------------------------------------------"));
      Serial.println(F("Verzeichnis lesen 'v', Verzeichnis erstellen 'n'"));
      Serial.println(F("Verzeichnis entfernen 'l', Datei erstellen 'e'"));
      Serial.println(F("Datei entfernen 'd', Befehle anzeigen 'b'"));
      Serial.println(F("Datei lesen 'a'"));
      Serial.println(F("-------------------------------------------------"));
    }

    // neuen Ordner anlegen
    if (Eingabe == 'n') 
    {
      Serial.print("Name des Ordners: ");

      // solange der String Ordner leer ist
      // -> solange lesen, bis return \n eingegeben wurde
      while (Ordner == "") Ordner = Serial.readStringUntil('\n');

      // wenn der Ordner nicht existiert -> Ordner erstellen
      if (!SD.mkdir(Ordner)) 
      {
        Serial.println("Ordner " + Ordner + " existiert bereits!");
      } 
      else Serial.println("Ordner " + Ordner + " erstellt!");

      // Variable leeren
      Ordner = "";
    }

    // Ordner löschen
    if (Eingabe == 'l') 
    {
      Serial.print("Name des Ordners: ");

      // solange der String Ordner leer ist
      // -> solange lesen, bis return \n eingegeben wurde
      while (Ordner == "") Ordner = Serial.readStringUntil('\n');

      // wenn der Ordner nicht existiert -> Fehlermeldung ausgeben
      if (!SD.rmdir(Ordner)) 
      {
        Serial.println("Ordner " + Ordner + " existiert nicht!");
      }
      else Serial.println("Ordner " + Ordner + " entfernt!");

      // Variable leeren
      Ordner = "";
    }

    // Datei löschen
    if (Eingabe == 'd') 
    {
      String DateinameAbfragen;
      Serial.print("Name der Datei: ");

      // solange der String Dateiname leer ist
      // -> solange lesen, bis return \n eingegeben wurde
      while (DateinameAbfragen == "") DateinameAbfragen = Serial.readStringUntil('\n');

      // wenn der Dateiname nicht existiert -> Fehlermeldung ausgeben
      if (!SD.remove(DateinameAbfragen)) 
      {
        Serial.println("Datei " + DateinameAbfragen + " existiert nicht!");
      }
      else Serial.println("Datei " + DateinameAbfragen + " entfernt!");

      // Variable leeren
      DateinameAbfragen = "";
    }

    // Datei erzeugen und Daten eingeben
    if (Eingabe == 'e') 
    {
      Serial.print("Name der Datei: ");

      // solange der String DateinameAbfragen leer ist
      // -> solange lesen, bis return \n eingegeben wurde
      while (DateinameAbfragen == "") DateinameAbfragen = Serial.readStringUntil('\n');

      // open erwartet ein char-Array -> Array Dateiname erstellen
      // char Dateiname[DateinameAbfragen.length()];
      DateinameAbfragen.toCharArray(Dateiname, DateinameAbfragen.length() + 1);
      Serial.println(Dateiname);

      /*
        O_CREAT -> Datei erstellen, wenn sie nicht existiert
        O_WRITE -> in die Date schreiben
        O_AT_END -> Startposition zum Schreiben an das Ende der Datei setzen
      */
      Datei.open(Dateiname, O_CREAT | O_WRITE | O_AT_END);

      // Daten in Datei schreiben
      Serial.println("Daten eingeben und Eingabe mit # beenden:");
      while (DatenSchreiben != "#") 
      {
        while (Serial.available() > 0) 
        {
          DatenSchreiben = Serial.readStringUntil('\n');
          Serial.println(DatenSchreiben);

          // Datensatz in Datei schreiben
          if (DatenSchreiben != "#") Datei.println(DatenSchreiben);
        }
      }

      // Datei schließen
      Datei.close();
      Serial.println("\nDatei " + DateinameAbfragen + " erfolgreich geschrieben!");
      
      DatenSchreiben = "";
      DateinameAbfragen = "";
    }

    // Datei öffnen und Daten anzeigen
    if (Eingabe == 'a') 
    {
      Serial.print("Name der Datei: ");

      // solange der String DateinameAbfragen leer ist
      // -> solange lesen, bis return \n eingegeben wurde
      while (DateinameAbfragen == "") DateinameAbfragen = Serial.readStringUntil('\n');

      // open erwartet ein char-Array -> Array Dateiname erstellen
      DateinameAbfragen.toCharArray(Dateiname, DateinameAbfragen.length() + 1);
      Serial.println(Dateiname);

      // Datei öffnen, O_RDONLY nur Lesen
      if (Datei.open(Dateiname, O_RDONLY)) 
      {
        while (Datei.available()) 
        {
          // ... werden sie gelesen und im Seriellen Monitor ausgegeben
          Serial.write(Datei.read());
        }
      } 
      else Serial.println("Datei " + DateinameAbfragen + " nicht gefunden!");

      // Datei schließen
      Datei.close();

      DateinameAbfragen = "";
    }
  }
}

Letzte Aktualisierung: 31. Mrz 2024 @ 11:28