GPS-Daten (NEO-6M Modul) auf SD-Karte speichern

Hallo,

ich benutze ein GPS-Modul NEO-6M, einen Arduino Mega 2560 und ein Ethernet Shield 2 (W5500).

Ich möchte die Daten des GPS-Moduls kontinuierlich auf der SD-Karte, die im SD-Karten-Slot des Ethernet Shields steckt, abspeichern. Dazu habe ich das GPS-Modul über Hardware-Serial1 verbunden.
Die Daten werden auch gesendet, das habe ich parallel zum Abspeichern überprüft. Es werden nur keine Daten auf der SD-Karte abgespeichert.

Kann mir jemand erklären, warum das so ist und was ich falsch mache?
Vielen Dank schonmal.

//Bibliotheken für die Sensoren
//#include <Ethernet.h>
#include <Wire.h>
#include <SenseBox.h>

//---Bibliothek für GPS-Modul---
#include <TinyGPS++.h>
TinyGPSPlus gps; // create gps object
//---------------------------
//---Bibliothek und Definitionen für SD-Karte---
#include <SPI.h>
#include "SdFat.h"
SdFat SD;

#define SD_CS_PIN SS
File myFile;
char filename[] = "00000000.TXT";

//---------------------------
void getFilename(char *filename) {
  filename[0] = gps.date.day()/10 + '0'; //To get 1st digit from day()
  filename[1] = gps.date.day()%10 + '0'; //To get 2nd digit from day()
  filename[2] = gps.date.month()/10 + '0'; //To get 1st digit from month()
  filename[3] = gps.date.month()%10 + '0'; //To get 2nd digit from month()
  filename[4] = '2';
  filename[5] = '0';
  filename[6] = (gps.date.year()/10)%10 + '0'; //To get 3rd digit from year()
  filename[7] = gps.date.year()%10 + '0'; //To get 4th digit from year()
  //filename[8] = '.';
  //filename[9] = 'T';
  //filename[10] = 'X';
  //filename[11] = 'T';
  return;
}


void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
//---------------------------
//---HardwareSerial1 wird gestartet---
  Serial1.begin(9600); 
//---Die SD-Karte wird gestartet und Spalten werden gesetzt---
  getFilename(filename);
  Serial.println(filename);
  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  pinMode(53,OUTPUT);
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);


  myFile = SD.open(filename, FILE_WRITE);
  if (myFile) {
    Serial.print("Writing to GPS.txt...");
    myFile.println("Date \t Time (UTC) \t Latitude \t Longitude");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening GPS.txt");
  }
  
  
  
}

void loop() {
//---GPS-Modul initiieren---
   
    while(Serial1.available()){ 
      //if(gps.encode(Serial1.read())){
      gps.encode(Serial1.read());
      if (gps.date.isUpdated()){
    //if(myFile){
        myFile.print(gps.date.day());
        myFile.print(".");
        myFile.print(gps.date.month());
        myFile.print(".");
        myFile.print(gps.date.year());
        myFile.print("\t");
      } 
      if (gps.date.isUpdated()){ 
        myFile.print(gps.time.hour());
        myFile.print(":");
        myFile.print(gps.time.minute());
        myFile.print(":");
        myFile.print(gps.time.second());    
        myFile.print("\t");
      }
      if (gps.location.isUpdated()){
    //if(myFile){
        myFile.print(gps.location.lat(), 6);
        myFile.print("\t");
        myFile.print(gps.location.lng(), 6);
        myFile.print("\t");
      }}//}

}

Hallo,
gibt es eine Fehlermeldung ?
Hast du den Sketch mal mit kurzem Text zum Speichern getestet ?

larull:
Es werden nur keine Daten auf der SD-Karte abgespeichert.
Kann mir jemand erklären, warum das so ist und was ich falsch mache?

#define SD_CS_PIN SS

Im Example "Datalogger" der SDFat-Lib heisst es:
const uint8_t chipSelect = SS; und dürfte Dir, wenn Du die PIN-Nummer nicht vergibst einen Fehler auswerfen.

Das ist der Nachteil, wenn man Preprozessorderiktiven benutzt.
Nach https://www.arduino.cc/en/uploads/Main/arduino-Ethernet-Shield2-V2-sch.pdf ist in C-7 Pin 4 Dein SS Kandidat.

Hallo,

also ich bekomme keine Fehlermeldung.
Ich habe auch einen kurzen Text getestet: Der wird auch nicht abgespeichert.

Wie vergebe ich die Pin-Nummer auf Pin 4?

also ich bekomme keine Fehlermeldung.

Das soll dir jemand glauben??
Guckst du hier:

if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}

larull:
also ich bekomme keine Fehlermeldung.

Ja. Deinen Code nicht aufgeräumt und mich in die Irre geführt.
Fest verdrahtet if (!SD.begin (4))
Was gibt denn der Serielle Monitor aus?
Was passiert, wenn Du im Setup diese Zeile auskommentierst?

 getFilename (filename);

Auf dem seriellen Monitor erscheint:
"Initializing SD card... initialization done."
"Writing to GPS.txt... done."

Und dann kommt nichts mehr.

Wenn ich die Zeile getFilename (filename);
auskommentiere wird anstatt in eine Datei "00002000.csv" in eine Datei "0000000.csv" gesepeichert.
Aber wieder nur das, was in der Setup-Funktion steht.

