I made a GPS library for decoding NMEA protocol

OK, this won't work for me as I have a GPS/GPRS shield that sits directly on top of the Arduino and uses pins 2 and 3.

I am aware that the example code does not work (yet) via Arduino pins 2 and 3. However, I'm hoping to borrow an Arduino this weekend and write some new example code that uses "SoftwareSerial" on those two pins. I have no reason to assume that would not work.

Maarten

But as you know the SoftwareSerial is quite slow or better it does
need a lot of power and that slows the Arduino down. I got some
experience in this. I do now parse the Gps sentence at 5hz on the
UART so the Hardware Serial on pin 0. I think as your program grows
Software Serial is going to be a problem.
And at 5hz the Software Serial is relay struggling getting the
data and parse them...

Geko

I wasn't really aware that SoftwareSerial was much slower than Serial, but I trust that it is. This may indeed be limiting to the number of sentences the library can process per second. However, this not only depends on the frequency of NMEA cycles (for example 1 Hz, or 5 Hz), but also on the number of sentences output per cycle. If you are only using a particular sentence type (for example GPRMC or GPGGA), then some GPS receivers let you choose to only output those sentence types. This will considerably speed-up processing.

Also, I would think that the library as-it-is does not require much processing, but only at the moment when a GPRMC sentence was completed: at that moment it does a lot of floating-point stuff.

Maarten

Hi Maarten,

Any progress with the Arduino port of the NMEA library? It works fine with the Wiring IDE though.

Keep up the good work.

thanks,
Madhu.

I'm looking forward to Maarten's progress too.

And I got some success(? )

with Arduino and NMEA library , I connected GPS to HW serial and AFSoftSerial to the PC
It works ^^ (<- smiling eyes. kind of Korean emoticon. korean emoticon is upright style. can you understand it? )
But programming is some hassle --; (<- cold sweating ?)

Any idea of how to connect the arduino BT to a BT GPS receiver?

this is the closest I've read to a BT connection other than a computer:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1180546719 :-[

How is the arduino port coming along?

I am looking foward to this :slight_smile:

I'm not sure why anybody is waiting for a "port" to the Arduino - the NMEA library works out of the box for me. I think the example programs are what needs to be modified.

I grabbed the provided example to show all sentences and modified two or three lines - it worked fine for me.

