Code starts here - call it GPSLogger_v2.1

/* Code starts here - call it GPSLogger_v2.1 :) */



// this is a generic logger that does checksum testing so the data written should be always good

// Assumes a sirf III chipset logger attached to pin 0 and 1



#include "AF_SDLog.h"

#include "util.h"

#include <avr/pgmspace.h>

#include <avr/sleep.h>



// power saving modes

#define SLEEPDELAY 0

#define TURNOFFGPS 0

#define LOG_RMC_FIXONLY 1



AF_SDLog card;

File f;



#define led1Pin 4

#define led2Pin 3

#define powerPin 2



#define BUFFSIZE 75

char buffer[BUFFSIZE];

uint8_t bufferidx = 0;

uint8_t fix = 0; // current fix data

uint8_t i;



/* EXAMPLE



$PSRF103,<msg>,<mode>,<rate>,<cksumEnable>*CKSUM<CR><LF>



<msg> 00=GGA,01=GLL,02=GSA,03=GSV,04=RMC,05=VTG

<mode> 00=SetRate,01=Query

<rate> Output every <rate>seconds, off=00,max=255

<cksumEnable> 00=disable Checksum,01=Enable checksum for specified message

Note: checksum is required



Example 1: Query the GGA message with checksum enabled

$PSRF103,00,01,00,01*25



Example 2: Enable VTG message for a 1Hz constant output with checksum enabled

$PSRF103,05,00,01,01*20



Example 3: Disable VTG message

$PSRF103,05,00,00,01*21



*/



#define SERIAL_SET   "$PSRF100,01,4800,08,01,00*0E\r\n"



// GGA-Global Positioning System Fixed Data, message 103,00

#define LOG_GGA 0

#define GGA_ON   "$PSRF103,00,00,01,01*25\r\n"

#define GGA_OFF  "$PSRF103,00,00,00,01*24\r\n"



// GLL-Geographic Position-Latitude/Longitude, message 103,01

#define LOG_GLL 0

#define GLL_ON   "$PSRF103,01,00,01,01*26\r\n"

#define GLL_OFF  "$PSRF103,01,00,00,01*27\r\n"



// GSA-GNSS DOP and Active Satellites, message 103,02

#define LOG_GSA 0

#define GSA_ON   "$PSRF103,02,00,01,01*27\r\n"

#define GSA_OFF  "$PSRF103,02,00,00,01*26\r\n"



// GSV-GNSS Satellites in View, message 103,03

#define LOG_GSV 0

#define GSV_ON   "$PSRF103,03,00,01,01*26\r\n"

#define GSV_OFF  "$PSRF103,03,00,00,01*27\r\n"



// RMC-Recommended Minimum Specific GNSS Data, message 103,04

#define LOG_RMC 1

#define RMC_ON   "$PSRF103,04,00,01,01*21\r\n"

#define RMC_OFF  "$PSRF103,04,00,00,01*20\r\n"



// VTG-Course Over Ground and Ground Speed, message 103,05

#define LOG_VTG 0

#define VTG_ON   "$PSRF103,05,00,01,01*20\r\n"

#define VTG_OFF  "$PSRF103,05,00,00,01*21\r\n"



// Switch Development Data Messages On/Off, message 105

#define LOG_DDM 1

#define DDM_ON   "$PSRF105,01*3E\r\n"

#define DDM_OFF  "$PSRF105,00*3F\r\n"



#define USE_WAAS   0     // useful in US, but slower fix

#define WAAS_ON    "$PSRF151,01*3F\r\n"       // the command for turning on WAAS

#define WAAS_OFF   "$PSRF151,00*3E\r\n"       // the command for turning off WAAS





// read a Hex value and return the decimal equivalent

uint8_t parseHex(char c) {

  if (c < '0')

    return 0;

  if (c <= '9')

    return c - '0';

  if (c < 'A')

    return 0;

  if (c <= 'F')

    return (c - 'A')+10;

}



// blink out an error code

void error(uint8_t errno) {

  while(1) {

    for (i=0; i<errno; i++) {

      digitalWrite(led1Pin, HIGH);

      digitalWrite(led2Pin, HIGH);

      delay(100);

      digitalWrite(led1Pin, LOW);

      digitalWrite(led2Pin, LOW);

      delay(100);

    }

    for (; i<10; i++) {

      delay(200);

    }

  }

}



void setup()

