Instructables

Step 3: My GPS program

Picture of My GPS program
I am not going to try to teach anyone how to write programs in Visual Express. My program is an example of how you can customize GPS software for your only needs. 
What I will cover are some of the problems and solutions in general terms.

Program Goals:
Talk to GPS and sample GPS data.
Display latitude, longitude, altitude.
Calculate a running average of the above.

Stage 2: I wanted to see how accurate my GPS was. See next step.

Problem: Talk to GPS. The BU-353 is a USB device. It receives +5V on the USB connection. One of the nice features is that once it has power, it starts sending out NMEA 0183 serial data at 4800 baud automatically every second.
Solution: So VB Express already has a control called Serialport. Set it to 4800 baud, set it to the correct Com number and open it.

Problem: Sample GPS data. If you have a way to look at the serial data from the BU-353, one line would be something like this:
$GPGGA,233632.000,3913.9963,N,10844.2590,W,2,09,0.9,1424.3,M,-16.7,M,0.8,0000*79

Here is how the NMEA 0183 defines this:
GGA - essential fix data which provide 3D location and accuracy data.
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

Where:
GGA Global Positioning System Fix Data
  123519             Fix taken at 12:35:19 UTC(Coordinated Universal Time)
  4807.038,N     Latitude 48 deg 07.038' N
  01131.000,E   Longitude 11 deg 31.000' E
  1                        Fix quality: 0 = invalid
                                 1 = GPS fix (SPS)
                                 2 = DGPS fix (This means WAAS is enabled and working)
  08                     Number of satellites being tracked
  0.9                    Horizontal dilution of position(Something to do with accuracy)
  545.4,M           Altitude, Meters, above mean sea level
  46.9,M             Height of geoid (mean sea level) above WGS84 ellipsoid
  (empty field)   time in seconds since last DGPS update
  (empty field)   DGPS station ID number
  *47                  the checksum data, always begins with *

Tip: I just learned something about latitude and longitude. Latitude can only go from 0 to 90; longitude can go from 0 to 180. That is why the latitude value above has four digits before the decimal and the longitude has five. In the above example 11 degrees is written 011.

NMEA 0183 protocols are defined all over the Internet. Here’s one:
http://biostatmatt.com/uploads/DescriptionNMEA.pdf
This protocol is not just for GPS so not all of the Sentences are relevant.

SubproblemA: The BU-353 is sending out several data strings every second. The computer program is receiving the serial data stream but doesn’t know where it ‘starts.’ (This is called asynchronous communications).
SolutionA: What the program has to do is continually look at the stream of data until it sees “$GPGGA”, then it knows the relevant data will follow.

SubproblemB: The $GPGGA data is one line of data. The computer needs to separate the data into the different parts.
SolutionB: In programming language, this is called parsing. The NMEA protocol has pretty strict rules on how the strings are defined. Every element is in a specified position and separated with a comma. So the program has to go through the data and extract what it wants and ignore the rest. For my purposes, I read down to Altitude and skipped the rest of the line.
FYI: The checksum is a means of verifying if the data string is corrupted or intact. In general, if you get corrupted data, it will usually be unreadable anyway. I just ignore checksums.

Problem: Display latitude, longitude, altitude. At this point, all of the data is in characters. It could simply be displayed in textboxes. But for my purposes, there are two problems. One is computers are dumb, they can’t average characters, they have to use numbers. I use a number of type ‘double’ which means it can include a decimal point, like 545.4. The second problem is that latitude and longitude are entered in the format of degrees and minutes in one number. 4807.038 is 48 deg 07.038' . Computers are dumb they can’t understand this.

Don't worry if the following doesn't make sense to you.
Solution: Most programming languages have a way to convert characters to a double. In VB express I used this:
dLat = Convert.ToDouble(lineArr(2))

Converting that latitude number is a little trickier, I did this
degrees = Int(dLat / 100)         //This takes the first two digits and converts them to an                                                                          integer (number without a decimal)
decimaldegrees = (dLat - (100 * degrees)) / 60.0         // This takes original number,
                                                                                                    subtracts the degrees portion and
                                                                                                    converts it to a decimal
fullLat = degrees + decimaldegrees     //This combines the two

E.g. if dLat = 4807.038
degrees = Int(4807.038 / 100)
degrees = Int(48.07038)
degrees = 48

decimaldegrees = (dLat - (100 * degrees)) / 60.0
decimaldegrees = (4807.038 - (100 * 48)) / 60.0
decimaldegrees = (4807.038 - (4800)) / 60.0
decimaldegrees = (7.038) / 60.0
decimaldegrees = 0.1173

fullLat = degrees + decimaldegrees
fullLat = 48 + 0.1173
fullLat = 48.1173

So isn’t programming fun? NO! It’s not! The good news is once you get the program right, the computer will do all the calculations effortlessly. The bad news is if the program (algorithm) is wrong, it will do it wrong effortlessly. Since I’m not nearly perfect, I have to do a lot of troubleshooting.

Map Location: I copied this feature from another programmer (I wish I remembered where I found it). If you have an Internet connection and a good CPU, pressing this button will open up Google Maps and display your GPS location. This isn't very useful to me. If I'm using my Pentium III laptop  in my car, it is too slow to display this and I usually don't have internet connection on the road anyway.

Problem: Calculate a running average of the above.
Solution: This is relatively easy, just keeping adding the values together and divide by the number of samples.
 
I have included two versions of my software.

To use the first, publish.zip, you need an internet connection. (I haven’t tested this) Save the zip file to your computer, run setup.exe. If this works the way it use to, it will download all the support files and install the program. You should be able to use this with any USB GPS that supports NMEA 0183 protocols.
The second version, Michaels GPS.zip contains all of the source code. I would suggest installing Microsoft Visual Basic Express 2010 first, then copying my files into the Project directory. Mine looks something like this:
\\MICHAEL-PC\Users\Michael\Documents\Visual Studio 2010\Projects\

The executable is under the project name, down a few directories . . . \bin\release. Theoretically, you can run the .exe file. The reason I suggested installing Microsoft Visual Basic Express 2010, is that it installs all the .NET stuff needed by the program. If that doesn’t work, you can also start of VB express and open the project and run it.
 
Setup: Enter the correct Comm port for your USB GPS. Click on Update. The data should start updating. If you get an error, Stop Updates and Update again.

 
Remove these adsRemove these ads by Signing Up
gavinzac4 years ago
With regard to the 'Map Location' issue:

You could use, or provide an option to use Open Street Map ( www.openstreetmap.org ) which is free, non-royalty, usually very accurate (and very easily editable and fixable if not) and most importantly: downloadable. The program could download all maps in a 100+ mile radius and the user is then unlikely to wander out of this zone before he has to download it. I'm guessing it could do 1000+ miles pretty easily to reduce the frequency of this.
msuzuki777 (author)  gavinzac4 years ago
Thanks, I've never heard of Open Street Map but just started looking at it. I like the downloadable maps and will look into tying into my program. I did find some information on how it can read in GPX files. My program doesn't generate GPX and I'm only vaguely familiar with them but I will look into this.

Thanks again,

LOG