compare GPS data

hello friends…
Am using GPS shield from ITEAD studio which is working properly. i have already stored GPS coordinates on the SD card. Now i want the arduino to read these data the compare them to the ones received by the GPS receiver then print out the location as stored.
For the GPS:

#include <TinyGPS.h>

#include <SoftwareSerial.h>

#define RXPIN 2
#define TXPIN 3

TinyGPS gps;
SoftwareSerial ss = SoftwareSerial(RXPIN, TXPIN);
void setup()
{
Serial.begin(38400);
Serial.print("Simple TinyGPS library v. ");
Serial.println(“coded by himuselefu”);
Serial.println();
pinMode(RXPIN, INPUT);
pinMode(TXPIN, OUTPUT);
ss.begin(38400);
}

void loop() //loop principal.
{
bool newData = false;
unsigned long chars;
unsigned short sentences, failed;

// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}

if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print(“LAT=”);
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
}

gps.stats(&chars, &sentences, &failed);
Serial.print(" CHARS=");
Serial.print(chars);
Serial.print(" SENTENCES=");
Serial.print(sentences);
Serial.print(" CSUM ERR=");
Serial.println(failed);
}

for the SD card i used the code below and i was able to read data from the sd card.

#include <SD.h>
int CS_pin = 10;
int pow_pin = 8;
File myFile;

void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
Serial.print(“Initializing SD card…”);
pinMode(10, OUTPUT);
pinMode(pow_pin, OUTPUT);
digitalWrite(pow_pin, HIGH);

if (!SD.begin(10)) {
Serial.println(“initialization failed!”);
return;
}
Serial.println(“initialization done.”);
}
void loop()
{
myFile = SD.open(“gps.txt”);
if (myFile) {

// read from the file until there’s nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
Serial.println(’\n’);
myFile.close();
} else {
// if the file didn’t open, print an error:
Serial.println(“error openning the file gps”);
}
delay(2000);
}

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

This code is a major flaw in an otherwise great product. Most GPSs only send data about once a second, anyway. The for loop and associated open and close braces should hit the bit bucket.

The second code need to collect the data read from the file into an array, until an end of record marker is located. It currently simply writes each character to the serial port.

Once the end of record marker is read, the data stored in the array needs to be parsed to locate the parts of interest. You have not defined what those parts are.

Then, the parts of interest need to be compared to the current data, by some means. What you are comparing will define what those means are.

I don’t think your requirements are properly stated. You seem to want to read some data from a file, perform some undefined comparison, and then unconditionally write the file data out somewhere. That doesn’t make sense to me. Might I suggest that you try again to define what you want to do?

Thanks so much Paul. Am a noob in GPS and arduino and i cant really understand what u mean by "The for loop and associated open and close braces should hit the bit bucket." Mayb if u can demonstrate using the code.

This is actually my project and this is what it does. On the sd card, ill store the coordinates of particular points on the earths surface plus the name of the location. The coordinates from the GPS receiver will be received by the arduino then compared to the ones on the SD card. If they match, then the name of the location is displayed on the serial monitor.

Hope uve caught the glimpse of the project.

Mayb if u can demonstrate using the code.

Sure. This:

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

should be:

    while (ss.available())
    {
      char c = ss.read();
      Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }

If they match, then the name of the location is displayed on the serial monitor.

So, you want to extract latitude and longitude from the GPS data, and compare to latitude and longitude values from the SD card. How do you define a match? Within 2 mm? 2 kilometers? The strings are the same?

What does the file on the SD card look like? Show the first few lines.

Thanks so much Paul. Will try it out. On the SD card i've stored the whole GPRMC sentence plus the name of the location as below. $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A - 'weststreet.'

Now i want to compare only the longitude and latitude of this location with the ones from the GPS receiver. When they match, it displays the name of the location "weststreet" on the serial monitor.

hi peterkim, could you please upload the code for comparing you have, why not try comparing with a switch and case statement. it would be prudent to consider the accuracy of gps which is around 2m, then comparing within a radius of say 10m and displaying weststreet. I could help but i need to see what you have

Thanks so much…in my code, i tried using if and else statements but its not working. Am not quite conversant with switch and case statement so ill highly appreciate if u could modify the code for me using switch and case statement.
Here is my code:

#include <TinyGPS.h>
#include <SD.h>
#include <SoftwareSerial.h>

#define RXPIN 2
#define TXPIN 3
int CS_pin = 10;
int pow_pin = 8;
File myFile;

TinyGPS gps;
SoftwareSerial ss = SoftwareSerial(RXPIN, TXPIN);
void setup()
{
Serial.begin(38400);
Serial.print("Simple TinyGPS library v. ");
Serial.println(“coded by himuselefu”);
Serial.println();
pinMode(RXPIN, INPUT);
pinMode(TXPIN, OUTPUT);
ss.begin(38400);

// Open serial communications and wait for port to open:
Serial.begin(9600);
Serial.print(“Initializing SD card…”);
// On the Ethernet Shield, CS is pin 4. It’s set as an output by default.
// Note that even if it’s not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(10, OUTPUT);
pinMode(pow_pin, OUTPUT);
digitalWrite(pow_pin, HIGH);

if (!SD.begin(10)) {
Serial.println(“initialization failed!”);
return;
}
Serial.println(“initialization done.”);
}

void loop() //loop principal.
{
bool newData = false;
unsigned long chars;
unsigned short sentences, failed;

// For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
}

if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print(“LAT=”);
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
}

gps.stats(&chars, &sentences, &failed);
Serial.print(" CHARS=");
Serial.print(chars);
Serial.print(" SENTENCES=");
Serial.print(sentences);
Serial.print(" CSUM ERR=");
Serial.println(failed);

myFile = SD.open(“data.txt”);
if (myFile) {

// read from the file until there’s nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
Serial.println(’\n’);
myFile.close();
}

else {
// if the file didn’t open, print an error:
Serial.println(“error openning the file”);
}
delay(2000);

if ((“LAT = 0105.70655”) && (“LON = 03701.06737”))
{
Serial.println(“Weststreet”);
delay(2000);
}
else
{

}
}

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

Get rid of the comment and the for loop. Keep the code in the body of the for loop. The GPS typically only sends data once a second. Spending a whole second waiting for data allows no time to process the data that was received.

  myFile = SD.open("data.txt");
  if (myFile) {
    
   
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    Serial.println('\n');
    myFile.close();
  }

You opened the file, and blindly spooled all the data to the serial port. That’s not going to be very helpful in terms of comparing where you are now to a list of places.

This whole block should be in the if(newdata) block.

  if (("LAT = 0105.70655") && ("LON = 03701.06737"))

Is “LAT = 0105.70655” true or false? This is not how to compare strings. You have a variable, flat, which is a float. You do not have have a string to compare it to. You could hardcode a string, but you can’t compare a string to a float.

What you are trying to do here is not Arduino specific. You really need to take a class on C programming.

Hi Peterkim I agree you need some classes in C. I woild recommend you the book The C programming Language. By Brian W. Kernighan and Dennis M. Ritchie. Published by Prentice-Hall in 1988. ISBN 0-13-110362-8 . A very nice book. Plus post complete code so that we can help you. i noticed in the else statement there is nothing to do, unless thats what you want. Is it? Here is my suggestion but remember that at the end of it all the ball is in your hands.Good day.

switch ( condition ) { case 1: Serial.println("Weststreet"); delay(2000); break; case 2: Serial.println("Northstreet"); delay(2000); break; }

Hi Left01 and PaulS.. so far ive tried comparing GPS data but with no avail. Ive come up with another idea which involves zoning of location depending on latitude and latitude. could you be having any idea of how zoning is done in arduino?

thanks peterkim

so far ive tried comparing GPS data but with no avail.

I guess I missed the post where that code, and results, was discussed.

could you be having any idea of how zoning is done in arduino?

I have no idea what you are talking about. Zoning is done by the city council, as far as I know. I don't think they use an Arduino to do it.

since its difficult to compare particular GPS coordinates, wat i mean is if the GPS is in a certain range of coordinates, then it displays the name of that location. For example:

Zones[0] = &Name(Serial.println("stanford")); Zones[0]->setVertices(6, (Vertex[6]) { Vertex(45.027162772967756, -93.48137855529785), Vertex(45.02946790848425, -93.4742546081543), Vertex(45.02955889877115, -93.46193790435791), Vertex(45.02861865883124, -93.46172332763672), Vertex(45.02861865883124, -93.47412586212158), Vertex(45.02649547957147, -93.48133563995361) } if the GPS is in the following range of coordinates, then it displays the name stanford. Thanks in advance.

Zones[0] = &Name(Serial.println("stanford"));

Serial.println() returns the number of bytes that it wrote. How is that useful information to pass to the Name() function? Why would you want to store the address of the returned value?

since its difficult to compare particular GPS coordinates

Why do you say that? The TinyGPS() library includes a f_get_position() function that gives lat and lon for where you are now. It also has a distance_between() method that can determine the distance to some other location. Now, that distance may (I haven't looked at the code) be based on a straight line distance, rather than the distance along the surface (assuming some not-too-accurate characteristics of the surface (of the earth)), but for your purposes ("You are at Stanford (, as opposed to Key West Florida)"), I can't see that as a significant limitation.

Certainly more straightforward than determining if a 3D location is within a volume defined by 6 points, whatever those points represent.

Hi, were you successful in getting the project working? i would like to see your final working code.

first of all u should know that GPS shield from ITEAD studio is not supported by TinyGPS. this means that you should find the coordinates manually..i.e. count every bit of the GPRMC sentence then displaying them. let me look for the code will get back to you shortly. thanks

peterkim: first of all u should know that GPS shield from ITEAD studio is not supported by TinyGPS. this means that you should find the coordinates manually..i.e. count every bit of the GPRMC sentence then displaying them. let me look for the code will get back to you shortly. thanks

AFAIK, TinyGPS doesn't care where the data comes from. It doesn't do the interfacing with any particular GPS, simply takes NMEA sentences and parses them for the data contained within. If you can capture the NMEA sentence from the device and pass to encode() then it will processs it.

If you can capture the NMEA sentence from the device and pass to encode() then it will processs it.

If the sentence IS complete, including checksum. IIRC, that is not the case for ITEAD's GPS shield.

I just found the following thread on iteadstudio GPS shield where it seems everyone us using TinyGPS OK.

Is there a newer version that doesn't return the checksums?

http://forum.arduino.cc/index.php?topic=113603.105

TinyGPS will read data from any GPS module that outputs standard NMEA "sentences". You already posted an example of your GPS output and it looked quite standard to me.

…MY math and programming skills tells me that this is easier with just one point (not 6)
Then calculate the ABS offset in x- an y-direction.
Known formulas will tell you the absolute length from fixed point to actual position
(if you dont travel very far, this formula can be redused to simple pythagoras)
I guess this will an elliptical area around fixed point - if not taken into account your latitude…