GPS/Parsing/Storing help

Greetings,
I'm new to the arduino world and need a nudge in the right direction.

I'm building a custom autopilot (marine)

I'm reading and parsing NMEA sentences from a Garmin chartplotter

I have modified the code I found here:
http://www.arduino.cc/playground/Tutorials/GPS
Credit
Igor Gonz[ch65533]lez Mart[ch65533]n. 05-04-2007
igor.gonzalez.martin@gmail.com

English translation by djmatic 19-05-2007

I changed:
char comandoGPR[7] = "$GPRMC";

To:
char comandoGPR[7] = "$GPRMB";

And changed to code to get a nice output:
$GPRMB,A,0.00,L,,JOHNS-PASS,2746.6550,N,08247.4703,W,**.656,**6.1,,V,A*00


Status(A=OK,V=KO): A
Cross-track error: 0.00
Turn: L
null:
Waypoint: JOHNS-PASS
Destination Lat: 2746.6550
Destination Lat: N
Destination Long: 08247.4703
Destination Long: W
Range to Dest: **.656 not far :)
Bearing to Dest: **6.1 in that direction :)
Velocity:
v: V
n: A

How do I store these values and call them up elsewhere in my code?

I want to read these and store them in variables. display them on an LCD and run procedures for steering based on "cross track" and "turn"

Any sugestions would be great!

Road

youll need to check the interfacing page. gl

Check the TinyGPS library.

-j

Thanks for the response,
I looked at TinyGPS, but it's farther from where I was :slight_smile:

I am a total novice to the code...

I am reading the GPMRB sentence Tiny doesn't seem to
Here is the code i used to produce the output:

#include <NewSoftSerial.h>
 NewSoftSerial mySerial =  NewSoftSerial(5, 6);
 #include <string.h>
 #include <ctype.h>
 //input from gps
 int ledPin = 13;                  // LED test pin
 int rxPin = 2;                    // RX PIN 
 int txPin = 3;                    // TX TX
 int byteGPS=-1;
 char linea[300] = "";
 char comandoGPR[7] = "$GPRMB";
 int cont=0;                            //buffer
 int bien=0;
 int conta=0;
 int indices[15];

 void setup() {
   pinMode(ledPin, OUTPUT);       // Initialize LED pin
   pinMode(rxPin, INPUT);
   pinMode(txPin, OUTPUT);
  
   Serial.begin(4800);
   mySerial.begin(4800);
   for (int i=0;i<300;i++){       // Initialize a buffer for received data
     linea[i]=' ';
   }   
 }

 void loop() {
   digitalWrite(ledPin, HIGH);
   byteGPS=mySerial.read();         // Read a byte of the serial port
   if (byteGPS == -1) {           // See if the port is empty yet
     delay(100); 
   } else {
     linea[conta]=byteGPS;        // If there is serial port data, it is put in the buffer
     conta++;                      
     Serial.print(byteGPS, BYTE); 
     if (byteGPS==13){            // If the received byte is = to 13, end of transmission
       digitalWrite(ledPin, LOW); 
       cont=0;
       bien=0;
       for (int i=1;i<7;i++){     // Verifies if the received command starts with $GPR
         if (linea[i]==comandoGPR[i-1]){
           bien++;
         }
       }
       if(bien==6){               // If yes, continue and process the data
         for (int i=0;i<300;i++){
           if (linea[i]==','){    // check for the position of the  "," separator
             indices[cont]=i;
             cont++;
           }
           if (linea[i]=='*'){    // ... and the "*"
             indices[14]=i;
             cont++;
           }
         }
         Serial.println("");      // ... and write to the serial port
         Serial.println("");
         Serial.println("---------------");
         for (int i=0;i<14;i++){
           switch(i){
             case 0 :Serial.print("Status(A=OK,V=KO): ");break;
             case 1 :Serial.print("Cross-track error: ");break;
             case 2 :Serial.print("Turn: ");break;
             case 3 :Serial.print("null: ");break;
             case 4 :Serial.print("Waypoint: ");break;
             case 5 :Serial.print("Destination Lat: ");break;
             case 6 :Serial.print("Destination Lat: ");break;
             case 7 :Serial.print("Destination Long: ");break;
             case 8 :Serial.print("Destination Long: ");break;
             case 9 :Serial.print("Range to Dest: ");break;
             case 10 :Serial.print("Bearing to Dest: ");break;
             case 11 :Serial.print("Velocity:    ");break;
             case 12 :Serial.print("v: ");break;
             case 13 :Serial.print("n: ");break;
             //case 14 :Serial.print("Checksum: ");break;
           }
           for (int j=indices[i];j<(indices[i+1]-1);j++){
             Serial.print(linea[j+1]); 
           }
           Serial.println("");
         }
         Serial.println("---------------");
       }
       conta=0;                    // Reset the buffer
       for (int i=0;i<300;i++){    //  
         linea[i]=' ';             
       }                 
     }
   }
 }

