Parsing NMEA strings and outputting them via LCD

Hi,

I have a project i am working on and i could use some help. I am trying to take NMEA GPS sentence in via the regular usb serial interface, parse them and output them on an HD44780 display. The sentences are coming from Flight Simulator X via the fsuipc interface. This is capable of outputting the GPS data from FSX via serial, yielding something like this:

$GPGSV,2,2,08,09,25,213,49,04,23,044,49,06,17,287,49,07,05,089,49*74
$GPRMC,100313.99,A,3344.459045,N,09639.616711,W,0.0,74.9,020810,3.8,E*7A
$GPGGA,100313.99,3344.459045,N,09639.616711,W,1,05,0.0,220.9,M,0.0,M,0.0,0000*66

Each burst of data outputs those three lines.

What I'm trying to do is pull the following data out of the strings. Latitude, Longitude, heading, speed and altitude. Then i will display them in the following format on a 20 x 4 LCD display:

LAT:XXXXXXXXXXXXXXXX
LON:XXXXXXXXXXXXXXXX
SPEED:8888XXXHDG:120
ALT:1200000YYXXXXXXX

When all is done i would have created a panel mount GPS unit of sorts.

I have the LCD display part working fine but i can't seem to find a good example that would allow me to read the GPS strings via serial, parse them and get the data out of them so that i can display them on the LCD.

I would appreciate any help and i'll be glad to post the finished code when it's done so that any other flight sim enthusiast can replicate it if they so choose

There are two parts to what you want to do. The first is collecting all the input into a string. The second is parsing the string to extract meaningful bits.

The TinyGPS library would be a good starting place to learn how to do both.

Thanks for the reply PaulS,

I heard about TinyGPS and I've been fighting with it all night .... but i can't seem to get it to work. The examples are set up for reading data from a GPS device using newsoftserial and outputting the data via the serial interface. However i want it to read the data via the serial interface and output it via the LCD. problem is i can't observe what is going wrong as I'm using the serial port to send data to the arduino via a third party app (fsuipc) so i can't monitor the output at the same time. If you have any suggestions or can nudge me in the right direction i would appreciate it.

You could post your code, for a code review.

Or, you could develop the code to read and parse the GPS data in a different sketch, that would leave the serial port available for debugging purposes. Then, move the code to the current sketch when you know it works.

The only part of the code that needs debugging is the one that actively uses the serial port. Unless there is a way to have it read serial data and output at the same time, but then since it's an application is using the port i can't access it with putty or with the serial monitor.

I guess i don't fully understand the concept of serial reading and parsing so i thought that i would start first with strings and using the tinygps static string example i would work my way up to having it read via serial, storing it in a string and then having tinygps decode that string. But i wasn't sure:

  • If i could have the serial data be read line by line without it skipping any (the simulated gps unit outputs lines 3 at a time ..... even at minimums 2. i.e. one $GPRMC line and a $GPGGA line.) even then the lines may vary in length (fairly constant until you get to about 100,000 feet in the sim and over 2000 knots ..... unlikely for average simming but i don't want it breaking should i fly a space shuttle) so i can't character count to define a line of data.

  • The static example uses an array to store the gps sentences and then reads them one at a time and decodes them. The problem with that is when each string is processed, the data that is not contained in that string is filled with an invalid number i.e. 99999999999 or 100000000000 . If you were to run that example you would see that alternately the speed string would fail for GGA and then altitude will fail for RMC as that data is not contained in the string. I was wondering if there is anyway i can have both strings read then the relative data parsed from both?

While i am new to arduino programming i am a programmer and it's just taking some time to adjust to the language. a code snippet or a tutorial would be very helpful and i should be able to take it from there

Okay so i decide to go in a new direction about this. Instead of reading NMEA sentences i decided to use another program that outputs data via serial in the following format:

2618,316,109,00,2527,4

where:

  • 2618 is the altitude
  • 316 is the heading
  • 109 is the airspeed
  • 00 is the flap position in degrees
  • 2527 is the engine rpm
  • 4 is a number that just increases by 1 from 0 - 9 every second .... not sure why, but it does. No option to turn it off either.

The output from the program as observed from putty is as follows:

2618,316,109,00,2527,4
2618,316,109,00,2527,4
2619,316,109,00,2527,4
2619,316,109,00,2527,4
2619,316,109,00,2527,4
2619,316,109,00,2527,4
2619,316,109,00,2527,4
2620,316,109,00,2527,4
2620,316,109,00,2527,4
2620,316,109,00,2527,5
2620,316,109,00,2528,5
2621,316,109,00,2528,5
2621,316,109,00,2528,5
2621,316,109,00,2528,5
2621,316,109,00,2528,5
2622,316,109,00,2528,5
2622,316,109,00,2528,5
2622,316,109,00,2528,5
2623,316,109,00,2528,5
2623,316,109,00,2528,5
2623,316,109,00,2528,5
2623,316,109,00,2528,5
2624,316,109,00,2528,5
2624,316,109,00,2528,5
2624,316,109,00,2528,5
2625,316,109,00,2528,5
2625,316,109,00,2528,5
2625,316,109,00,2528,5
2626,316,109,00,2528,5
2626,316,109,00,2528,5
2626,316,109,00,2528,5
2627,316,109,00,2528,5
2627,316,109,00,2528,5
2627,316,109,00,2528,5
2628,316,109,00,2528,5
2628,316,109,00,2528,5
2629,316,109,00,2528,5
2629,316,109,00,2527,5
2629,316,109,00,2527,5
2630,316,108,00,2527,5
2630,316,108,00,2527,5
2631,316,108,00,2527,5
2631,316,108,00,2527,5
2631,316,108,00,2527,5
2632,316,108,00,2527,5
2632,316,108,00,2527,5
2633,316,108,00,2527,5
2633,316,108,00,2527,6
2633,316,108,00,2527,6
2634,316,108,00,2527,6
2634,316,108,00,2527,6
2635,316,108,00,2527,6
2635,316,108,00,2527,6
2636,316,108,00,2526,6
2636,316,108,00,2526,6
2637,316,108,00,2526,6
2637,316,108,00,2526,6
2638,316,108,00,2526,6
2638,316,108,00,2526,6
2638,316,108,00,2526,6
2639,316,108,00,2526,6
2639,316,108,00,2526,6
2640,316,108,00,2525,6

and so on if you get the idea. My question is now this:

  • how do i read a comma delimited string via serial and parse it into separate variables. Also would the strings in this case be null terminated ?
  • will an arduino be able to handle this data? (it is being sent at 115200 which i know it supports but can it take it via the usb interface from the computer as a constant stream of data?)

I think this should be an easier method as it is just comma separated numbers but once again i'm new to arduino serial communication so ... yeah