serial.write output GPS sentence formation and concatenation

I am trying to append a preamble to a GPS serial sentence for use by a GPS position tool called GooPs.

The GooPs FAQ for doing this:

http://goopstechnologies.com/?page_id=20#How_do_I_interface_my_application_to

suggests that I need to format the sentences with a NMEA string that is is prepended with an ID and host name

ie "joe@joescar:" such that the serial output looks like this:

joe@joescar:$GPRMC,130043,A,3731.5300,N,12221.2400,W,1.0,0.0,082507,0.0,E,A*01

When I run the attached code my output to the serial monitor is:

joe@joescar:
$GPRMC,061019.000,A,3401.8522,N,11708.9977,W,0.10,90.53,221017,,,D*4B

The problem is that GooPs appears to not parse the line fees after "joe@joescar:"

My question is, How do I write the commands to concatenate or format the strings/sentances to output everything on one line be=fore the CR/LF?

Thanks in advance.

GPS_Tracket_toptechboy.com_LESSON22_PDS_21Oct17_v1a.ino (3.01 KB)

larosta:
How do I write the commands to concatenate or format the strings/sentances to output everything on one line be=fore the CR/LF?

Try a Google search on;

'Arduino how to concatenate strings'

Should be some tips there.

The obvious cause of such a problem would be the use of Serial.println() where Serial.print() would be appropriate.

I agree that Serial.print(); should be the solution buthwhen I implement it the “joe@joescar:” has a line feed (cr) at the end when I look at the output in the serial monitor.

larosta

  Serial.print(System_ID);
  Serial.println(NMEA2);
  Serial.println("");

Maybe the text that is generated by NMEA2=GPS.lastNMEA(); has a CR/LF at the start of the text?

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R

