Reputation: 41
I have a GPS gadget, and I would like to know how I can receive information with C++ (coordinates) from it?
Upvotes: 0
Views: 2763
Reputation: 490108
This is probably easier to answer than the comments indicate. While most GPS units do support proprietary (usually) binary protocols, nearly all that are even close to current also support NMEA-formatted data, and will supply it by default. Whether connected by serial port, bluetooth or USB, most also look to user programs like a serial port.
IOW, you can probably support something like 90% of reasonably current GPS units simply by opening a serial port, and reading data from it. The only ugly part is that the NMEA standard for the data format is fairly expensive (though it's not as bad as it used to be -- you can now buy just the parts of it you care about, which is to say only appendix B, IIRC).
Fortunately, unless you're planning to get your software certified for marine or aircraft navigation, you probably don't need that -- there are a fair number of web sites that cover the (few) message types you probably care about. For that matter, if you just open up a terminal program on the right COM port and look at the data, it's not too hard to find the latitude/longitude all by yourself (at least if you have at least a vague notion of where you are).
It's basically CSV format -- one record per line, with fields separated by commas. It's all in normal ASCII/ANSI text, so getting coordinates is mostly a matter of checking that the first field says it's the right kind of record ("$GPGGA"), then getting fields 3, 4 5, and 6 (3 and 4 are latitude and 5 and 6 longitude -- 3 and 5 give the number, 4 and 6 have "N", or "S" and "E" or "W" to indicate north/south latitude and East/West longitude). You'll probably also want to check that the field after that contains "1" or "2", indicating a normal or Differential GPS fix respectively (a "0" would indicate no GPS fix, so invalid data).
Not that it matters a lot, but you should probably also realize that there are several other field types you'll probably receive, and some of them contain fix data as well. $GPGGA just happens to be the one I've used -- there are others that are probably just as good, but I've never had much reason to look at others, because that one's been adequate for what I needed/did.
Edit: Here's a sample dump of data exactly as it's received from the GPS, in this case over a Bluetooth virtual serial port:
$GPGGA,090809.103,3901.4345,N,10448.2482,W,0,00,50.0,2078.2,M,-21.4,M,0.0,0000*43 $GPRMC,090809.103,V,3901.4345,N,10448.2482,W,0.00,0.00,220311,,*07 $GPVTG,0.00,T,,M,0.00,N,0.0,K*60 $GPGGA,090810.103,3901.4345,N,10448.2482,W,0,00,50.0,2078.2,M,-21.4,M,0.0,0000*4B
In the second $GPGGA record:
$GPGGA,090810.103,3901.4345,N,10448.2482,W,0,00,50.0,2078.2,M,-21.4,M,0.0,0000*4B
"$GPGGA" is the record ("Sentence") type identifier.
"090810.103" is the current UTC time.
"3901.4345,N" is the latitude.
"10448.2482,W" is the longitude.
The next: "0" is telling you that the preceding latitude/longitude are not valid.
The latitude and longitude are both formatted (IIRC) with the last two places before the decimal point being the minutes, and what's after the decimal point the fractions of a minute, so the `3901.4345" really means 39º 1.4345' north latitude.
Upvotes: 5