larull:
Wenn ich die Zeile getFilename (filename);
auskommentiere wird anstatt in eine Datei "00002000.csv" in eine Datei "0000000.csv" gesepeichert.
Aber wieder nur das, was in der Setup-Funktion steht.

Moment!
Ich bin bisher davon ausgegangen, das überhaupt nicht gespeichert wird.
Das im Setup die Anlage der Datei und der Inhalt funktioniert, hast Du bisher verschwiegen.
Dann wäre es ja ein Leichtes um erstmal die Funktionalität zu testen, den Code nicht in eine Datei sondern auf dem SerMon schreiben zu lassen.
Ersetze loop durch:

void loop()
{
  while (Serial1.available())
  {
    Serial.println ("GPS-Modul Start");
    gps.encode (Serial1.read());

    if (gps.date.isUpdated())
    {
      Serial.println ("Neue GPS-Daten");
      Serial.print (gps.date.day());
      Serial.print (".");
      Serial.print (gps.date.month());
      Serial.print (".");
      Serial.print (gps.date.year());
      Serial.print ("\t");
      Serial.print (gps.time.hour());
      Serial.print (":");
      Serial.print (gps.time.minute());
      Serial.print (":");
      Serial.print (gps.time.second());
      Serial.println ();
    }
  }
delay(1000);
}

und berichte.

Entschuldige bitte, das habe ich vergessen zu erwähnen.
Wenn ich die loop dadurch ersetze werden die Daten auf dem seriellen Monitor angezeigt.

Und wenn ich den Teil zu dem restlichen Code in die loop einsetze auch.

larull:
Wenn ich die loop dadurch ersetze werden die Daten auf dem seriellen Monitor angezeigt.

Naja, und nun machst Du das mit der Datei genauso wie mit dem seriellen Monitor:

(ungetestet, sollte aber gehen)

void loop()
{
  while (Serial1.available())
  {
    Serial.println ("GPS-Modul Start");
    gps.encode (Serial1.read());

    if (gps.date.isUpdated())
    {
      Serial.println ("Neue GPS-Daten");
      Serial.print (gps.date.day());
      Serial.print (".");
      Serial.print (gps.date.month());
      Serial.print (".");
      Serial.print (gps.date.year());
      Serial.print ("\t");
      Serial.print (gps.time.hour());
      Serial.print (":");
      Serial.print (gps.time.minute());
      Serial.print (":");
      Serial.print (gps.time.second());
      Serial.println ();

      if (myFile = SD.open (filename, FILE_WRITE))
      {
        myFile.print (gps.date.day());
        myFile.print (".");
        myFile.print (gps.date.month());
        myFile.print (".");
        myFile.print (gps.date.year());
        myFile.print ("\t");
        myFile.print (gps.time.hour());
        myFile.print (":");
        myFile.print (gps.time.minute());
        myFile.print (":");
        myFile.print (gps.time.second());
        myFile.print ("\t");
        myFile.print (gps.location.lat(), 6);
        myFile.print ("\t");
        myFile.print (gps.location.lng(), 6);
        myFile.println ("\t");
        SD.close();
      }
      else
      {
        Serial.print ("Kann Datei: "));
        Serial.print (filename);
        Serial.println (" nicht öffnen");
      }
    }
    delay (1000);
  }

Nur falls es nicht geht:
Evtl. kann/muss man SD.close() durch myFile.close() ersetzen oder ergänzen.

Und wie oft willst du
"GPS-Modul Start"
sehen???

Immer noch ungetestet :wink:

geht das denn im setup, die datei anhand der gps-daten zu erzeugen, obwohl noch nicht ein byte gelesen wurde?
oder hab ich nen denkfehler?

harryberlin:
geht das denn im setup, die datei anhand der gps-daten zu erzeugen, obwohl noch nicht ein byte gelesen wurde?
oder hab ich nen denkfehler?

Aus #6:

Auf dem seriellen Monitor erscheint:
"Initializing SD card... initialization done."
"Writing to GPS.txt... done."

Ich weiss sonst nicht, wie ich es beschreiben kann.

Und ja, es würde gehen - wenn das Neo initialisiert und danach gewartet wird bis Daten - natürlich mit Abbruchtimeout

Hallo,

Ich habe den ungetesteten loop-Code eingefügt und SD.close() durch myFile.close() ersetzt. Und noch zwei Klammern abgeändert.
Es funktioniert jetzt! Die Daten werden wie gewünscht abgespeichert.

Dankeschön für die Hilfe.

larull:
Es funktioniert jetzt! Die Daten werden wie gewünscht abgespeichert.

Na das ist ja mal ne Erfolgsmeldung!
Die Nachwelt ist nicht traurig, wenn Sie liest wie Du Deinen Code jetzt aufgebaut hast um sich daran ein Beispiel zu nehmen.
Und wenn Du Deinen Code hier gepostet hast, dann gehe bitte in das erste Post von Dir und schreib ein [gelöst] oder ähnliches in die Betreffzeile.
Danke.

larull:
Hallo,

Ich habe den ungetesteten loop-Code eingefügt und SD.close() durch myFile.close() ersetzt. Und noch zwei Klammern abgeändert.
Es funktioniert jetzt! Die Daten werden wie gewünscht abgespeichert.

Dankeschön für die Hilfe.

Wir warten noch auf deinen angepassten Sketch.