Simple GPS logging to SD with Duemilanove 368

Its my first post, so Hi to everyone!
Was browsing this Arduino forum for quite a while now and find it very useful and found tons of good information here, well-done!.
My problem is though, I am trying to log data from Lycosys LS20031 10Hz GPS to an SD card without any conversion or parsing NMEA sentences.
I have tried code below from ladyada
(using hardware Serial interface), but it can't seems to cope with the data coming from GPS and misses some sentences. Even after I dropped the rate to 38400 it is still misses some. I can not go lower then 38400 as the GPS wouldn't work at 10Hz.
I have tried to go 5Hz and 19200 and only limited to GGA, GSA and RMC sentences and it improved a bit, but still missing some chunks of data.
I have checked the GPS itself, by using basic GPS test code below and it spits data on the screen perfectly.

void setup() {
  Serial.begin(57600);  
}

void loop() {
  if (Serial.available()) {
    Serial.print(Serial.read(), BYTE);
  }
}

I understand the problems are with hardware serial interface and reading the forums NewSoftSerial is the way to go, I have tried many different codes from various forums, but I can't find a good working code which would do NewSoftSerial and SD logging. Unfortunately, I am not a programmer, so it takes me quite a long time to figure out what the code does. I have attempted to merge two codes together, but no much luck there.

So, if anyone could point me in the direction of a good starting code to get SD logging with NewSoftSerial or any other alternatives.
Or if you could help me changing the code below to adopt NewSoftSerial, I would really appreciate this.

How is the code you showed doing anything useful? The code is reading data from the serial port, and writing data back to the same port. What's on the other end of the port?
If it's the GPS, how is the GPS dealing with the data you send it?

If it's the Serial Monitor, where is the GPS data coming from?

Hi PaulS! thanks for reply. This code above I used only just to test the GPS. The setup as follows: The GPS TX wire connected to PIN 0 on Arduino board. Also GPS's GND and 3.3V connected to Arduino board as well. I connected PC to the USB port for monitoring data coming from the GPS, using Arduino 0018 serial monitor.
The code above just sends to PC everything it receives from PIN0. My understanding is PIN 0&1 and USB Serial FTDI is the same thing.

I have just realised, I haven't included the code for writing GPS data to the SD card in the post above, here it is.

/* 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 5

#define BUFFSIZE 75
char buffer[BUFFSIZE];
uint8_t bufferidx = 0;
uint8_t fix = 0; // current fix data
uint8_t i;


#define SERIAL_SET   "$PMTK300,100,0,0,0,0*2C\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 0
#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 0
#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(38400);
  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 != '

There is a lot of stuff there that I don't need, like sleepmode and customising GPS output. I need to clear it up. But the point is, the output I see on the PC and also logged to the card has missing sentences, as highlighted below:

#~~~$GPGSA,A,3,30,25,31,06,03,13,,,,,,,6.68,4.53,4.91*05
#$GPRMC,152258.600,A,5130.5633,N,00000.3302,W,0.26,23.99,010910,,,A*49
#$GPGGA,152258.700,5130.5633,N,00000.3302,W,1,6,4.53,30.9,M,47.0,M,,*7B
#$GPGSA,A,3,30,25,31,06,03,13,,,,,,,6.68,4.53,4.91*05
#$GPRMC,152258.700,A,5130.5633,N,00000.3302,W,0.26,23.97,010910,,,A*46
#$GPGGA,152258.800,5130.5633,N,00000.3302,W,1,6,4.53,30.9,M,47.0,M,,*74
#$GPGSA,A,3,30,25,31,06,03,13,,,,,,,6.68,4.53,4.91*05
#$GPRMC,152258.800,A,5130.5633,N,00000.3302,W,0.26,23.91,010910,,,A*4F
[glow]#~~$GPGGA,152259.100,5130.5633,N,00000.3302,W,1,6,4.53,30.9,M,47.0[/glow]
#$GPGSA,A,3,30,25,31,06,03,13,,,,,,,6.68,4.53,4.91*05
#$GPRMC,152259.100,A,5130.5633,N,00000.3302,W,0.25,23.72,010910,,,A*49
#$GPGGA,152259.200,5130.5633,N,00000.3302,W,1,6,4.53,30.9,M,47.0,M,,*7F
#$GPGSA,A,3,30,25,31,06,03,13,,,,,,,6.68,4.53,4.91*05
#$GPRMC,152259.200,A,5130.5633,N,00000.3302,W,0.24,23.67,010910,,,A*4F
#*~$GPGSA,A,3,30,25,31,06,03,13,,,,,,,6.68,4.52,4.91*04
[glow]#$GPRMC,152259.500,A,5130.5634,N,00000.3302,W,0.22,23.44,010910,,,A*48[/glow]
#$GPGGA,152259.600,5130.5634,N,00000.3302,W,1,6,4.53,31.0,M,47.0,M,,*74
#$GPGSA,A

)
       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 */


There is a lot of stuff there that I don't need, like sleepmode and customising GPS output. I need to clear it up. But the point is, the output I see on the PC and also logged to the card has missing sentences, as highlighted below:

§DISCOURSE_HOISTED_CODE_1§