Daten speichern mit dem Datenlogger-Shield

FunduinoZuletzt aktualisiert am

Messwerte mit Zeitstempel auf einer SD-Karte aufzeichnen

Das Datenlogger-Shield vereint zwei Bauteile auf einer Platine: eine Echtzeituhr (RTC), die Datum und Uhrzeit dank Knopfzelle auch ohne Stromversorgung behält, und ein SD-Karten-Modul, das Dateien schreibt und liest. Damit zeichnest du Messwerte mit Zeitstempel auf und wertest sie später in einer Tabellenkalkulation aus.

In dieser Anleitung speicherst du zuerst einfache Zahlen auf der Karte, liest die Datei wieder aus und baust die Schaltung anschließend zu einem Temperatur- und Luftfeuchtigkeits-Logger im CSV-Format aus.

Datenlogger-Shield einzeln und auf einen Arduino aufgesteckt
Das Datenlogger-Shield wird einfach auf den Arduino gesteckt

Was das Datenlogger-Shield kann

Auf dem Datenlogger-Shield sitzen zwei Bauteile: ein RTC-Modul (Real Time Clock), das Datum und Uhrzeit kennt, und ein SD-Karten-Modul, das eine SD-Karte beschreibt und liest. Einmal gestellt, behält die Uhr dank einer Batterie ihre Zeit auch nach dem Ausschalten.

Damit kannst du:

  • Daten im CSV-Format auf einer SD-Karte speichern, zum Beispiel gemessene Temperaturen
  • diese Daten aus­lesen und in einer Textverarbeitung oder Tabellenkalkulation weiterverarbeiten
  • das aktuelle Datum und die aktuelle Zeit lesen und mitspeichern

Eine CSV-Datei (Comma Separated Values, also durch Kommas getrennte Werte) dient dem Austausch von Daten über die Grenzen von Betriebssystemen und Programmen hinweg. Die Spalten trennt ein Komma, eine neue Zeile entsteht durch einen Zeilenumbruch.

Aufbau

Das Datenlogger-Shield wird einfach auf den Arduino gesteckt – mehr ist für den ersten Versuch nicht zu tun. Die SD-Karte spricht der Arduino über Pin 10 an.

Datenlogger-Shield einzeln und auf einen Arduino aufgesteckt
Das Datenlogger-Shield wird einfach auf den Arduino gesteckt

Bibliothek installieren

Bevor du mit dem Programmieren beginnst, brauchst du eine Bibliothek. Klicke auf das Symbol der Bibliotheksverwaltung oder gehe im Menü auf Sketch › Bibliothek einbinden › Bibliotheken verwalten und suche nach SdFat. Ein Klick auf „Installieren“ genügt.

Bibliotheksverwaltung der Arduino IDE mit der Bibliothek SdFat
Die Bibliothek SdFat in der Bibliotheksverwaltung

Daten speichern und wieder lesen

Im ersten Schritt legst du eine Datei „Zahlen.txt“ an, füllst sie mit den Zahlen von 1 bis 10 und liest sie anschließend wieder aus – zu sehen im seriellen Monitor.

Alles passiert hier im setup(), der loop() bleibt leer: Das Programm läuft nur ein einziges Mal durch.

Serieller Monitor mit dem Inhalt der Datei Zahlen.txt
Die geschriebene Datei, zurückgelesen im seriellen Monitor
Datei schreiben und wieder auslesen
// Bibliothek einbinden
#include "SdFat.h"

// Name der SD-Karte
SdFat SD;

// Datenpin der SD-Karte
int DatenPin = 10;

void setup()
{
  // Bezeichner für die Datei
  File Datei;

  // SD-Karte mit Angabe des Datenpins starten
  SD.begin(DatenPin);

  // Eine vorhandene Datei wird zuerst geloescht, damit der Versuch von vorn beginnt.
  SD.remove("Zahlen.txt");

  // seriellen Monitor starten
  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) { ; }
  delay(500);

  Serial.println("Zahlen in die Datei Zahlen.txt schreiben");

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

  // Daten in die Datei schreiben
  Datei.println("1 2 3 4 5 6 7 8 9 10");

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

  Serial.println("Datei Zahlen.txt lesen");

  // O_RDONLY = nur lesen
  Datei.open("Zahlen.txt", O_RDONLY);

  // Solange sich Daten in der Datei befinden ...
  while (Datei.available())
  {
    // ... werden sie gelesen und im seriellen Monitor ausgegeben.
    Serial.write(Datei.read());
  }

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

void loop()
{
  // bleibt leer, das Programm läuft nur einmal
}

Temperatur mit Datum und Uhrzeit aufzeichnen

Jetzt liefert ein Sensor DHT22 die Werte für Temperatur und Luftfeuchtigkeit. Sie landen in der Datei Messung.csv. Damit eine Tabellenkalkulation sie lesen kann, folgt auf jeden Wert ein Komma.

Der Sensor hängt im Sketch an Pin 8. Zusätzlich zu SdFat brauchst du zwei weitere Bibliotheken:

  • DHT sensor library von Adafruit (installiert die Adafruit Unified Sensor Library gleich mit)
  • RTClib für die Echtzeituhr

Das Programm wartet auf eine Eingabe im seriellen Monitor: Mit „l“ liest es die Messwerte und schreibt sie in die Datei, mit „e“ löscht es die Datei wieder.

