Shop OBEX P1 Docs P2 Docs Learn Events
Help! GPS NMEA Parser using single cog — Parallax Forums

Help! GPS NMEA Parser using single cog

I need to parse NMEA strings and I only have a single cog to do it. Ryan David has written code (search GPS NMEA Parser in the OBEX) which in theory should do it, but I can't get it to work. It's based off FullDuplexSerial. Has any one had success with this code? I'm trying to read data from a SkyTraq GPS module.

Instead of returning heading which should be some value between 0 and 360 degrees (or maybe 0 and 3600), it returns 808464432. Number of satellites, when first powering the GPS on should start at 0 and then go to a value of between 4 and 30. However, I'm getting a value starting at 12336 then increases to 12340 and 12341 (presumably 4 and 5 satellites).

I have verified the GPS module works with other code that I've used for years (GPS_Str_NMEA.spin v1.0 by I.Kövesdi which uses 3 cogs) so I know I have the GPS_Baud set up correctly. The parser probably wouldn't output any values if the GPS_Baud wasn't set up correctly since it is looking for the GGA and RMC NMEA string IDs before pulling data. I just don't understand why the numbers returned don't make sense. I have experimented with the four different modes and haven't had success there either:

'' mode bit 0 = invert rx
'' mode bit 1 = invert tx
'' mode bit 2 = open-drain/source tx
'' mode bit 3 = ignore tx echo on rx

I've also wondered if my NMEA sting from the GPS module has an extra byte added or removed. I have tried shifting the satellite bytes around in the parser. For instance, I have made them bytes g44 and g45 instead of g45 and g46. I've also shifted them the other direction by one byte. That didn't work either.

If anyone knows what the issue might be here or knows of a different GPS NMEA string parser that uses a single cog, please share. In the meantime I'll keep digging deeper.

Thanks

Comments

  • Did you check out Chris Gadd's object?

    http://obex.parallax.com/object/909
  • Doesn't FDS use it's own extra cog? If you're having to start FDS from within the parser you're now using two cogs - which you don't have.
  • Publison wrote: »
    Did you check out Chris Gadd's object?

    http://obex.parallax.com/object/909

    I'm looking at it right now. It assumes that the NMEA strings start with either "GPGGA" and "GPRMC". Mine start with either GNGGA" or "GNRMC". This breaks the code. I can't see to find where in his code I can fix this bug. Take a look and let me know your thoughts.

    You can actually test the code without a GPS/GNS module which is a great feature Chris added which I haven't seen in any other GPS/GNS code. In his GPS_generator.spin, if you change:

    'GGA_string byte "GPGGA,123456.000,3848.7563,N,12117.7583,W,1,09,1.3,79,M,-33.5,M,,0000",0
    'RMC_string byte "GPRMC,123456.000,A,3848.7563,N,12117.7583,W,1.23,336.78,180419,,,A",0

    to

    'GGA_string byte "GNGGA,123456.000,3848.7563,N,12117.7583,W,1,09,1.3,79,M,-33.5,M,,0000",0
    'RMC_string byte "GNRMC,123456.000,A,3848.7563,N,12117.7583,W,1.23,336.78,180419,,,A",0

    you'll see for yourself how the code breaks.

    It has to be a simple fix somewhere in GPS_parser.spin , but I can't seem to find it.

    Take a look and let me know if you see the fix. I'm just having a hard time wrapping my head around the large DAT block. I think the issue might be the way the code uses the checksum to determine message type:

    parse_header ' Determine message type by comparing checksum
    cmp UART_byte,#"," wz ' at first delimiter
    if_ne jmp #Main_loop
    cmp checksum,#GNRMC wz
    if_ne cmp checksum,#GNGGA wz
    if_e mov Message,checksum ' Store checksum for parser branches
    if_ne jmp #Wait_for_start ' Disregard message if not RMC or GGA
    movs parse_byte,#parse_time
    jmp #Main_loop

    Since my message headers start with GPGGA instead of GNGGA, I think it's somehow affecting the checksum.

    Thoughts?
  • I was right, it was an issue with the checksum.

    The assembly code calculates the checksum of the message header, including the first deliminator ",".

    For "GPRMC," it's $67 but for "GNRMC," it's $79.
    For "GPGGA," it's $7A but for "GNGGA," it's $64.

    I just had to change two constants in the GPS_parser.spin code.

    I really need to work more on my assembly code skills.

    Thanks to everyone who helped out.
  • Parallax have a new GPS module coming out soon, and the code for that is already in Blockly demo site:

    http://demo.blockly.parallax.com/blockly/projectlink?id=2192&key=f42bba25-5955-4a31-b3b8-3b9f1a0f4e8d

    The module also supports 3 or 4 satellite types, including GNxxx and GPxxx. Maybe it would give some clues to download the SimpleIDE project and look at the GPS libraries which include a parser.

    Not sure if that all works in 1 cog, but it might help so sharing the possibility!

  • I was right, it was an issue with the checksum.

    The assembly code calculates the checksum of the message header, including the first deliminator ",".

    For "GPRMC," it's $67 but for "GNRMC," it's $79.
    For "GPGGA," it's $7A but for "GNGGA," it's $64.

    I just had to change two constants in the GPS_parser.spin code.

    I really need to work more on my assembly code skills.

    Thanks to everyone who helped out.
    I'm glad you were able to figure it out. I figured since I was validating the checksum anyhow that that'd be a simple way to determine the message type. Simple to implement, simple to break; I didn't realize that other constellations used different headers.
    I uploaded a new version that checks the three message type characters individually, also added support for up to five decimal places in latitude and longitude, fixed the binary values for altitude, course, and speed to output value x 100, added support for the number of satellites in view, and finally quashed a bug in the date method.

    Still located here.

    Also included a lite version that only extracts to text strings.

  • @ChrisGadd Thanks for the update in OBEX. GPS stuff is always a moving target.
Sign In or Register to comment.