Go Down

Topic: How can I print GPS data in one line? (Read 209 times) previous topic - next topic

coding1227

Hi fellow Arduinoers!

I have a quick question for you. I am starting to play around with a Parallax GPS, and I would like to print only one line (instead of a bunch of lines). Right now, I am using the code attached below (based on the info from http://playground.arduino.cc/Tutorials/GPS) and I get this output in my PC's serial out:

$GPGGA,212637.000,2218.2591,N,15750.3783,W,1,05,4.2,40.1,M,4.7W,0.00,193.78,170913,,,A*7A
$GPGGA,212638.000,2218.2591,N,15750.3783,W,1,05,4.2,40.1,M,4.7,M,,0000*4B
$GPGSA,A,3,29,12,02,25,05,,,,,,,,5.6,4.2,3.7*3B
$GPRMC,212638.000,A,2218.2591,N,15750.3783,W,0.00,193.78,170913,,,A*75
Time in UTC (HhMmSs): 212638.000
Status (A=OK,V=KO): A
Latitude: 2218.2591
Direction (N/S): N
Longitude: 15750.3783
Direction (E/W): W
Velocity in knots: 0.00
Heading in degrees: 193.78
Date UTC (DdMmAa): 170913
Magnetic degrees:
(E/W):
Mode: A

My question is: what would I need to change in the code in order to only print the line that starts with "$GPRMC"?

Thanks in advance,

     Luc

Code: [Select]

#include <string.h>
#include <ctype.h>

int ledPin = 13;                  // LED test pin
int rxPin = 0;                    // RX PIN
int txPin = 1;                    // TX TX
int byteGPS=-1;
char linea[300] = "";
char comandoGPR[7] = "$GPRMC";
int cont=0;
int bien=0;
int conta=0;
int indices[13];

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

void loop() {
   digitalWrite(ledPin, HIGH);
   byteGPS=Serial.read();         // Read a byte of the serial port
   if (byteGPS == -1) {           // See if the port is empty yet
     delay(100);
   } else {
     // note: there is a potential buffer overflow here!
     linea[conta]=byteGPS;        // If there is serial port data, it is put in the buffer
     conta++;                     
     Serial.write(byteGPS);
     if (byteGPS==13){            // If the received byte is = to 13, end of transmission
       // note: the actual end of transmission is <CR><LF> (i.e. 0x13 0x10)
       digitalWrite(ledPin, LOW);
       cont=0;
       bien=0;
       // The following for loop starts at 1, because this code is clowny and the first byte is the <LF> (0x10) from the previous transmission.
       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
             // note: again, there is a potential buffer overflow here!
             indices[cont]=i;
             cont++;
           }
           if (linea[i]=='*'){    // ... and the "*"
             indices[12]=i;
             cont++;
           }
         }
         Serial.println("");      // ... and write to the serial port
         Serial.println("");
         Serial.println("---------------");
         for (int i=0;i<12;i++){
           switch(i){
             case 0 :Serial.print("Time in UTC (HhMmSs): ");break;
             case 1 :Serial.print("Status (A=OK,V=KO): ");break;
             case 2 :Serial.print("Latitude: ");break;
             case 3 :Serial.print("Direction (N/S): ");break;
             case 4 :Serial.print("Longitude: ");break;
             case 5 :Serial.print("Direction (E/W): ");break;
             case 6 :Serial.print("Velocity in knots: ");break;
             case 7 :Serial.print("Heading in degrees: ");break;
             case 8 :Serial.print("Date UTC (DdMmAa): ");break;
             case 9 :Serial.print("Magnetic degrees: ");break;
             case 10 :Serial.print("(E/W): ");break;
             case 11 :Serial.print("Mode: ");break;
             case 12 :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]=' ';             

       }                 
     }
   }
}

PeterH


My question is: what would I need to change in the code in order to only print the line that starts with "$GPRMC"?


Most of it.

The serial port handling is pretty nasty - the code doesn't check for data available before reading it and doesn't have buffer overflow protection. Bizarrely, it seems to be using the hardware serial UART both for receiving the GPS input and for sending output to (presumably) the PC. Just how have you got the PC and GPS unit connected to the Arduino?

Additionally, I'm not convinced that sketch produced the output you quoted since the sketch prints a burst line ("---------------") which is not present in your sample output.
I only provide help via the forum - please do not contact me for private consultancy.

Cyric

#2
Sep 18, 2013, 01:15 am Last Edit: Sep 18, 2013, 01:19 am by Cyric Reason: 1
lamers GPS lib is great and works for parsing GPRMC even has special functions for it.
GPRMC Routines

These routines provide easy access to 'GPRMC' type sentences. GPRMC type sentences are available from every GPS receiver, and for most applications they provide all the data you need. For example, they contain your exact position, speed, and direction of movement. For most projects, or if you are new to dealing with GPS data, these routines are all you need.

http://www.maartenlamers.com/nmea/

you can even make the lib only show them or all the sentences plus it has many functions other libs do not have.

as an after though i remember TinyGps did ok also.
http://arduiniana.org/libraries/tinygps/

alnath

#3
Sep 18, 2013, 01:41 am Last Edit: Sep 18, 2013, 02:14 am by alnath Reason: 1
agreed with the previous answers, but given the results you have, if you remove the line
Serial.write(byteGPS);
in
Code: [Select]
    conta++;                      
//    Serial.write(byteGPS);
    if (byteGPS==13){            // If the received byte is = to 13, end of transmission


all the lines before the really wanted datas shouldn't be printed.
If you want the line $GPRMC..... to be printed, just add
Serial.println(linea);
here :
Code: [Select]
     
if(bien==6){               // If yes, continue and process the data
        Serial.println(linea);
        for (int i=0;i<300;i++){
          if (linea[i]==','){    // check for the position of the  "," separator


not tested, but that should work.

zoomkat

There is a library called textfinder that might do what you want to do.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Go Up