GPS Modul in Datalogger integrieren

Hallo Forengemeinde,

mein Datalogger mit einem Beschleunigungssensor (ADXL335) und einem Temperatursensor (TMP36) funktioniert mit meinem Arduino Uno wunderbar. Von Sparkfun habe ich ein MicroSD-shield wodurch ich die Daten auch entsprechend speichern kann.

Nun ist mein GPS-Modul von Adafruit gekommen (Adafruit Ultimate GPS) und leider reichen meine Anfängerkenntnisse nicht, das GPS in meinen bisherigen Code zu integrieren.

Mir reicht die Longitude und latitude angabe und lasse mir entsprechend diese in meinem code ausgeben. dies funktioniert leider nicht und ich bekomme lediglich Nullen als Position ausgegeben, wenn ich jedoch das “Echo”-Beispiel nutze, dann bekomme ich jedoch meine Position angezeigt. Heißt der Sensor bekommt ein Signal, daran sollte es nicht liegen, daher wäre die Fehlerquelle noch der Code.

wäre super, wenn mir jemand hierbei helfen könnte. danke :slight_smile:

Hier zunächst meiner (das delay werde ich noch ändern, da wurde ich bereits aufmerksam gemacht, dass dies nicht das beste Mittel ist):

#include <Adafruit_GPS.h>
#if ARDUINO >= 100
 #include <SoftwareSerial.h>
  // Older Arduino IDE requires NewSoftSerial, download from:
  // http://arduiniana.org/libraries/newsoftserial/
// #include <NewSoftSerial.h>
 // DO NOT install NewSoftSerial if using Arduino 1.0 or later!
#endif

#include <SD.h>

const int chipSelect = 8;
int pinX = A0;     // X-Achse
int pinY = A1;     // Y-Achse
int pinZ = A2;     // Z-Achse
int pinT = A3; //Temperatursensor
int x;

#if ARDUINO >= 100
  SoftwareSerial mySerial(3, 2);
#endif
Adafruit_GPS GPS(&mySerial);

#define GPSECHO  true

void setup()  
{    
  // connect at 115200 so we can read the GPS fast enuf and
  // also spit it out
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  //Serial.println("Adafruit GPS library basic test!");

  // 9600 NMEA is the default baud rate for MTK - some use 4800
  GPS.begin(9600);
  
  // You can adjust which sentences to have the module emit, below
  
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data for high update rates!
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // uncomment this line to turn on all the available data - for 9600 baud you'll want 1 Hz rate
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_ALLDATA);
  
  // Set the update rate
  // 1 Hz update rate
  //GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  // 5 Hz update rate- for 9600 baud you'll have to set the output to RMC or RMCGGA only (see above)
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ);
  // 10 Hz update rate - for 9600 baud you'll have to set the output to RMC only (see above)
  //GPS.sendCommand(PMTK_SET_NMEA_UPDATE_10HZ);

  // Request updates on antenna status, comment out to keep quiet
  GPS.sendCommand(PGCMD_ANTENNA);

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  //useInterrupt(true);
  
  delay(1000);
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()                     // run over and over again
{
  char c = GPS.read();
    //if you want to debug, this is a good time to do it!
  if (GPSECHO)
  if (c) Serial.print(c);
  
  int maxX = 0;
  int maxY = 0;
  int maxZ = 0;
  int minX = 510;
  int minY = 510;
  int minZ = 610;
  int maxT = 0;
  
  for(x=0; x<=10; x++)
  {
    delay(200);
    if (analogRead(pinX) > maxX, analogRead(pinY) > maxY, analogRead(pinZ) > maxZ)
    {
      maxX = analogRead(pinX);
      maxY = analogRead(pinY);
      maxZ = analogRead(pinZ);
    }
     if (analogRead(pinX) < minX, analogRead(pinY) < minY, analogRead(pinZ) < minZ)
         {
      minX = analogRead(pinX);
      minY = analogRead(pinY);
      minZ = analogRead(pinZ);
    }
     
  }

char Werte[200];

  sprintf(Werte, "%d,%d,%d,%d,%d,%d,%d", maxX,maxY,maxZ,minX,minY,minZ,analogRead(pinT)); 

  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(Werte);
    dataFile.close();
    // print to the serial port too:
    Serial.print("Location: ");
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(", "); 
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
    Serial.println(Werte);
  }   
  // do nothing! all reading and printing is done in the interrupt
}

nun noch der Beispiel-Code, welcher funktioniert

#include <Adafruit_GPS.h>
#if ARDUINO >= 100
 #include <SoftwareSerial.h>
#else
  // Older Arduino IDE requires NewSoftSerial, download from:
  // http://arduiniana.org/libraries/newsoftserial/
// #include <NewSoftSerial.h>
 // DO NOT install NewSoftSerial if using Arduino 1.0 or later!
#endif