I have an application that I need to send GPS data over a wireless link (XBee) to a laptop running a Google Earth overlay software package called GooPs (http://goopstechnologies.com/). This software allows the use of a via a TCP/IP socket to allow the user to select and connect to several different data sources and display their data.

The format that it uses for the incoming data is:

@:

Example:
joe@joescar:$GPRMC,130043,A,3731.5300,N,12221.2400,W,1.0,0.0,082507,0.0,E,A*01

More information can be found in the FAQ here:

http://goopstechnologies.com/?page_id=20#How_do_I_Add_a_remote_vehicle

I have generated a sketch that almost gets me to a solution (attached).

The problem is that it appears that there is a in the data stream that causes GooPs to not properly parse the GPS data that follows the @:

Here is an example of what I see on a terminal program connected to the output of the ARDUINO UNO:

joe@joescar:$GPGGA,165007.000,3401.8519,N,10429.0035,W,2,10,0.87,569.6,M,-32.5,M,0000,000058
joe@joescar:$GPRMC,165007.000,A,3401.8519,N,10429.0035,W,0.15,226.19,231017,,,D
7B

Here is what I would like it to be:

joe@joescar:$GPGGA,165007.000,3401.8519,N,10429.0035,W,2,10,0.87,569.6,M,-32.5,M,0000,000058
joe@joescar:$GPRMC,165007.000,A,3401.8519,N,10429.0035,W,0.15,226.19,231017,,,D
7B

I have tried putting the data in an array and using remove to eliminate the before sending it out and that did not work. I have tried using the standard Serial.println() and Serial.print() without sucess.

Any assistance or observations will be greatly appreciated.

GPS_Tracker_for_Goops_23Oct17_v1c.ino (3.03 KB)

There is no magic. If a line feed is being sent, it is because YOUR code is explicitly asking for one to be sent. Since you didn't post your code, there is no way anyone here can help you...

Regards,
Ray L.

Why have you started a new thread when you already have one going
http://forum.arduino.cc/index.php?topic=506987.msg3456257#msg3456257

@larosta, do not cross-post. Threads merged.

Ray,

I thought the the code was attached as "GPS_Tracker_for_Goops_23Oct17_v1c.ico"

Just in case, here it is inline:

// Program to receive GPS data from Adafruit Ultimate GPS receiver and format it for output on a serial radio link
// ie XBee to a receiving station running GooPs GPS tracking software (http://goopstechnologies.com/)
//
// Project is intended to allow a user at a central location to locate several vehicles equipped with GPS receivers.

//Make sure to install the adafruit GPS library from GitHub - adafruit/Adafruit_GPS: An interrupt-based GPS Arduino library for no-parsing-required use
//template inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }

#include <Adafruit_GPS.h> //Load the GPS Library. Make sure you have installed the library form the adafruit site above
#include <SoftwareSerial.h> //Load the Software Serial Library. This library in effect gives the arduino additional serial ports
#include <Streaming.h>

SoftwareSerial mySerial(3, 2); //Initialize SoftwareSerial, and tell it you will be connecting through pins 2 and 3
Adafruit_GPS GPS(&mySerial); //Create GPS object

String NMEA1; //We will use this variable to hold our first NMEA sentence
String NMEA2; //We will use this variable to hold our second NMEA sentence

// const char Veh_ID[] = "joe@joescar:";

String Veh_ID = "joe@joescar:";

char c; //Used to read the characters spewing from the GPS module

void setup() {
Serial.begin(9600); //Turn on the Serial Monitor
GPS.begin(9600); //Turn GPS on at baud rate of 9600
GPS.sendCommand("$PGCMD,33,0*6D"); // Turn Off GPS Antenna Update
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //Tell GPS we want only $GPRMC and $GPGGA NMEA sentences
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
delay(1000); //Pause
}

void loop() // run over and over again
{
readGPS(); //This is a function we define below which reads two NMEA sentences from GPS
}

void readGPS(){ //This function will read and remember two NMEA sentences from GPS
clearGPS(); //Serial port probably has old or corrupt data, so begin by clearing it all out

// Get first NMEA data sentance
while(!GPS.newNMEAreceived()) { //Keep reading characters in this loop until a good NMEA sentence is received
c = GPS.read(); //read a character from the GPS
}

GPS.parse(GPS.lastNMEA()); //Once you get a good NMEA, parse it

NMEA1 = GPS.lastNMEA(); //Once parsed, save NMEA sentence into NMEA1

// Get second NMEA data sentance
while(!GPS.newNMEAreceived()) { //Go out and get the second NMEA sentence, should be different type than the first one read above.
c = GPS.read();
}

GPS.parse(GPS.lastNMEA());

NMEA2 = GPS.lastNMEA();

// Send Vehicle ID and NEMA data out of serail port
Serial << Veh_ID << NMEA1 << "\n";
Serial << Veh_ID << NMEA2 << "\n";
}

void clearGPS() { //Since between GPS reads, we still have data streaming in, we need to clear the old data by reading a few sentences, and discarding these
while(!GPS.newNMEAreceived()) {
c = GPS.read();
}

GPS.parse(GPS.lastNMEA());

while(!GPS.newNMEAreceived()) {
c = GPS.read();
}

GPS.parse(GPS.lastNMEA());

}

I have looked at the output of the GPS receiver using a logic analyzer and do not see the in the serial data.

It appears the there is something I am missing about how the Serial IO libraries format the data for output> I just do not see what it could be.

-larosta

larosta:
It appears the there is something I am missing

There sure is. Read How to use the Forum

And you have had a few suggestions already but you have not bothered to respond to any of them.

...R

Robin,

I believe that if you take the time to look at the messages from -larosta you will find several postings with additional information. I do not believe that a search the forums and read the documentation require a response. I get that and believe me I have spent a lot of time searching the available data, trying methods I found there, and reviewing documentation both on-line and printed. I do get the fact that these forums are only as good as the information provided and in that spirit I have tried to update the thread as I have progressed through a situation. That said, I came here in an attempt to find a some knowledgeable help on the subject from experienced subject matter experts solution not be criticized.

-larosta

  // Send Vehicle ID and NEMA data out of serail port
  Serial << Veh_ID << NMEA1 << "\n";
  Serial << Veh_ID << NMEA2 << "\n";

Do you know EXACTLY what the << operator is doing? If not, quit being lazy. Typing 2 Serial.print() statements and 2 Serial.println() statements ONCE is not going to wear your fingers out.

PaulS,

I started this project with the more familiar Serial.print(); and Serial.println(); statements. That is where I realized that there was a problem. When I use this method I get the same output that I get with the

Serial << Veh_ID << NMEA1 << "\n";

I think that I do understand how it is overloaded and found the technique here in the forum in a posting that appeared to be well vetted.

Just to make sure that Serial.print(); works. Here is a version of the code using that as a method:

// Program to receive GPS data from Adafruit Ultimate GPS receiver and format it for output on a serial radio link
// ie XBee to a receiving station running GooPs GPS tracking software (http://goopstechnologies.com/)
//
// Project is intended to allow a user at a central location to locate several vehicles equipped with GPS receivers.

//Make sure to install the adafruit GPS library from GitHub - adafruit/Adafruit_GPS: An interrupt-based GPS Arduino library for no-parsing-required use
//template inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }

#include <Adafruit_GPS.h> //Load the GPS Library. Make sure you have installed the library form the adafruit site above
#include <SoftwareSerial.h> //Load the Software Serial Library. This library in effect gives the arduino additional serial ports
#include <Streaming.h>

// GPS Baud Rate is 9600
#define GPSBAUD 9600
#define RXPIN 3
#define TXPIN 2

SoftwareSerial mySerial(RXPIN, TXPIN); //Initialize SoftwareSerial, and tell it you will be connecting through pins 2 and 3

Adafruit_GPS GPS(&mySerial); //Create GPS object

String NMEA1; //We will use this variable to hold our first NMEA sentence
String NMEA2; //We will use this variable to hold our second NMEA sentence

const char Veh_ID[] = "joe@joescar:";

// const String Veh_ID = "joe@joescar:";

char c; //Used to read the characters spewing from the GPS module

void setup() {
Serial.begin(9600); //Turn on the Serial Monitor
GPS.begin(9600); //Turn GPS on at baud rate of 9600
GPS.sendCommand("$PGCMD,33,0*6D"); // Turn Off GPS Antenna Update
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //Tell GPS we want only $GPRMC and $GPGGA NMEA sentences
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
delay(1000); //Pause
}

void loop() // run over and over again
{
readGPS(); //This is a function we define below which reads two NMEA sentences from GPS
}

void readGPS(){ //This function will read and remember two NMEA sentences from GPS
clearGPS(); //Serial port probably has old or corrupt data, so begin by clearing it all out

// Get first NMEA data sentance
while(!GPS.newNMEAreceived()) { //Keep reading characters in this loop until a good NMEA sentence is received
c = GPS.read(); //read a character from the GPS
}

GPS.parse(GPS.lastNMEA()); //Once you get a good NMEA, parse it

NMEA1 = GPS.lastNMEA(); //Once parsed, save NMEA sentence into NMEA1

// Get second NMEA data sentance
while(!GPS.newNMEAreceived()) { //Go out and get the second NMEA sentence, should be different type than the first one read above.
c = GPS.read();
}

GPS.parse(GPS.lastNMEA());

NMEA2 = GPS.lastNMEA();

// Send Vehicle ID and NEMA data out of serail port
// Serial << Veh_ID;
// Serial << Veh_ID << NMEA1 << "\n";
// Serial << Veh_ID << NMEA2 << "\n";

// Serial << Veh_ID << NMEA1;
// Serial << Veh_ID << NMEA2;

// Serial << NMEA1;
// Serial << NMEA2;

// Serial << "joe@joescar" << NMEA1;

Serial.print(Veh_ID);
Serial.print(NMEA1);
Serial.println();
Serial.print(Veh_ID);
Serial.print(NMEA2);
Serial.println();

// Serial << "joe@joescar" << NMEA2;

}

void clearGPS() { //Since between GPS reads, we still have data streaming in, we need to clear the old data by reading a few sentences, and discarding these
while(!GPS.newNMEAreceived()) {
c = GPS.read();
}

GPS.parse(GPS.lastNMEA());

while(!GPS.newNMEAreceived()) {
c = GPS.read();
}

GPS.parse(GPS.lastNMEA());

}

Since you seem to think that you get a line feed added to the output of the Veh_ID string, why don't you shit-can all the code that gets data from the GPS and PROVE that the line-feed is being mysteriously added.

const char Veh_ID[] = "joe@joescar:";

void setup()
{
   Serial.begin(9600);  //Turn on the Serial Monitor (Actually that is NOT what that statement does)
   Serial.print("Veh_ID: [");
   Serial.print(Veh_ID);
   Serial.print("]");
}

void loop()
{
}

If you get

Veh_ID: [joe@joescar:]

the linefeed is coming from the way you manage the GPS data.

If you get

Veh_ID: [joe@joescar:
]

the problem is with whatever you are sending the data to.

Which problem are we trying to solve?

I believe that I have the problem resolved. Thunks to all of the folks that took the time to assist and provide their insightful and knowledgeable recommendations. I cannot believe the depth of knowledge and experience I have found on this forum. Thanks again.

I believe that I have the problem resolved.

What was the cause of the problem and how did you resolve it ?

Formatting problem in the serial data.

fix was adding a .substring(1) to the parsing subroutine.