Here is the modified code, but my contribution wasn't much. Oh yeah, you'll need the AFSoftSerial library (since the normal software serial doesn't have an avaliable function).

// This example illustates access to all sentence types,
// using the NMEA library. It assumes that a GPS receiver
// is connected to serial port 'Serial1' at 4800 bps.

#include <nmea.h>
#include <AFSoftSerial.h>

// Constants
#define rxPin 9
#define txPin 8

// set up the serial port

AFSoftSerial mySerial = AFSoftSerial(rxPin, txPin);

// variables
NMEA gps(ALL);    // GPS data connection to all sentence types

void setup() {
  Serial.begin(9600);
  mySerial.begin(4800);
}

void loop() {
  if (mySerial.available() > 0 ) {
    // read incoming character from GPS and feed it to NMEA type object
    if (gps.decode(mySerial.read())) {
      // full sentence received
      Serial.print ("Sentence = ");
      Serial.println (gps.sentence());
      Serial.print ("Datatype = ");
      Serial.println (gps.term(0));
      Serial.print ("Number of terms = ");
      Serial.println (gps.terms());
    }
  }
}

Hope this helps,

Brad.

[edit]I've seen a reference somewhere on the forum that this library has a large memory footprint - perhaps that's the problem people are seeing? I've upgraded to the 328P, so maybe that's why I don't see a problem?[/edit]

I've seen a reference somewhere on the forum that this library has a large memory footprint - perhaps that's the problem people are seeing? I've upgraded to the 328P, so maybe that's why I don't see a problem?

I think your assessment is correct, Brad. Creating a single NMEA object allocates ~1200 bytes of RAM, which is probably great for the 328P, but a little too big to fit in a "conventional" Arduino.

I am working on a derivative library called TinyGPS that provides a subset of NMEA's functionality but is much smaller. It provides latitude, longitude, time, date, course, speed, and magnetic variation -- everything that the $GPRMC sentence provides. I would welcome suggestions on whether this would suffice for a majority of users.

Mikal

It provides latitude, longitude, time, date, course, speed, and magnetic variation -- everything that the $GPRMC sentence provides. I would welcome suggestions on whether this would suffice for a majority of users.

Mikal-

I'm not sure what everybody else needs, but I think it would be fine for my purposes (I haven't looked, but I think that's enough information to plot my location on google maps).

Since I'm passing the data via XBee using API mode, I'm limited to a payload of 72 bytes (once I get the code sorted out) so simple is really better.

I'm looking forward to your library.

Brad.

I'm looking forward to your library.

You just signed up as an alpha tester! :slight_smile:

I'll send the library via PM. Because I am very eager to keep it as small as possible, it (currently) doesn't use any floating point at all. Therefore, it reports lat/long in integral units of 1/10000th of a degree. If you want the same kind of float output that Martin's library has you can simply convert with:

float lat = (float)tinygps.latitude() / 10000.0;

Mikal

Mikal,

any chance to have the altitude too?
I'm working on a similar project( a small GPS parser), but I still am at an early stage.
I'm trying not to use float numbers, now I'm optimizing the sentence recognition/checksum calculation, then I will start with the sentence parsing.

I will gladly be the second alpha fpr your tynyGPS... :slight_smile:

rgds
giorgio

Hi gio--

Yeah, I've had some other people ask about altitude. I'll make sure to get that in there soon. Sorry for the oversight.

Mikal

Sorry for resurrecting this old thread - but this thing is exactly what i was looking for.. unfortunately it doesnt compile:

In file included from C:\Documents and Settings\Administrator\Desktop\arduino\hardware\cores\arduino/WProgram.h:4,


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected unqualified-id before 'int'


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected identifier before '(' token


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected `)' before '(' token


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected ',' or '...' before '(' token


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected initializer before ')' token


c:/documents and settings/administrator/desktop/arduino/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:176: error: '__compar_fn_t' has not been declared


In file included from C:\Documents and Settings\Administrator\Desktop\arduino\hardware\cores\arduino/WProgram.h:6,

From what i can see there is no real problem with a file of this library, but i only get these errors when i try to compile this library..

Nachtwind, which library are you using, there are two mentioned in this thread.

I am using Mikal's code and it compiles without problem in version 0012.

Not sure what code you are actually running but those errors are caused some pesky macros in the Arduino code – these macros will be removed in the imminent release of version 0013.

if you don't want to wait, try adding the following to the your sketch Just after the #include of the gps header file

#undef int
#undef abs
#undef double
#undef float
#undef round

Thanks for the help. I was referring to the first Library in this thread - i think i have overlooked the second one then...

But thanks, that did really help me :0)

All--

I'm pleased to release a beta version of my new GPS/NMEA library at http://www.sundial.com/tinygps. If you try it out, please send me a note so that I can verify that it is working correctly.

Mem and Brad, the newest version (5) reorganizes the API just a bit. There is now an "age of fix" associated with both the position and the date/time. This is a good way to tell if your data is getting stale.

Mikal

I have compiled the code with my sketches and although I have not had the chance to actually connect a GPS to this version, it looks good – not having to call the status method (as in version 3) does simplify the usage. Here is the relevant fragment from my time sketch:

boolean gpsTimeSync(){
  //  syncs time and returns true if valid time avail from gps
  unsigned long datetime_fix_age = 0;
  gps.get_datetime(NULL,NULL, &datetime_fix_age);
  if(datetime_fix_age < 1100){
    DateTime.sync(gpsTimeToTime_t());
    return true;
  }   
  return false;
} 

time_t gpsTimeToTime_t(){
  // returns time_t from gps date and time 
  byte month, day, hour, minute, second, hundredths;
  int year;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, NULL, NULL);
  return DateTime.makeTime( second, minute, hour, day, month, year );
}

Also, for another application that involves logging gps position as frequently as possible, I was thinking about adding a callback function to the end of the term_complete method so the app did not need to poll to see if new data was available, what do you think?

BTW, I think the example sketches in the download will seem odd to many Arduino users because the streaming syntax is not common. I suggest at least one example sketch using the typical (albeit long winded) arduino style for those users that have no experience with the insertion syntax.

Again, many thanks for the library.

Mem,

Excellent feedback as always. I'll remove the streaming << examples in the next iteration.

The callback idea is a very good one, but what would you think of instead changing "gps << c" to "gps.encode(c)" and having the encode method return a boolean indicating whether or not a valid sentence had just been processed? You'd then write code like:

while (afss.available())
{
  if (gps.encode(afss.read()))
  {
    ... process gps data here
  }
}

I think that that would be more palatable to a beginner. Can you think of a situation where the callback would be preferred to this?

Thanks for the feedback.

Mikal

Mikal,

That's a much better idea, returning a boolean from the encode method is an excellent solution.