// Connect the GPS Power pin to 5V
// Connect the GPS Ground pin to ground
// If using software serial (sketch example default):
//   Connect the GPS TX (transmit) pin to Digital 3
//   Connect the GPS RX (receive) pin to Digital 2
// If using hardware serial (e.g. Arduino Mega):
//   Connect the GPS TX (transmit) pin to Arduino RX1, RX2 or RX3
//   Connect the GPS RX (receive) pin to matching TX1, TX2 or TX3

// If using software serial, keep these lines enabled
// (you can change the pin numbers to match your wiring):
#if ARDUINO >= 100
  SoftwareSerial mySerial(3, 2);
#else
  NewSoftSerial mySerial(3, 2);
#endif
Adafruit_GPS GPS(&mySerial);
// If using hardware serial (e.g. Arduino Mega), comment
// out the above six lines and enable this line instead:
//Adafruit_GPS GPS(&Serial1);


// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO  true

// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

void setup()  
{    
  // connect at 115200 so we can read the GPS fast enuf and
  // also spit it out
  Serial.begin(9600);
  Serial.println("Adafruit GPS library basic test!");

  // 9600 NMEA is the default baud rate for MTK - some use 4800
  GPS.begin(9600);
  
  // You can adjust which sentences to have the module emit, below
  
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data for high update rates!
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // uncomment this line to turn on all the available data - for 9600 baud you'll want 1 Hz rate
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_ALLDATA);
  
  // Set the update rate
  // 1 Hz update rate
  //GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  // 5 Hz update rate- for 9600 baud you'll have to set the output to RMC or RMCGGA only (see above)
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ);
  // 10 Hz update rate - for 9600 baud you'll have to set the output to RMC only (see above)
  //GPS.sendCommand(PMTK_SET_NMEA_UPDATE_10HZ);

  // Request updates on antenna status, comment out to keep quiet
  GPS.sendCommand(PGCMD_ANTENNA);

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  useInterrupt(true);
  
  delay(1000);
}

// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
  if (GPSECHO)
    if (c) UDR0 = c;  
    // writing direct to UDR0 is much much faster than Serial.print 
    // but only one character can be written at a time. 
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}


void loop()                     // run over and over again
{
}

Kurze Info habe es nun hinbekommen und der Code sieht wie folgt aus:

#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
const int chipSelect = 8;

int pinX = A0;     // X-Achse
int pinY = A1;     // Y-Achse
int pinZ = A2;     // Z-Achse
int pinT = A3; //Temperatursensor

SoftwareSerial mySerial(3, 2);

Adafruit_GPS GPS(&mySerial);

#define GPSECHO  true

boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

void setup()  
{

  Serial.begin(115200);

  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
  
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate

  GPS.sendCommand(PGCMD_ANTENNA);

  useInterrupt(true);

  delay(1000);
  // Ask for firmware version
  mySerial.println(PMTK_Q_RELEASE);
  
    Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;  
#endif
}

void useInterrupt(boolean v) {
  if (v) {
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();
void loop()                     // run over and over again
{
  // in case you are not using the interrupt above, you'll
  // need to 'hand query' the GPS, not suggested :(
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }
  
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {

    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

  if (timer > millis())  timer = millis();


  if (millis() - timer > 2000) { 
    timer = millis(); // reset the timer
    
//  Serial.println();
//  Serial.print("\nTime: ");
//  Serial.print(GPS.hour, DEC); Serial.print(':');
//  Serial.print(GPS.minute, DEC); Serial.print(':');
//  Serial.print(GPS.seconds, DEC); Serial.print('.');
//  Serial.println(GPS.milliseconds);
//  Serial.print("Location: ");
//  Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
//  Serial.print(", "); 
//  Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
//  Serial.print("Speed (knots): "); Serial.println(GPS.speed);
  
  char Werte[50];

  sprintf(Werte, "%d,%d,%d,%d,%d", analogRead(pinX), analogRead(pinY),analogRead(pinZ),analogRead(pinT),GPS.speed); 

  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(GPS.latitude, 4); Serial.print(GPS.lat);
    dataFile.println(GPS.longitude, 4); Serial.print(GPS.lon);
    dataFile.println(Werte);
    dataFile.close();
    // print to the serial port too:
    Serial.println(Werte);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
  }
}

Bin jetzt noch etwas am knobeln bzgl der Datenauswertung, aber wird schon werden :wink:

bzgl der Datenauswertung.
auf der website geovisualizer[dot]com kann ich meine GPS Daten als Dezimalzahlen eingeben und bekomme entsprechend meine Route ausgespuckt.
Leider erhalte ich jedoch bei meinem Code am Ende die Position in grad, minuten, sekunden. hat jmd einen tipp wie ich die daten als dezimalzahl erhalte? bzw wie ich meine daten so erhalte, dass ich ohne viel aufwand mir die Route anzeigen lassen kann?

okay, löse die ganze Sache nun so, dass ich eine Umrechnung in excel ausführe. Aufwand ist dadurch auch minimal. passt :wink: