Modify GPS tracker coding

So i have GPS tracker project. I use this code :

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>

#define rxPin 2
#define txPin 3
SoftwareSerial sim800L(rxPin,txPin); 

//GPS Module RX pin to Arduino 9
//GPS Module TX pin to Arduino 8
AltSoftSerial neogps;

TinyGPSPlus gps;

unsigned long previousMillis = 0;
long interval = 60000;


void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(115200);
  
  //Begin serial communication with Arduino and SIM800L
  sim800L.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  neogps.begin(9600);

  Serial.println("Initializing...");
  //delay(10000);

  //Once the handshake test is successful, it will back to OK
  sendATcommand("AT", "OK", 2000);
  sendATcommand("AT+CMGF=1", "OK", 2000);
  //sim800L.print("AT+CMGR=40\r");
  
}

void loop()
{
  while(sim800L.available()){
    Serial.println(sim800L.readString());
  }
  while(Serial.available())  {
    sim800L.println(Serial.readString());
  }

    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) {
       previousMillis = currentMillis;
       sendGpsToServer();
    }
}

int sendGpsToServer()
{
    //Can take up to 60 seconds
    boolean newData = false;
    for (unsigned long start = millis(); millis() - start < 2000;){
      while (neogps.available()){
        if (gps.encode(neogps.read())){
          newData = true;
          break;
        }
      }
    }
  
    //If newData is true
    if(true){
      newData = false;
      
      String latitude, longitude;
      float altitude;
      unsigned long date, time, speed, satellites;
  
      latitude = String(gps.location.lat(), 6); // Latitude in degrees (double)
      longitude = String(gps.location.lng(), 6); // Longitude in degrees (double)
      altitude = gps.altitude.meters(); // Altitude in meters (double)
      date = gps.date.value(); // Raw date in DDMMYY format (u32)
      time = gps.time.value(); // Raw time in HHMMSSCC format (u32)
      speed = gps.speed.kmph();
      
      Serial.print("Latitude= "); 
      Serial.print(latitude);
      Serial.print(" Longitude= "); 
      Serial.println(longitude);
  
      //if (latitude == 0) {return 0;}
      
      String url, temp;
      url = "http://ENTER_YOUR_WEBSITE/gpsdata.php?lat=";
      url += latitude;
      url += "&lng=";
      url += longitude;

      //url = "http://ahmadssd.000webhostapp.com/gpsdata.php?lat=222&lng=222";

      Serial.println(url);    
      delay(300);
          
    sendATcommand("AT+CFUN=1", "OK", 2000);
    //AT+CGATT = 1 Connect modem is attached to GPRS to a network. AT+CGATT = 0, modem is not attached to GPRS to a network
    sendATcommand("AT+CGATT=1", "OK", 2000);
    //Connection type: GPRS - bearer profile 1
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    //sets the APN settings for your network provider.
    sendATcommand("AT+SAPBR=3,1,\"APN\",\"internet\"", "OK", 2000);
    //enable the GPRS - enable bearer 1
    sendATcommand("AT+SAPBR=1,1", "OK", 2000);
    //Init HTTP service
    sendATcommand("AT+HTTPINIT", "OK", 2000); 
    sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 1000);
    //Set the HTTP URL sim800.print("AT+HTTPPARA="URL","http://ahmadssd.000webhostapp.com/gpsdata.php?lat=222&lng=222"\r");
    sim800L.print("AT+HTTPPARA=\"URL\",\"");
    sim800L.print(url);
    sendATcommand("\"", "OK", 1000);
    //Set up the HTTP action
    sendATcommand("AT+HTTPACTION=0", "0,200", 1000);
    //Terminate the HTTP service
    sendATcommand("AT+HTTPTERM", "OK", 1000);
    //shuts down the GPRS connection. This returns "SHUT OK".
    sendATcommand("AT+CIPSHUT", "SHUT OK", 1000);

  }
  return 1;    
}

int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    //Initialice the string
    memset(response, '\0', 100);
    delay(100);
    
    //Clean the input buffer
    while( sim800L.available() > 0) sim800L.read();
    
    if (ATcommand[0] != '\0'){
      //Send the AT command 
      sim800L.println(ATcommand);
    }

    x = 0;
    previous = millis();

    //this loop waits for the answer with time out
    do{
        //if there are data in the UART input buffer, reads it and checks for the asnwer
        if(sim800L.available() != 0){
            response[x] = sim800L.read();
            //Serial.print(response[x]);
            x++;
            // check if the desired answer (OK) is in the response of the module
            if(strstr(response, expected_answer) != NULL){
                answer = 1;
            }
        }
    }while((answer == 0) && ((millis() - previous) < timeout));

  Serial.println(response);
  return answer;
}

//AT+CFUN=1
//AT+CGATT=1
//AT+SAPBR=3,1,"Contype","GPRS"
//AT+SAPBR=3,1,"APN","internet"
//AT+SAPBR=1,1

