btw im using arduino nano,sim 800l and gps neo6m
A post was split to a new topic: Comapring GPS co-ordinates
Roughly of 10% is good enough--4 decimal places would be a box 0.0001*60*1852m=11.11m
in latitude N/S, and 11.11m * cos(latitude)
in longitude E/W -- the box will get narrower as you move away from the equator. 70% as wide at 45N.
This is my final 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;
// Default position
double previousLatitude = -7.95455920757861;
double previousLongitude = 112.46525436491427;
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
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
//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");
sendGpsToServer(String(gps.location.lat(),6),String(gps.location.lng(),6));
}
void loop()
{
while(sim800L.available()){
Serial.println(sim800L.readString());
}
while(Serial.available()) {
sim800L.println(Serial.readString());
}
boolean newData = false;
while (neogps.available()){
if (gps.encode(neogps.read())){
newData = true;
break;
}
}
//If newData is true
if(true){
newData = false;
double latitude, longitude;
latitude = gps.location.lat();
longitude = gps.location.lng();
if(latitude != 0 && longitude != 0){
if (haversine(previousLatitude, previousLongitude, latitude, longitude) > 15 ){
sendGpsToServer(String(gps.location.lat(),6),String(gps.location.lng(),6));
}
}
}
}
int sendGpsToServer(String latitude, String longitude)
{
float altitude;
unsigned long date, time, speed, satellites;
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();
String url, temp;
url = "http://xyz.com&latitude=";
url += latitude;
url += "&longitude=";
url += longitude;
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
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
You chose the unnecessarily complex solution? If you are happy with that then great. Thanks for posting your solution.
In my case the solution was more precise. Thanks for your help!
More precise in what way ?
double previousLatitude = -7.95455920757861;
double previousLongitude = 112.46525436491427;
Your using a Nano so there is no point in using double, or that many decimal places, it wont add to the precision.
1 Like
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.