{

  WDTCSR |= (1 << WDCE) | (1 << WDE);

  WDTCSR = 0;

  Serial.begin(4800);

  putstring_nl("\r\nGPSlogger");

  pinMode(led1Pin, OUTPUT);

  pinMode(led2Pin, OUTPUT);

  pinMode(powerPin, OUTPUT);

  digitalWrite(powerPin, LOW);



  if (!card.init_card()) {

    putstring_nl("Card init. failed!");

    error(1);

  }

  if (!card.open_partition()) {

    putstring_nl("No partition!");

    error(2);

  }

  if (!card.open_filesys()) {

    putstring_nl("Can't open filesys");

    error(3);

  }

  if (!card.open_dir("/")) {

    putstring_nl("Can't open /");

    error(4);

  }



  strcpy(buffer, "GPSLOG00.TXT");

  for (buffer[6] = '0'; buffer[6] <= '9'; buffer[6]++) {

    for (buffer[7] = '0'; buffer[7] <= '9'; buffer[7]++) {

      //putstring("\ntrying to open ");Serial.println(buffer);

      f = card.open_file(buffer);

      if (!f)

        break;

      card.close_file(f);

    }

    if (!f)

      break;

  }



  if(!card.create_file(buffer)) {

    putstring("couldnt create ");

    Serial.println(buffer);

    error(5);

  }

  f = card.open_file(buffer);

  if (!f) {

    putstring("error opening ");

    Serial.println(buffer);

    card.close_file(f);

    error(6);

  }

  putstring("writing to ");

  Serial.println(buffer);

  putstring_nl("ready!");



  putstring(SERIAL_SET);

  delay(250);



  if (LOG_DDM)

    putstring(DDM_ON);

  else

    putstring(DDM_OFF);

  delay(250);



  if (LOG_GGA)

    putstring(GGA_ON);

  else

    putstring(GGA_OFF);

  delay(250);



  if (LOG_GLL)

    putstring(GLL_ON);

  else

    putstring(GLL_OFF);

  delay(250);



  if (LOG_GSA)

    putstring(GSA_ON);

  else

    putstring(GSA_OFF);

  delay(250);



  if (LOG_GSV)

    putstring(GSV_ON);

  else

    putstring(GSV_OFF);

  delay(250);



  if (LOG_RMC)

    putstring(RMC_ON);

  else

    putstring(RMC_OFF);

  delay(250);



  if (LOG_VTG)

    putstring(VTG_ON);

  else

    putstring(VTG_OFF);

  delay(250);



  if (USE_WAAS)

    putstring(WAAS_ON);

  else

    putstring(WAAS_OFF);

}



void loop()

{

  //Serial.println(Serial.available(), DEC);

  char c;

  uint8_t sum;



  // read one 'line'

  if (Serial.available()) {

    c = Serial.read();

    //Serial.print(c, BYTE);

    if (bufferidx == 0) {

      while (c != '$')

        c = Serial.read(); // wait till we get a $

    }

    buffer[bufferidx] = c;



    //Serial.print(c, BYTE);

    if (c == '\n') {

      //putstring_nl("EOL");

      //Serial.print(buffer);

      buffer[bufferidx+1] = 0; // terminate it



      if (buffer[bufferidx-4] != '*') {

        // no checksum?

        Serial.print('*', BYTE);

        bufferidx = 0;

        return;

      }

      // get checksum

      sum = parseHex(buffer[bufferidx-3]) * 16;

      sum += parseHex(buffer[bufferidx-2]);



      // check checksum

      for (i=1; i < (bufferidx-4); i++) {

        sum ^= buffer[i];

      }

      if (sum != 0) {

        //putstring_nl("Cxsum mismatch");

        Serial.print('~', BYTE);

        bufferidx = 0;

        return;

      }

      // got good data!



      if (strstr(buffer, "GPRMC")) {

        // find out if we got a fix

        char *p = buffer;

        p = strchr(p, ',')+1;

        p = strchr(p, ',')+1;       // skip to 3rd item



        if (p[0] == 'V') {

          digitalWrite(led1Pin, LOW);

          fix = 0;

        } else {

          digitalWrite(led1Pin, HIGH);

          fix = 1;

        }

      }

      if (LOG_RMC_FIXONLY) {

        if (!fix) {

          Serial.print('_', BYTE);

          bufferidx = 0;

          return;

        }

      }

      // rad. lets log it!

      Serial.print(buffer);

      Serial.print('#', BYTE);

      digitalWrite(led2Pin, HIGH);      // sets the digital pin as output



      if(card.write_file(f, (uint8_t *) buffer, bufferidx) != bufferidx) {

         putstring_nl("can't write!");

    return;

      }



      digitalWrite(led2Pin, LOW);



      bufferidx = 0;



      // turn off GPS module?

      if (TURNOFFGPS) {

        digitalWrite(powerPin, HIGH);

      }



      sleep_sec(SLEEPDELAY);

      digitalWrite(powerPin, LOW);

      return;

    }

    bufferidx++;

    if (bufferidx == BUFFSIZE-1) {

       Serial.print('!', BYTE);

       bufferidx = 0;

    }

  } else {



  }



}



void sleep_sec(uint8_t x) {

  while (x--) {

     // set the WDT to wake us up!

    WDTCSR |= (1 << WDCE) | (1 << WDE); // enable watchdog & enable changing it

    WDTCSR = (1<< WDE) | (1 <<WDP2) | (1 << WDP1);

    WDTCSR |= (1<< WDIE);

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    sleep_enable();

    sleep_mode();

    sleep_disable();

  }

}



SIGNAL(WDT_vect) {

  WDTCSR |= (1 << WDCE) | (1 << WDE);

  WDTCSR = 0;

}



/* End code */

你可能感兴趣的:(Logger)