Everything is working properly and there are no errors.

In that code, data will be sent every 60 seconds, but I have other logic.

I want to compare two coordinates.New coordinates are compared with previous coordinates.If the result is > 10 meters (0.01 km) or more, that coordinates will be stored in the database.

From that logic, how should my code be changed?

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use [color = red]code tags[/color] (the </> icon above the compose window) to make it easier to read and copy for examination

Why are you asking about coding in PHP on the Arduino forum ?

Here is a haversine function written in C++ that I copied from //TinyGPS++ using distanceBetween - #3 by BDub - Libraries - Particle and have used in an Arduino project

double haversine(double lat1, double lon1, double lat2, double lon2)
{
  const double rEarth = 6371000.0; // in meters
  double x = pow( sin( ((lat2 - lat1) * M_PI / 180.0) / 2.0), 2.0 );
  double y = cos(lat1 * M_PI / 180.0) * cos(lat2 * M_PI / 180.0);
  double z = pow( sin( ((lon2 - lon1) * M_PI / 180.0) / 2.0), 2.0 );
  double a = x + y * z;
  double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a));
  double d = rEarth * c;
  return d; // in meters
}

Why write your own code for calculating the distance between two sets of GPS co-ordinates ?

The TinyGPS++ library has that function built in, is there a problem with it ?

No, i not asking php code. I just attached the code just for the information that the haversine formula looks like, and I happen to have an example in PHP.

What I'm asking is, how can my arduino code be modified like the logic I presented. Because I don't have any C++ coding skills (.ino)

And if we make the changes for you, you will still have no C++ coding skills. At least make an attempt and post it. We can help fix it for you.

If you can code in almost any other language (PHP, JavaScript, for example) you already have 80% of the skills you need to code in C++.

ok, i will give it a try...

Oh, and please tell us what type of Arduino you are using. We frequently see people using software serial libraries on Mega and other types which have multiple hardware serial ports, which is a little stupid.

I am using arduino nano and some modules (SIM800L, Neo6m GPS)

Ok, software serial it is then.

There is another, much simpler way to compare coordinates to decide if they are close to each other. You can calculate the difference in the latitude and difference in longitude and round those to a number of decimal places. If they are both zero after rounding, the coordinates are in the same small "box". This "box" is not perfectly square, of course, especially when further from the equator, but I think it might be good enough for the purpose I think you need it for. I suspect your reason for wanting to know the distance between coordinates is so that if they are close, you do not send unnecessary data to your database, for example when an object is stationary for long periods (but of course there are minor differences in the lat/long values coming from the GPS device).

I think rounding lat/long differences to 4 decimal places will give you a box which is very roughly 10m square.

What do you mean like this?

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>

#define rxPin 2
#define txPin 3
SoftwareSerial sim800L(rxPin,txPin);

//GPS Module RX pin to Arduino 9
//GPS Module TX pin to Arduino 8
AltSoftSerial neogps;

TinyGPSPlus gps;

unsigned long previousMillis = 0;
long interval = 60000;
double previousLatitude = 0;   // I set previousLatitude to 0,so the first data always send to the server

float roundoff(float value, unsigned char prec)
{
  float pow_10 = pow(10.0f, (float)prec);
  return round(value * pow_10) / pow_10;
}


void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(115200);

  //Begin serial communication with Arduino and SIM800L
  sim800L.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  neogps.begin(9600);

  Serial.println("Initializing...");
  //delay(10000);

  //Once the handshake test is successful, it will back to OK
  sendATcommand("AT", "OK", 2000);
  sendATcommand("AT+CMGF=1", "OK", 2000);
  //sim800L.print("AT+CMGR=40\r");

}

void loop()
{
  while(sim800L.available()){
    Serial.println(sim800L.readString());
  }
  while(Serial.available())  {
    sim800L.println(Serial.readString());
  }

    // ~Old~
    // unsigned long currentMillis = millis();
    // if(currentMillis - previousMillis > interval) {
    //    previousMillis = currentMillis;
    //    sendGpsToServer();
    // }

    double newLatitude;
    newLatitude = roundoff(gps.location.lat(), 4); //rounding to 4 decimal places

    if ( previousLatitude != newLatitude ) {
      sendGpsToServer();
      previousLatitude = newLatitude;
    }
}

