Ublox GPS NEO-6M Testing

Can anyone help me get started with programming this module, i only have been able to power it one, i have followed a tutorial from arduinotronics:

I can't seem to receive any real response from the device apart the a blinking LED.

I have to make a GPS Data Logger.

Most GPS modules will output serial data by default. You can send them instructions to vary the output rate and various other parameters, but it should work without any configuration.

If you have a USB to serial converter, you can connect directly to your computer. There are various free apps for the computer which will show you what the device is doing.

i guess i did get it to work,and now the only issues when using the TinyGPS++ Library, is that the printed time is for london rather than than of my country, could someone help identify the parts i need to edit

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
   This sample code demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(9600);
  ss.begin(GPSBaud);

  Serial.println(F("FullExample.ino"));
  Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
  Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
  Serial.println(F("Sats HDOP Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum"));
  Serial.println(F("          (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail"));
  Serial.println(F("---------------------------------------------------------------------------------------------------------------------------------------"));
}

void loop()
{
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
  printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
  printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);

  unsigned long distanceKmToLondon =
    (unsigned long)TinyGPSPlus::distanceBetween(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON) / 1000;
  printInt(distanceKmToLondon, gps.location.isValid(), 9);

  double courseToLondon =
    TinyGPSPlus::courseTo(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON);

  printFloat(courseToLondon, gps.location.isValid(), 7, 2);

  const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);

  printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);

  printInt(gps.charsProcessed(), true, 6);
  printInt(gps.sentencesWithFix(), true, 10);
  printInt(gps.failedChecksum(), true, 9);
  Serial.println();
  
  smartDelay(1000);

  if (millis() > 5000 && gps.charsProcessed() < 10)
    Serial.println(F("No GPS data received: check wiring"));
}

// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec)
{
  if (!valid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartDelay(0);
}

static void printInt(unsigned long val, bool valid, int len)
{
  char sz[32] = "*****************";
  if (valid)
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz);
  smartDelay(0);
}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
  if (!d.isValid())
  {
    Serial.print(F("********** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
    Serial.print(sz);
  }
  
  if (!t.isValid())
  {
    Serial.print(F("******** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
    Serial.print(sz);
  }

  printInt(d.age(), d.isValid(), 5);
  smartDelay(0);
}

static void printStr(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartDelay(0);
}

Plus i need to remove the excess information, i only need latitude longitude date and time.

the coordinates for Mauritius would be LAT -20.2 LONG 57.4

How do i modify it further for Data Logging on SD.

If you just want to remove the printing of the information, you'll just have to delete these print statements:

  printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
  printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);

And fix the headers to match of course.

Changing the time zone is a little more complicated, and really requires a Time library. TinyGPS and TinyGPS++ do not have that built-in. There's a Time library in the playground.

If that's what you want to do, ignore the rest of this, as it may be more complicated thany you want to mess with...

Cheers,
/dev

If you're really trying to reduce your RAM usage, the NeoGPS library is fully configurable with a few #defines. Simply put a // in front of the pieces you don't want.

For example, the configuration you want is only date/time/location. That would look like this in GPSfix.h:

#define GPS_FIX_DATE
#define GPS_FIX_TIME
#define GPS_FIX_LOCATION
//#define GPS_FIX_ALTITUDE
//#define GPS_FIX_SPEED
//#define GPS_FIX_HEADING
//#define GPS_FIX_SATELLITES
//#define GPS_FIX_HDOP
//#define GPS_FIX_VDOP
//#define GPS_FIX_PDOP
//#define GPS_FIX_LAT_ERR
//#define GPS_FIX_LON_ERR
//#define GPS_FIX_ALT_ERR

It also has a date/time structure that would allow you to select a different time zone. You would need to take the UTC time from the gps.fix(), convert it to seconds (i.e. clock_t), then convert it back to a time_t structure with a time zone offset:

    clock_t utc_seconds = (clock_t) gps.fix().dateTime;
    time_t  my_time( utc_seconds, MY_HOURS_OFFSET_FROM_LONDON );

Then you can print the whole date & time with this

    Serial << my_time << '\n';

or access the time pieces like this:

    Serial.Print( my_time.hours )

If you want the current location, you would access these parts of gps.fix():

    int32_t my_lat = gps.fix().lat;
        // This is degrees * 10,000,000, or -202,000,000 for your location

Or, if you want the floating-point latitude, you would do this:

    double my_lat = gps_fix().latitude(); // notice the extra "()" on the end

Fair warning, though. This is really a C++ implementation, so it uses some concepts you may not be familiar with in plain-old C, like most Arduino code. I would suggest starting with the NMEA.ino example program here and see how you feel about it. :slight_smile: You'll need to change it to use the SoftwareSerial ss, too.

Thank you for the help. I've tried out the NMEA.ino and edited the GPS.fix. Library as you advised, yet i'm having trouble compiling. There is an issue with Serial1.

Arduino: 1.5.8 (Windows 7), Board: "Arduino Uno"
NMEA.ino: In function 'void setup()':
NMEA.ino:35:3: error: 'Serial1' was not declared in this scope
NMEA.ino: In function 'void loop()':
NMEA.ino:44:10: error: 'Serial1' was not declared in this scope
Error compiling.

and i also don't know the pin configuration. Where should i connect the Rx and Tx from the GPS Module.

As for the time zone, i've not yet tried it.

An Arduino Uno has no Serial1.
I just use software serial with my Ublox, just remember the default speed may not be the same as the example code.

Oh yeahhh. I'll try see if it works on a MEGA. Thanks. I hope it does.


After Testing. I guess it did not work either. The example as it is did not compile.

/*
  Serial is for trace output.
  Serial1 should be connected to the GPS device.
*/

#include <Arduino.h>

#include "NMEAGPS.h"
#include "Streamers.h"

// Set this to your debug output device.
Stream & trace = Serial;

static NMEAGPS gps;

//--------------------------

void setup()
{
  // Start the normal trace output
  Serial.begin(9600);
  trace.print( F("NMEA test: started\n") );
  trace.print( F("fix object size = ") );
  trace.println( sizeof(gps.fix()) );
  trace.print( F("NMEAGPS object size = ") );
  trace.println( sizeof(NMEAGPS) );

  trace_header();

  trace.flush();
  
  // Start the UART for the GPS device
  Serial1.begin(9600);
}

//--------------------------

void loop()
{
  static uint32_t last_rx = 0L;

  while (Serial1.available()) {
    last_rx = millis();

    if (gps.decode( Serial1.read() ) == NMEAGPS::DECODE_COMPLETED) {
//      trace << (uint8_t) gps.nmeaMessage << ' ';

// Make sure that the only sentence we care about is enabled
#ifndef NMEAGPS_PARSE_RMC
#error NMEAGPS_PARSE_RMC must be defined in NMEAGPS.h!
#endif

      if (gps.nmeaMessage == NMEAGPS::NMEA_RMC)
        //  Use received GPRMC sentence as a pulse
        seconds++;
    }
  }

  // Print things out once per second, after the serial input has died down.
  // This prevents input buffer overflow during printing.

  static uint32_t last_trace = 0L;

  if ((last_trace != seconds) && (millis() - last_rx > 5)) {
    last_trace = seconds;

    // It's been 5ms since we received anything, log what we have so far...
    trace_all( gps, gps.fix() );
  }
}

Arduino: 1.5.8 (Windows 7), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
Build options changed, rebuilding all
C:\Users\Jayvin\Documents\Arduino\libraries\NeoGPS-masterOriginal\ubxGPS.cpp: In member function 'bool ubloxGPS::rxEnd()':
C:\Users\Jayvin\Documents\Arduino\libraries\NeoGPS-masterOriginal\ubxGPS.cpp:34:20: error: 'struct NMEAGPS::' has no member named 'parser_ok'
** statistics.parser_ok++;**
** ^**
C:\Users\Jayvin\Documents\Arduino\libraries\NeoGPS-masterOriginal\ubxGPS.cpp: In member function 'virtual NMEAGPS::decode_t ubloxGPS::decode(char)':
C:\Users\Jayvin\Documents\Arduino\libraries\NeoGPS-masterOriginal\ubxGPS.cpp:156:24: error: 'struct NMEAGPS::' has no member named 'parser_crcerr'
** statistics.parser_crcerr++;**
** ^**
C:\Users\Jayvin\Documents\Arduino\libraries\NeoGPS-masterOriginal\ubxGPS.cpp:166:24: error: 'struct NMEAGPS::' has no member named 'parser_crcerr'
** statistics.parser_crcerr++;**
** ^**
Error compiling.

I had a simple LCD clock/calendar up and running in about 20 minutes on a Uno, using TinyGPS+ with a Ublox 6M and SoftwareSerial at 9600 bits per second, with flash to spare.

I actually had the tinyGPS++ library working but i'm having trouble on the storing the data on an SD. :S

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
/*
   GPS
   Rx from GPS to pin 2
   Tx from GPS to pin 3
   
   SD
   MOSI - pin 11
   MISO - pin 12
   CLK - pin 13
   CS - pin 4
*/
static const int RXPin = 3, TXPin = 2;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//SD
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;

void setup()
{
  Serial.begin(9600);
  
    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.");
  
  
  
  ss.begin(GPSBaud);

  ///Serial.println(F("FullExample.ino"));
  //Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
  //Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  //Serial.println(F("by Mikal Hart"));
  Serial.println();
  Serial.println(F("Latitude   Longitude   Date       Time     Date"));
  Serial.println(F("(deg)      (deg)                 (UTC+0)   Age"));
  Serial.println(F("---------------------------------------------------------------------------------------------------------------------------------------"));
}

void loop()
{
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    //dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
  
  
  
  
  
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  //printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  //printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
  printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  //printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  //printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  //printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  //printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
  //printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);

  unsigned long distanceKmToLondon =
    (unsigned long)TinyGPSPlus::distanceBetween(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON) / 1000;
  //printInt(distanceKmToLondon, gps.location.isValid(), 9);

  double courseToLondon =
    TinyGPSPlus::courseTo(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT, 
      LONDON_LON);

  //printFloat(courseToLondon, gps.location.isValid(), 7, 2);

  const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);

 // printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);

  //printInt(gps.charsProcessed(), true, 6);
  //printInt(gps.sentencesWithFix(), true, 10);
  //printInt(gps.failedChecksum(), true, 9);
  Serial.println();
  
  smartDelay(1000);

  if (millis() > 5000 && gps.charsProcessed() < 10)
    Serial.println(F("No GPS data received: check wiring"));
}

// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do 
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec)
{
  if (!valid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartDelay(0);
}

static void printInt(unsigned long val, bool valid, int len)
{
  char sz[32] = "*****************";
  if (valid)
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz);
  smartDelay(0);
}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
  if (!d.isValid())
  {
    Serial.print(F("********** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
    Serial.print(sz);
  }
  
  if (!t.isValid())
  {
    Serial.print(F("******** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
    Serial.print(sz);
  }

  printInt(d.age(), d.isValid(), 5);
  smartDelay(0);
}

static void printStr(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartDelay(0);
}

Arduino: 1.5.8 (Windows 7), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
Build options changed, rebuilding all
GPD_SD_trial.ino: In function 'void loop()':
GPD_SD_trial.ino:70:22: error: 'dataString' was not declared in this scope
Error compiling.

i obviously did not declare the dataString, basically i did not know how to continue.

You don't put anything into the "dataString" you didn't declare, so why not just get rid of it?

Actually, i was going to use the dataString for the data that is being printed on the Serial Monitor. I am now looking for a way to program that part.

A combination of dtostrf and sprintf, plus about a 60 byte buffer ?

Truth be spoken. I don't really understand anything about these, are they an available function? Serial.print?

http://www.hobbytronics.co.uk/arduino-float-vars

could you help me find some better resources?

dtostrf will convert a float to a string.
sprintf will convert just about anything except a float into a string (but it will copy a string into another string)

(Uncompiled untested) just to point you in the right direction)

char longBuffer [20]; // may need resizing
char latBuffer [20]; // may need resizing
char dataString [80];
dtostrf (latBuffer, gps.location.lat(), 6); // may need to put this in a conditional in case the fix isn't valid
dtostrf (latBuffer, gps.location.lng(), 6);
sprintf (dataString, "%s,%s, @ %02d:%02d:%02d", latBuffer, longBuffer, hours, minutes, seconds);

So i should just add that to my code? If i am not mistaken you've declared the dataString as a string of all the different strings that were being printed, right?

before the void setup:

char longBuffer [20]; // may need resizing
char latBuffer [20]; // may need resizing
char dataString [80];

In the loop fn:

dtostrf (latBuffer, gps.location.lat(), 6); // may need to put this in a conditional in case the fix isn't valid
dtostrf (longBuffer, gps.location.lng(), 6);
sprintf (dataString, "%s,%s, @ %02d:%02d:%02d", latBuffer, longBuffer, hours, minutes, seconds);

Then the

dataFile.println(dataString)

should write it to the file on the SD.


After Compiling,

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
/*
   GPS
   Rx from GPS to pin 2
   Tx from GPS to pin 3

   SD
   MOSI - pin 11
   MISO - pin 12
   CLK - pin 13
   CS - pin 4
*/
static const int RXPin = 3, TXPin = 2;
static const uint32_t GPSBaud = 9600;

//from forum
char longBuffer [20]; // may need resizing
char latBuffer [20]; // may need resizing
char dataString [80];

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//SD
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;

void setup()
{
  Serial.begin(9600);

  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.");



  ss.begin(GPSBaud);

  ///Serial.println(F("FullExample.ino"));
  //Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
  //Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  //Serial.println(F("by Mikal Hart"));
  Serial.println();
  Serial.println(F("Latitude   Longitude   Date       Time     Date"));
  Serial.println(F("(deg)      (deg)                 (UTC+0)   Age"));
  Serial.println(F("---------------------------------------------------------------------------------------------------------------------------------------"));
}

void loop()
{
  dtostrf (latBuffer, gps.location.lat(), 6); // may need to put this in a conditional in case the fix isn't valid
  dtostrf (longBuffer, gps.location.lng(), 6);
  sprintf (dataString, "%s,%s, @ %02d:%02d:%02d", latBuffer, longBuffer);

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

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





  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  //printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  //printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
  printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  //printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  //printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  //printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  //printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
  //printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);

  unsigned long distanceKmToLondon =
    (unsigned long)TinyGPSPlus::distanceBetween(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT,
      LONDON_LON) / 1000;
  //printInt(distanceKmToLondon, gps.location.isValid(), 9);

  double courseToLondon =
    TinyGPSPlus::courseTo(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT,
      LONDON_LON);

  //printFloat(courseToLondon, gps.location.isValid(), 7, 2);

  const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);

  // printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);

  //printInt(gps.charsProcessed(), true, 6);
  //printInt(gps.sentencesWithFix(), true, 10);
  //printInt(gps.failedChecksum(), true, 9);
  Serial.println();

  smartDelay(1000);

  if (millis() > 5000 && gps.charsProcessed() < 10)
    Serial.println(F("No GPS data received: check wiring"));
}

// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec)
{
  if (!valid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i = flen; i < len; ++i)
      Serial.print(' ');
  }
  smartDelay(0);
}

