Umweltmessstation ohne Internetanbindung

Offline Upload mit SD Karte

An Orten wo gerade kein Internet oder LoRaWAN verfügbar ist, bietet es sich an eine SD Karte zu verwenden, um Messwerte zu speichern. Die Messwerte können später ganz einfach von der SD Karte auf die openSenseMap übertragen werden! Das RTC (Real-Time-Clock) wird verwendet, um die Messwerten mit eine korrekten Zeitstempel zu versehen. Das RTC Modul bestitz eine Uhr, die nachdem diese einmal eingestellt wurden, mithilfe einer Batterie bis zu 7 Jahre läuft und ausgelesen werden kann.

Aufbau

Stecke die microSD Karte in das SD-Bee. Achte hier darauf die microSD Karte korrekt zu installieren, eine Illustration auf der Rückseite des SD-Bee zeigt dir wie die microSD Karte eingesteckt werden muss. Stecke daraufhin die SD-Bee an den XBEE2-Steckplatz. Wichtig ist, dass du den Steckplatz XBEE2 verwendest, da das Bee ansonsten nicht ordnungsgemäß funktioniert. Das RTC Modul verbindest du mit einem der JST-JST-Kabel an einen der fünf I2C-Ports. Nun musst du noch den Umweltsensor mit dem JST-JST-Kabel anschließen an einen weiteren I2C-Port anschließen und der Aufbau ist fertig! Du kannst den Aufbau natürlich auch um weitere Sensoren erweitern.

Registrierung auf der openSenseMap

Bevor du mit der Programmierung beginnst solltest du dein Messgerät auf der openSenseMap registrieren. Wähle die Sensoren aus, die du an deine senseBox angeschlossen hast. Nach der Registrierung erhälst du für jeden Sensor bzw. für jedes Phänomen eine SensorID, die wichtig ist, um die Messwerte richtig zuordnen zu können.

Programmierung: Messwerte auf SD-Karte speichern

Jede Minute soll ein Messwert auf der SD-Karte gespeichert werden, um diese nachher gebbündelt auf der openSenseMap hochladen zu können.

Schritt 1: Librarys importieren, Variablen erstellen

Zuerst müssen die benötigten Librarys aus dem Board-Support-Package eingeladen werden.

#include <SPI.h>
#include <SD.h>
#include "SenseBoxMCU.h"
#include <RV8523.h>

Daraufhin werden für die Sensor ID’s der Sensoren konstanten erstellt. Die Sensor ID’s werden dir nach Fertigstellung der Registrierung angezeigt und können alternativ über das Dashboard eingesehen werden Dashboard->deine SenseBox -> Editieren -> Sensoren.

// ID's
const char *TEMP_ID = "SENSORID";
const char *HUMI_ID= "SENSORID";

Zusätzlich werden wird noch ein Objekt myFile, welches die Datei die auf der SD-Karte gespeichert werden soll, repräsentiert.
Als letztes muss noch ein Objekt für den Sensor, als auch für das RTC Modul definiert werden.

File myFile;
HDC1080 hdc;
RV8523 rtc;

Als letztes wird noch eine Variable erstellt, in der die Uhrzeit später gespeichert wird. Der Typ char gibt an, dass es sich um eine Zeichenkette handelt und die Zahl innerhalb der eckigen Klammern definiert die Länge.

char timestamp[64];

Schritt 2: Uhrzeit einstellen

Bevor die Uhrzeit des RTC Moduls ausgelesen werden kann, musst du diese vorher mithilfe eines anderen Sketches setzen. Schaue hier wie das funktioniert. Beachte, dass die Uhrzeit nur einmal eingestellt werden muss. Solange die Batterie korrekt eingelegt ist läuft die Uhr weiter und kann ausgelesen werden

Schritt 3: Datei auf der SD Karte erstellen und Sensoren initialisieren

In der setup() Funktion wird nun die SD-Karte initalisiert. Daraufhin wird die SD Karte geöffnet und die Datei mit dem Namen "data.csv" wird erstellt. Anschließend wird die Datei wieder geschlossen. Zusätzlich muss nun auch das RTC Modul initalisiert werden. Als letztes werden hier noch die angeschlossenen Sensoren initialisiert.

void setup() {
  SD.begin(28);
  dataFiledata = SD.open("data.txt", FILE_WRITE);
  dataFiledata.close();

  rtc.begin();
  rtc.start();
  rtc.batterySwitchOver(1);

  HDC.begin();

}

Schritt 4: Im Intervall Messwerte auf der SD-Karte speichern

In der loop() Funktion sollen nun alle 60 Sekunden Messwerte auf der SD Karte speichern. Dafür wird nichtd ie delay() Funktion aus der Standard Arduino Library benutz, sondern definieren unser eigenes Messinterval. Die delay() Funktion sorgt dafür, dass der Programmcode komplett unterbrochen wird, durch ein eigenes definiertes Messintervall lässt sich dies besser lösen. Dafür werden 3 zusätzliche Variablen am Anfang unseres Programms, noch vor dem setup() und der loop() Funktion, definiert. Die Variablen speichern die Zeit seit dem Start des Intervals, die Länge des Intervalls und die aktuelle Laufzeit des Programmes.

const long interval = 60000; // 60.000 Millisekunden = 60 Sekunden
long time_start = 0;
long time_actual = 0;

Die Arduino Funktion millis() gibt die Anzahl an Millisekunden zurück seitdem die senseBox gestartet ist. Mithilfe dieser Funktion kann eine if-Abfrage erstellt werden, welche gültig wird, wenn 60 Sekunden vergangen sind.