int sendGpsToServer()
{
    //Can take up to 60 seconds
    boolean newData = false;
    for (unsigned long start = millis(); millis() - start < 2000;){
      while (neogps.available()){
        if (gps.encode(neogps.read())){
          newData = true;
          break;
        }
      }
    }

    //If newData is true
    if(true){
      newData = false;

      String latitude, longitude;
      float altitude;
      unsigned long date, time, speed, satellites;

      latitude = String(gps.location.lat(), 6); // Latitude in degrees (double)
      longitude = String(gps.location.lng(), 6); // Longitude in degrees (double)
      altitude = gps.altitude.meters(); // Altitude in meters (double)
      date = gps.date.value(); // Raw date in DDMMYY format (u32)
      time = gps.time.value(); // Raw time in HHMMSSCC format (u32)
      speed = gps.speed.kmph();

      Serial.print("Latitude= ");
      Serial.print(latitude);
      Serial.print(" Longitude= ");
      Serial.println(longitude);

      //if (latitude == 0) {return 0;}

      String url, temp;
      url = "http://yyy.com/api/location/insert?key=ppp&latitude=";
      url += latitude;
      url += "&longitude=";
      url += longitude;

      //url = "http://ahmadssd.000webhostapp.com/gpsdata.php?lat=222&lng=222";

      Serial.println(url);
      delay(300);

    sendATcommand("AT+CFUN=1", "OK", 2000);
    //AT+CGATT = 1 Connect modem is attached to GPRS to a network. AT+CGATT = 0, modem is not attached to GPRS to a network
    sendATcommand("AT+CGATT=1", "OK", 2000);
    //Connection type: GPRS - bearer profile 1
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    //sets the APN settings for your network provider.
    sendATcommand("AT+SAPBR=3,1,\"APN\",\"internet\"", "OK", 2000);
    //enable the GPRS - enable bearer 1
    sendATcommand("AT+SAPBR=1,1", "OK", 2000);
    //Init HTTP service
    sendATcommand("AT+HTTPINIT", "OK", 2000);
    sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 1000);
    //Set the HTTP URL sim800.print("AT+HTTPPARA="URL","http://ahmadssd.000webhostapp.com/gpsdata.php?lat=222&lng=222"\r");
    sim800L.print("AT+HTTPPARA=\"URL\",\"");
    sim800L.print(url);
    sendATcommand("\"", "OK", 1000);
    //Set up the HTTP action
    sendATcommand("AT+HTTPACTION=0", "0,200", 1000);
    //Terminate the HTTP service
    sendATcommand("AT+HTTPTERM", "OK", 1000);
    //shuts down the GPRS connection. This returns "SHUT OK".
    sendATcommand("AT+CIPSHUT", "SHUT OK", 1000);

  }
  return 1;
}

int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout){

    uint8_t x=0,  answer=0;
    char response[100];
    unsigned long previous;

    //Initialice the string
    memset(response, '\0', 100);
    delay(100);

    //Clean the input buffer
    while( sim800L.available() > 0) sim800L.read();

    if (ATcommand[0] != '\0'){
      //Send the AT command
      sim800L.println(ATcommand);
    }

    x = 0;
    previous = millis();

    //this loop waits for the answer with time out
    do{
        //if there are data in the UART input buffer, reads it and checks for the asnwer
        if(sim800L.available() != 0){
            response[x] = sim800L.read();
            //Serial.print(response[x]);
            x++;
            // check if the desired answer (OK) is in the response of the module
            if(strstr(response, expected_answer) != NULL){
                answer = 1;
            }
        }
    }while((answer == 0) && ((millis() - previous) < timeout));

  Serial.println(response);
  return answer;
}

//AT+CFUN=1
//AT+CGATT=1
//AT+SAPBR=3,1,"Contype","GPRS"
//AT+SAPBR=3,1,"APN","internet"
//AT+SAPBR=1,1

A good start. But you need to check longitude as well, otherwise if the object was traveling exactly East or West, your code would not see any change in latitude and not record the new position.

Also I would not have used such a complex function for rounding. You can simply write

    double newLatitude = round(gps.location.lat() * 10000.0) / 10000.0; //rounding to 4 decimal places

Or you can simplify it to

    long newLatitude = round(gps.location.lat() * 10000.0); //scaled up so that 1 unit represents 0.0001 degree of lat/long which is approximately 10m

Thank's for your help!

Please post your completed and tested code in this topic for others to find if they are searching for a similar solution.

Oh, i have other problem.What data type is used to store coordinates? I'm using double, but it only saves 2 decimal places...

Is it only saving 2 decimal places or are you only outputting 2 decimal places ?

Where are you seeing only 2 decimal places ?

On serial monitor,i print it using Serial.print()

     double latitude, longitude;

     latitude = gps.location.lat();
     longitude = gps.location.lng();

     Serial.print("Latitude= ");
     Serial.print(latitude);
     Serial.print(" Longitude= ");
     Serial.println(longitude);

Then it will default to printing 2 decimal places unless you add a second parameter like this

     Serial.print(latitude, 4);  //print latitude with 4 decimal places

[quote="UKHeliBob, post:20, topic:944987"]
Serial.print(latitude, 4); //print latitude with 4 decimal places

hello can i get a help,i want to do maybe a similiar thing with this post, but want to compare two coordinates.New coordinates are compared with previous coordinates.If the result is > 10 meters (0.01 km) or more, and if gps module can acknowledge that the modul is move it wil send a message to my device