Vor der ersten Verwendung musst du die Uhr einmal stellen. Die Zeile rtc.adjust(DateTime(2023, 2, 17, 15, 30, 30)) steht im Sketch zunächst im Kommentar. Nimm sie einmal heraus, trage Datum und Uhrzeit ein und lade den Sketch hoch. Danach kommentierst du sie wieder aus – sonst stellt sich die Uhr bei jedem Neustart auf denselben Zeitpunkt zurück. Anschließend läuft die Zeit dank der Batterie weiter, auch ohne Strom am Board.

Arduino mit Datenlogger-Shield und angeschlossenem DHT22-Sensor
Aufbau mit dem Temperatursensor DHT22
Bibliotheksverwaltung mit der DHT sensor library
Die DHT sensor library von Adafruit
Bibliotheksverwaltung mit der Bibliothek RTClib
Die Bibliothek RTClib
Serieller Monitor mit Datum, Uhrzeit, Temperatur und Luftfeuchtigkeit
Messwerte mit Datum und Uhrzeit im seriellen Monitor
Tabellenkalkulation mit den Spalten Datum, Zeit, Temperatur und Luftfeuchtigkeit
Dieselben Daten, geöffnet in einer Tabellenkalkulation
1 / 5
Temperatur mit Datum und Uhrzeit aufzeichnen
// benötigte Bibliotheken
#include "SdFat.h"
#include "RTClib.h"
#include "DHT.h"

// Bezeichner der SD-Karte
SdFat SD;

// Datenpin der SD-Karte
int DatenPin = 10;

// Pin des DHT-Sensors
int SENSOR_DHT = 8;

// Name des RTC-Moduls (rtc)
RTC_DS3231 rtc;

// Sensortyp festlegen: DHT22 oder DHT11
#define SensorTyp DHT22

// Dem Sensor einen Namen zuweisen
DHT dht(SENSOR_DHT, SensorTyp);

// Variablen für Temperatur und Luftfeuchtigkeit
float Temperatur;
float Luftfeuchtigkeit;

// Bezeichner für die Datei
File Datei;

void setup()
{
  /*
    Wenn Datum und Zeit nicht korrekt sind: Datum und Zeit setzen.
    Reihenfolge: Jahr, Monat, Tag, Stunde, Minute, Sekunde
    Beispiel: 17. Februar 2023, 15 Uhr 30 Minuten 30 Sekunden

    rtc.adjust(DateTime(2023, 2, 17, 15, 30, 30));
  */

  // RTC-Modul starten
  rtc.begin();

  // Sensor DHT starten
  dht.begin();

  Serial.begin(9600);

  // auf serielle Verbindung warten
  while (!Serial) { ; }

  // SD-Karte mit Angabe des Datenpins starten
  SD.begin(DatenPin);

  // Menue anzeigen
  Serial.println("------------------------------");
  Serial.println("l = Daten lesen und in Datei schreiben");
  Serial.println("e = Datei entfernen");
  Serial.println("------------------------------");
}

void loop()
{
  // auf serielle Eingabe warten
  while (Serial.available() > 0)
  {
    // Eingabe im seriellen Monitor lesen
    char Zeichen = Serial.read();

    // Temperatur und Luftfeuchtigkeit lesen und speichern
    if (Zeichen == 'l')
    {
      // aktuelle Zeit ermitteln
      DateTime aktuell = rtc.now();

      // Datumsformat festlegen
      char Datum[] = "DD.MM.YYYY";
      // Format der Zeitangabe festlegen
      char Zeit[] = "hh:mm:ss";

      // Daten lesen
      Temperatur = dht.readTemperature();
      Luftfeuchtigkeit = dht.readHumidity();

      // Ausgabe im seriellen Monitor
      Serial.println("------------------------------");
      Serial.print("Datum: ");
      Serial.println(aktuell.toString(Datum));
      Serial.print("Zeit: ");
      Serial.print(aktuell.toString(Zeit));
      Serial.println(" Uhr");
      Serial.print("Temperatur: ");
      Serial.println(Temperatur);
      Serial.print("Luftfeuchtigkeit in %: ");
      Serial.println(Luftfeuchtigkeit);
      Serial.println("------------------------------");

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

      /*
        Datum und Zeit in die Datei schreiben.
        Jedem Wert muss ein Komma folgen, nach dem letzten Wert ein Zeilenvorschub.
      */
      Datei.print(aktuell.toString(Datum));
      Datei.print(",");
      Datei.print(aktuell.toString(Zeit));
      Datei.print(",");
      Datei.print(Temperatur);
      Datei.print(",");
      Datei.println(Luftfeuchtigkeit);

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

      Serial.println();
      Serial.println("Zeige Messung.csv");

      // Datei Messung.csv oeffnen
      Datei.open("Messung.csv", O_RDONLY);

      // Solange sich Daten in der Datei befinden ...
      while (Datei.available())
      {
        // ... werden sie gelesen und im seriellen Monitor ausgegeben.
        Serial.write(Datei.read());
      }

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

    // Datei loeschen
    if (Zeichen == 'e')
    {
      // Wenn die Datei Messung.csv existiert, wird sie entfernt.
      if (SD.exists("Messung.csv"))
      {
        SD.remove("Messung.csv");
        Serial.println("Datei Messung.csv entfernt!");
      }
      else
      {
        Serial.println("Datei Messung.csv existiert nicht!");
      }
    }
  }
}
Anleitung bewerten

Kommentare

Frage stellen oder Erfahrung teilen

Schreib uns, wenn etwas nicht funktioniert. Nenne dabei dein Board und die Fehlermeldung.

Wir prüfen jeden Kommentar vor der Veröffentlichung. Deine E-Mail-Adresse bleibt bei uns.