void loop() {
  time_start = millis();
    if (time_start > time_actual + interval) {
      // 60 Sekunden sind vergangen
      time_actual = millis();

    }

}

Nun da das Messinterval definiert ist, müssen noch innerhalb des Intervals die Messwerte auf der SD Karte speichern. Damit die Messwerte später Problemlos auf der openSenseMap hochgeladen werden können, müssen die Messwerte in einem bestimmten Format gespeichert werden. Dieses sieht wiefolgt aus.

sensorID, Messwert, *Zeitstempel, *Längengrad, *Breitengrad, *Höhe

Parameter mit einem * davor deuten daraufhin, dass diese optional sind und nicht zwingend zum Upload nötig sind. Da in diesem Beispiel kein GPS Sensor installiert ist können die Werte für Längengrad, Breitengrad und Höhe ignorieren werden. Der Zeitstempel in korrekten Format wird aus der Uhrzeit des RTC-Moduls erstellt. Dazu werden eine Variablen erstellt, in der die einzelnen Bestandteile Uhrzeit gespeichert wird. Im Anschluss rufen wird die Funktion rtc.get() aufgerufen und übergeben zusätzlich die eben erstellten Variablen. Die Funktion speichert die nötigen Informationen in die Variablen die übergeben werden.

    uint8_t sec, min, hour, day, month;
    uint16_t year;
    // Uhrzeit wird in die verschiedenen Variablen gespeichert
    rtc.get(&sec, &min, &hour, &day, &month, &year);

Nun müssen die Variablen noch in ein ordentliches Format übersetzt werden. Mit der Funktion sprintf können wir Zeichenketten nach einem vorgegebenen Muster erstellen.

    sprintf(timestamp, "20%02d-%02d-%02dT%02d:%02d:%02dZ",
            year,
            month,
            day,
            hour,
            min,
            sec);

Mithilfe dieser Funktion wird in der Variable timestamp, der String 20%02d-%02d-%02dT%02d:%02d:%02dZ eingefügt. Jedes %02d in diesem String wird mit dem Wert nach den Kommas ersetzet. In diesem Beispiel wird aus 20%02d-%02d-%02dT%02d:%02d:%02dZ nach der Funktion 2021-01-7T12:56:00Z. Mit diesem Vorwissen kann nun das Programm so veräädert werden, dass die Messwerte korrekt auf der SD Karte gespeichert werden.

void loop() {
  time_start = millis();
  if (time_start > time_actual + interval) {
    time_actual = millis();
    uint8_t sec, min, hour, day, month;
    uint16_t year;
    // Uhrzeit wird in die verschiedenen Variablen gespeichert
    rtc.get(&sec, &min, &hour, &day, &month, &year);
    sprintf(timestamp, "20%02d-%02d-%02dT%02d:%02d:%02dZ",
            year,
            month,
            day,
            hour,
            min,
            sec);
    // Datei vorher öffnen
    myFile = SD.open("data.txt", FILE_WRITE);
    myFile.print(TEMP_ID);
    myFile.print(",");
    myFile.print(hdc.getTemperature());
    myFile.print(",");
    myFIle.println(timestamp)
    // zweiter Messwert
    myFile.print(HUMI_ID);
    myFile.print(",");
    myFile.print(hdc.getHumidity());
    myFile.print(",");
    myFIle.println(timestamp)
    // Datei nachher schliessen
    myFile.close();
  }

}

Beim Speichern der Messwerte muss darauf geachtet werden, dass die Datei auf der SD Karte Anfangs per myFile = SD.open() geöffnet wird und anschließend per myFile.close() wieder geschlossen wird!

Schritt 5: Hochladen der Daten auf der openSenseMap

Nachdem du deine senseBox eine Weile hast Messwerte sammeln lassen, können die Messwerte auf die openSenseMap hochladen werden! Hierfür entferne das SD-Bee von seinem Steckplatz und nehme die microSD Karte heraus. Anschließend steckst du die microSD Karte in den microSD Adapter, welchen du an deinen Computer anschließen kannst. Nicht alle Computer haben einen Anschluss für den Adapter, solltest du keinen solchen Anschluss gibt es im Internet zahlreiche Möglichkeiten unter anderem USB Kartenlesegeräte.

Hast du den SD Adapter mit deinem Computer verbunden werden dir nun die Dateien auf der SD Karte angezeigt werden. Unter den Dateien befindet sich auch die Datei data.csv befinden. Kopiere diese auf deinen PC.

Gehe auf die openSenseMap und logge dich in dein Benutzerkonto ein. Navigiere über das Dashboard (Erreichbar über das Benutzer Icon oben rechts) zu deiner senseBox und wähle Daten-Upload aus. Klicke dort auf Wähle eine Datei und wähle die soeben kopierte .csv Datei aus. In dem großen Kasten wird eine Vorschau der zu hochladenenen Messwerte angezeigt. Über den Upload Knopf kannst du nun die Messwerte hochladen!

/images/projects/SD/osmupload.png - Logo

Extras

Mit der erstellten csv Datei kannst du zusätzlich auch weitere Berechnungen oder ähnliches durchführen. So lassen sich z.B. mit Programmen wie Excel leicht Graphen und Visualisierungen zu deiner Messung erstellen, probiere es mal aus! Wie das zum Beispiel mit ArcGIS Online funktionieren kann zeigt dir Verena hier

Den vollständigen Sketch findest du hier.