Author Topic: How to get GPS sentences to variable numbers  (Read 5932 times)

0 Members and 1 Guest are viewing this topic.

Offline acjacques

  • Newbie
  • Posts: 33
    • View Profile
How to get GPS sentences to variable numbers
« on: October 18, 2019, 12:27:32 am »
Hi friends; I am trying to make an application that will use GPS informations like SOG (Speed over Ground) that is the field  after the  7th coma. How select and convert this field that is a string to a number variable with decimals  ?  The LEN os total string is not fixed.
   
A tipical GPS sentence is like the following serial stream:

$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A   (followed by CR +LF) 

Where:
     RMC          Recommended Minimum sentence C
     123519       Fix taken at 12:35:19 UTC
     A            Status A=active or V=Void.
     4807.038,N   Latitude 48 deg 07.038' N
     01131.000,E  Longitude 11 deg 31.000' E
     022.4        Speed over the ground in knots
     084.4        Track angle in degrees True
     230394       Date - 23rd of March 1994
     003.1,W      Magnetic Variation
     *6A          The checksum data, always begins with *

There are any  code  already done  that could help me ?


Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: How to get GPS sentences to variable numbers
« Reply #1 on: October 18, 2019, 03:17:13 am »
Looks like it’s basically comma separated values.  Can’t you just use INPUT to get the data?
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #2 on: October 18, 2019, 06:17:58 am »
Probably, you're asking about the way the chain breaks into comma-separated components, right? Try this simple way.

Code: QB64: [Select]
  1. a$ = "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"
  2. a$ = a$ + "," 'add next comma for next loop:
  3.  
  4.  
  5. 'break the string by commas
  6. DO UNTIL p = _INSTRREV(a$, ",")
  7.     oldp = p
  8.     p = INSTR(p + 1, a$, ",")
  9.     PRINT "position in string:"; p,
  10.     PRINT _TRIM$(MID$(a$, oldp + 1, p - oldp - 1)) 'this is your output
  11.  
  12.  
« Last Edit: October 18, 2019, 06:31:32 am by Petr »

Offline Bert22306

  • Forum Regular
  • Posts: 206
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #3 on: October 18, 2019, 12:27:31 pm »
I think that Steve has the quickest method. Since RMC has a fixed number of data fields, if you enter it as a comma-delimited file using INPUT, then QB64 will automatically know what the individual fields are.

Something like this:

INPUT #1, Header$, UTC, Status$, Lat, NorS$, Long, EorW$, and so on. All of those input parameters will then be available to you as individual parameters. That's the beauty of NMEA 0183 format.

In short, QB64 should be able to do automatically what Petr described.

Offline acjacques

  • Newbie
  • Posts: 33
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #4 on: October 19, 2019, 02:35:50 pm »
Thanks for all comments.
But since the NMEA sentences are a stream of characters with no fixed length how capture the whole sentence  ?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #5 on: October 19, 2019, 03:12:54 pm »
CRLF$ as you said, signals the end of a sentence, once that is detected in the stream by INSTR, you have a sentence to decode.

If you have a whole page (or long string) of sentences, you can use Split to parse the page into an array of sentences using the CRLF$ characters for delimiter and use Split again to parse the fields out of each array sentence using comma as the delimiter.

Split code and demo: https://www.qb64.org/forum/index.php?topic=1607.0

But I don't know "from a stream", maybe Input #1 could do that too, it does work that way from a text file.
« Last Edit: October 19, 2019, 04:35:04 pm by bplus »

FellippeHeitor

  • Guest
Re: How to get GPS sentences to variable numbers
« Reply #6 on: October 19, 2019, 04:12:30 pm »
Thanks for all comments.
But since the NMEA sentences are a stream of characters with no fixed length how capture the whole sentence  ?

Aren’t they comma separated? There must be some separation.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #7 on: October 19, 2019, 05:33:03 pm »
There must be a defined sequence of data in the data stream as you wrote it. Does every stream start with $GPRMC? Or follow after the CR + LF? I don't know the specification of this data stream.

As you wrote:


     RMC          Recommended Minimum sentence C   -> is this STRING TYPE? How lenght? its STRING * 6? if is, then its first 6 bytes in stream,
     123519       Fix taken at 12:35:19 UTC               -> is this INTEGER or LONG numeric value? If INTEGER, so byte 7,8 is for this value, but if it is LONG type, then bytes 7 to 11 are this value,
     A            Status A=active or V=Void.                  -> is this _UNSIGNED _BYTE (or STRING * 1) type?
     4807.038                                                          -> is this SINGLE, or DOUBLE type? (4 bytes or 8 bytes)
     N   Latitude 48 deg 07.038' N                             -> STRING * 1?
     01131.000                                                        -> SINGLE or DOUBLE?
     E  Longitude 11 deg 31.000' E             
     022.4        Speed over the ground in knots
     084.4        Track angle in degrees True
     230394       Date - 23rd of March 1994
     003.1,W      Magnetic Variation
     *6A          The checksum data, always begins with *

If you find the data type in the stream, then simply follow these steps:

TYPE Stream
  RMC AS STRING * 6
  TIMEFIX AS LONG
  Status AS STRING * 1
.
.
.
END TYPE

DIM S as Stream

GET #1, ,S  (if #1 is stream channel)
« Last Edit: October 19, 2019, 05:47:06 pm by Petr »

Offline acjacques

  • Newbie
  • Posts: 33
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #8 on: October 19, 2019, 05:42:24 pm »
I need a code that deal  this "synchronizing"  byte to byte.   I am receiving  serial bytes then i need to start to "adquire" the whole GPS string only after  receive  the $
leading character and stop when receive  the CR+LF at the end.
All sentences  starts with $  and finish with CR +LF
« Last Edit: October 19, 2019, 06:03:28 pm by acjacques »

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #9 on: October 19, 2019, 06:05:08 pm »
IF program wait to dollar symbol to start, then first step is something as this (pseudocode)

TYPE Stream
 Value0 AS STRING * 1
 Value1 AS SINGLE
 Value2 AS DOUBLE
END TYPE

DIM S AS STREAM
DIM Start as STRING * 1
StreamEnd = CHR$ ( (how is ascii (CHR$) code for CR+LF?) )

OPEN Datastream FOR BINARY AS #1


DO UNTIL START = "$"
GET #1, ,START
LOOP
START = ""
GET #1, ,S 'read all values from stream at once

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #10 on: October 19, 2019, 06:18:06 pm »
Try this TYPE (without warranty):

TYPE STREAM
RMC AS STRING * 5  'If the program has already read the dollar symbol, you do not read 6 characters but 5 because the dollar symbol has already been read
FixTaken AS LONG
Status as STRING * 1
Latitude AS SINGLE  'IF NOT WORK, REWRITE IT TO DOUBLE
LatitudeS AS STRING * 1
Longitude AS SINGLE 'IF NOT WORK, REWRITE IT TO DOUBLE
LongitudeS AS STRING * 1
Speed AS SINGLE
Track AS SINGLE
Date AS LONG
Variation AS SINGLE
VariationS AS STRING * 1
Checksum AS STRING * 4
END TYPE
« Last Edit: October 19, 2019, 06:20:58 pm by Petr »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: How to get GPS sentences to variable numbers
« Reply #11 on: October 20, 2019, 12:33:04 am »
whole$ = “”: byte$ = “ “
DO
    GET #1, ,byte$
    whole$ = whole$ + byte$
LOOP UNTIL byte$ = CHR$10)
whole$ = LEFT$(whole$, LEN(whole$) - 2)


The above will get your whole string, and strip off the CRLF, which you then parse with INSTR searching the commas, and placing the values into your relevant fields.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline acjacques

  • Newbie
  • Posts: 33
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #12 on: October 20, 2019, 02:05:18 pm »
Good. 
I do not understand the
whole$ = “”: byte$ = “ “       .
Could please explain what means  the extra characters ?

Offline Bert22306

  • Forum Regular
  • Posts: 206
    • View Profile
Re: How to get GPS sentences to variable numbers
« Reply #13 on: October 20, 2019, 02:38:47 pm »
Thanks for all comments.
But since the NMEA sentences are a stream of characters with no fixed length how capture the whole sentence  ?

NMEA 0183 strings start with $, then end with <cr><lf>. The data fields end with *, and always followed by two bytes of checksum.

So, why not run a loop, starting with $ until you reach *, reading character by character, then end (i.e. exit) the loop when you reach *, then do the XOR operation on the characters (bytes) you inputted, to see if the checksum is correct?

First, call the entire NMEA sentence a$. Then you separate that input string into its individual characters:

    FOR i = 1 TO 1000
        num(i) = ASC(a$, i)
        IF num(i) = 42 THEN EXIT FOR
    NEXT i
    numChar = i

The second statement breaks up the long string a$ into its separate characters. The array num(i) is the decimal value assigned to each of the ASCII characters in the NMEA RMC sentence. You exit that FOR loop when you reach character 42, which is *.

Now you know the length of that string of characters. numChar = i. (NMEA strings are at most 82 characters long, so even if the string is not compliant, 1000 should be more than enough.)

Then the checksum:

    FOR i = 2 TO numChar - 1
        total = total XOR num(i)
    NEXT i
    totalHexInit$ = HEX$(total)
    totalHex$ = RIGHT$("00" + totalHexInit$, 2)

You have to start with the character after $, end with the characters just before *, and the checksum is two bytes wide. Now you have the computed checksum, which you can check against the checksum characters sent in the RMC sentence, after *.
« Last Edit: October 20, 2019, 09:32:57 pm by Bert22306 »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: How to get GPS sentences to variable numbers
« Reply #14 on: October 20, 2019, 02:50:07 pm »
Good. 
I do not understand the
whole$ = “”: byte$ = “ “       .
Could please explain what means  the extra characters ?

whole$ = “” — this erases whole$, in case you’ve used it before. 
byte$ = “ “ — this sets byte$ to be one character in size (CHR$(32)), so you read one byte at a time with the GET command, as you mentioned previously.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!