Help! GPS NMEA Parser using single cog
Juliet Oscar Echo
Posts: 31
in Propeller 1
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
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
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?
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.
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 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.