I believe the values I am after are in one of these variables but I can't figure out where :-/ Can't they be dumped into variables the same as they are printed??

Here's what I use. It only parses the info from the GGA sentence, so may not have everything you need out-of-the-box. It is a good example though of how to parse a GPS sentence - you can adapt it for whatever sentence you need.

It is VERY heavily based on the Ardupilot code.

void altitude2_parse(void){
  char *token;
  const char delimiters[] = "$,";
  token = strtok_r(altitude_buffer, delimiters, &brkb);//GPGGA header, not used anymore
  token = strtok_r(NULL, delimiters, &brkb);//UTC

  //Longitude in degrees, decimal minutes. (ej. 4750.1234 degrees decimal minutes = 47.835390 decimal degrees)
  //Where 47 are degrees and 50 the minutes and .1234 the decimals of the minutes.
  //To convert to decimal degrees, devide the minutes by 60 (including decimals), 
  //Example: "50.1234/60=.835390", then add the degrees, ex: "47+.835390=47.835390" decimal degrees
  token = strtok_r(NULL, delimiters, &brkb); //Contains Latitude in degrees decimal minutes... 

  //taking only degrees, and minutes without decimals, 
  //strtol stop parsing till reach the decimal point "."  result example 4750, eliminates .1234
  temp=strtol (token,&pEnd,10);

  //takes only the decimals of the minutes
  //result example 1234. 
  temp2=strtol (pEnd+1,NULL,10);

  //joining degrees, minutes, and the decimals of minute, now without the point...
  //Before was 4750.1234, now the result example is 47501234...
  temp3=(temp*10000)+(temp2);


  //modulo to leave only the decimal minutes, eliminating only the degrees.. 
  //Before was 47501234, the result example is 501234.
  temp3=temp3%1000000;


  //Dividing to obtain only the de degrees, before was 4750 
  //The result example is 47 (4750/100=47)
  temp/=100;

  //Joining everything and converting to float variable... 
  //First i convert the decimal minutes to degrees decimals stored in "temp3", example: 501234/600000= .835390
  //Then i add the degrees stored in "temp" and add the result from the first step, example 47+.835390=47.835390 
  //The result is stored in "lat" variable... 
  lat=temp+((float)temp3/600000);


  token = strtok_r(NULL, delimiters, &brkb); //lat, north or south?
  //If the char is equal to S (south), multiply the result by -1.. 
  if(*token=='S'){
    lat=lat*-1;
  }

  //This the same procedure use in lat, but now for Lon....
  token = strtok_r(NULL, delimiters, &brkb);
  temp=strtol (token,&pEnd,10); 
  temp2=strtol (pEnd+1,NULL,10); 
  temp3=(temp*10000)+(temp2);
  temp3=temp3%1000000; 
  temp/=100;
  lon=temp+((float)temp3/600000);

  token = strtok_r(NULL, delimiters, &brkb); //lon, east or west?
  if(*token=='W'){
    lon=lon*-1;
  }
  token = strtok_r(NULL, delimiters, &brkb);//Position fix
  fix_quality = atoi(token);
  token = strtok_r(NULL, delimiters, &brkb); //
  token = strtok_r(NULL, delimiters, &brkb);//HDOP
  token = strtok_r(NULL, delimiters, &brkb);//ALTITUDE
  altitude=atoi(token);
  
}

Can't they be dumped into variables the same as they are printed??

From your code, removing anything that doesn't involve printing, or that only prints literal strings, this is what's left:

     Serial.print(byteGPS, BYTE);

and:

           for (int j=indices[i];j<(indices[i+1]-1);j++){
             Serial.print(linea[j+1]);
           }

The stuff you want is ALREADY in variables. It's up to you to recognize that, and to parse the relevant bits that you want.