static void printInt(unsigned long val, bool valid, int len)
{
  char sz[32] = "*****************";
  if (valid)
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i = strlen(sz); i < len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len - 1] = ' ';
  Serial.print(sz);
  smartDelay(0);
}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
  if (!d.isValid())
  {
    Serial.print(F("********** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
    Serial.print(sz);
  }

  if (!t.isValid())
  {
    Serial.print(F("******** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
    Serial.print(sz);
  }

  printInt(d.age(), d.isValid(), 5);
  smartDelay(0);
}

static void printStr(const char *str, int len)
{
  int slen = strlen(str);
  for (int i = 0; i < len; ++i)
    Serial.print(i < slen ? str[i] : ' ');
  smartDelay(0);
}

i have this :S
Arduino: 1.5.8 (Windows 7), Board: "Arduino Uno"
Build options changed, rebuilding all
GPD_SD_trial.ino: In function 'void loop()':
GPD_SD_trial.ino:69:44: error: cannot convert 'char*' to 'double' for argument '1' to 'char* dtostrf(double, signed char, unsigned char, char*)'
GPD_SD_trial.ino:70:45: error: cannot convert 'char*' to 'double' for argument '1' to 'char* dtostrf(double, signed char, unsigned char, char*)'
Error compiling.

Sorry - parameters in wrong order http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html

char * dtostrf(double __val,signed char __width,unsigned char __prec,	char * __s)

e.g for latBuffer:
val=gps.location.lat()
width=4
prec=6

Should i modify it to:

char * dtostrf(gps.location.lat(),4,6,latBuffer)

After the modification, it did compile, but when i checked the SD card, the datalog.txt file was not even created.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>

/* Pin Configurations
   
   GPS
   Rx from GPS to pin 2
   Tx from GPS to pin 3

   SD
   MOSI - pin 11
   MISO - pin 12
   CLK - pin 13
   CS - pin 4
*/
static const int RXPin = 3, TXPin = 2;
static const uint32_t GPSBaud = 9600;

//from forum
char longBuffer [15]; // may need resizing
char latBuffer [15]; // may need resizing
char dataString [80];

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
//SD
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;

File dataFile;

void setup()
{
  Serial.begin(9600);

  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.");


  if (SD.exists("datalog.txt")) {
    Serial.println("datalog.txt exists.");
  }
  else {
    Serial.println("datalog.txt doesn't exist.");
  }

  // open a new file and immediately close it:
  Serial.println("Creating datalog.txt...");
  dataFile = SD.open("datalog.txt", FILE_WRITE);
 dataFile.close();

  // Check to see if the file exists: 
  if (SD.exists("datalog.txt")) {
    Serial.println("datalog.txt exists.");
  }
  else {
    Serial.println("datalog.txt doesn't exist.");  
  }



  ss.begin(GPSBaud);

  ///Serial.println(F("FullExample.ino"));
  //Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
  //Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  //Serial.println(F("by Mikal Hart"));
  Serial.println();
  Serial.println(F("Latitude   Longitude   Date       Time     Date"));
  Serial.println(F("(deg)      (deg)                 (UTC+0)   Age"));
  Serial.println(F("----------------------------------------------------------"));
}

void loop()
{
  

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

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





  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  //printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
  //printInt(gps.hdop.value(), gps.hdop.isValid(), 5);
  printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
  printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
  //printInt(gps.location.age(), gps.location.isValid(), 5);
  printDateTime(gps.date, gps.time);
  //printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
  //printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
  //printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
  //printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.value()) : "*** ", 6);

  unsigned long distanceKmToLondon =
    (unsigned long)TinyGPSPlus::distanceBetween(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT,
      LONDON_LON) / 1000;
  //printInt(distanceKmToLondon, gps.location.isValid(), 9);

  double courseToLondon =
    TinyGPSPlus::courseTo(
      gps.location.lat(),
      gps.location.lng(),
      LONDON_LAT,
      LONDON_LON);

  //printFloat(courseToLondon, gps.location.isValid(), 7, 2);

  const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);

  // printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);

  //printInt(gps.charsProcessed(), true, 6);
  //printInt(gps.sentencesWithFix(), true, 10);
  //printInt(gps.failedChecksum(), true, 9);
  Serial.println();

  smartDelay(1000);

  if (millis() > 5000 && gps.charsProcessed() < 10)
    Serial.println(F("No GPS data received: check wiring"));
}

// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void printFloat(float val, bool valid, int len, int prec)
{
  if (!valid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i = flen; i < len; ++i)
      Serial.print(' ');
  }
  smartDelay(0);
}

static void printInt(unsigned long val, bool valid, int len)
{
  char sz[32] = "*****************";
  if (valid)
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i = strlen(sz); i < len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len - 1] = ' ';
  Serial.print(sz);
  smartDelay(0);
}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
  if (!d.isValid())
  {
    Serial.print(F("********** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
    Serial.print(sz);
  }

  if (!t.isValid())
  {
    Serial.print(F("******** "));
  }
  else
  {
    char sz[32];
    sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
    Serial.print(sz);
  }

  printInt(d.age(), d.isValid(), 5);
  smartDelay(0);
}

static void printStr(const char *str, int len)
{
  int slen = strlen(str);
  for (int i = 0; i < len; ++i)
    Serial.print(i < slen ? str[i] : ' ');
  smartDelay(0);
  
  dtostrf (gps.location.lat(),4,6,latBuffer); // may need to put this in a conditional in case the fix isn't valid
  dtostrf (gps.location.lng(),4,6,longBuffer);
  sprintf (dataString, "%s,%s, @ %02d:%02d:%02d", latBuffer, longBuffer);
}

Can someone point out the mistake i've made.

You never call printStr

dataFile.println(dataString)

This part was supposed to print the data into the file, right?

The file itself was not created. :S