Problem of getting exact location using DFRobot_sim808.h by GSM808

it seems that the location is not accurate enough and im trying to understand this simple code i found in DFRobot library. Can anyone help me how to convert them to accurate latitude and longitude? thanks ! just the location i’m worrying about.

Here is my code:

#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
#define MESSAGE_LENGTH 160
char message[MESSAGE_LENGTH];
int messageIndex = 0;
char MESSAGE[300];
char lat[12];
char lon[12];
char wspeed[12];
char newlatminutes[12];
int latitude;
int longitude;

char phone[16];
char datetime[24];
#define phone_num “09096637389”

#define PIN_TX 10
#define PIN_RX 11
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

void setup()
{
pinMode(6,INPUT);
pinMode(52, INPUT);
digitalWrite(6,HIGH);
delay(2000);
digitalWrite(6,LOW);
delay(1000);

mySerial.begin(9600);
Serial.begin(9600);

//******** Initialize sim808 module *************
while(!sim808.init())
{
Serial.print(“Sim808 init error\r\n”);
delay(1000);
}
delay(3000);

if( sim808.attachGPS())
Serial.println(“Open the GPS power success”);
else
Serial.println(“Open the GPS power failure”);

Serial.println(“Init Success, please send SMS message to me!”);

}

void loop()
{

//*********** Detecting unread SMS ************************
messageIndex = sim808.isSMSunread();

while(!sim808.getGPS())
{
if (sim808.getGPS()){
Serial.print(“speed_kph :”);
Serial.println(sim808.GPSdata.speed_kph);
delay(2000);
}
}

//*********** At least, there is one UNREAD SMS ***********
if (messageIndex > 0 || digitalRead(52) == LOW)
{
Serial.print("messageIndex: ");
Serial.println(messageIndex);

sim808.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);

//*In order not to full SIM Memory, is better to delete it
sim808.deleteSMS(messageIndex);
Serial.print("From number: ");
Serial.println(phone);
Serial.print("Datetime: ");
Serial.println(datetime);
Serial.print("Recieved Message: ");
Serial.println(message);

Serial.print(sim808.GPSdata.year);
Serial.print("/");
Serial.print(sim808.GPSdata.month);
Serial.print("/");
Serial.print(sim808.GPSdata.day);
Serial.print(" “);
Serial.print(sim808.GPSdata.hour);
Serial.print(”:");
Serial.print(sim808.GPSdata.minute);
Serial.print(":");
Serial.print(sim808.GPSdata.second);
Serial.print(":");
Serial.println(sim808.GPSdata.centisecond);

// Serial.print(“latitude :”);
// Serial.println(sim808.GPSdata.lat,6);
/* sim808.latitudeConverToDMS();

Serial.print(sim808.latDMS.degrees);
Serial.print("^");
Serial.print(sim808.latDMS.minutes);
Serial.print("’");
Serial.print(sim808.latDMS.seconeds,6);
Serial.println(""");
Serial.print(“newlatitude :”);*/

// Serial.print(“longitude :”);
// Serial.println(sim808.GPSdata.lon,6);
sim808.LongitudeConverToDMS();
Serial.print(“longitude :”);
Serial.print(sim808.longDMS.degrees,2);
Serial.print("^");
Serial.print(sim808.longDMS.minutes,2);
Serial.print("’");
Serial.print(sim808.longDMS.seconeds,6);
Serial.println(""");

Serial.println(sim808.GPSdata.lat);
Serial.print(“latitude :”);
Serial.print("^");

Serial.println(sim808.GPSdata.lon);
Serial.print(“longitude :”);
Serial.print("^");

Serial.print(“speed_kph :”);
Serial.println(sim808.GPSdata.speed_kph);
Serial.print(“heading :”);
Serial.println(sim808.GPSdata.heading);
Serial.println();

float la = sim808.GPSdata.lat;
float lo = sim808.GPSdata.lon;
float ws = sim808.GPSdata.speed_kph;

dtostrf( la,6, 6, lat); //put float value of la into char array of lat. 6 = number of digits before decimal sign. 2 = number of digits after the decimal sign.
dtostrf( lo,6, 6, lon); //put float value of lo into char array of lon
dtostrf( ws,6, 6, wspeed); //put float value of ws into char array of wspeed

sprintf(MESSAGE, “Latitude : %s\nLongitude : %s\nSpeed in kph : %s kph\nEMERGENCY !! Track my location here: \nhttp://maps.google.com/maps?q=%s,%s”, lat, lon, wspeed, lat, lon);
if (messageIndex < 0) {
Serial.println(“Sim808 init success”);
Serial.println(“Start to send message …”);
Serial.println(MESSAGE);
Serial.println(phone_num);
sim808.sendSMS(phone_num,MESSAGE);
}
else {
Serial.println(“Sim808 init success”);
Serial.println(“Start to send message …”);
Serial.println(MESSAGE);
Serial.println(phone);
sim808.sendSMS(phone,MESSAGE);
}
//************* Turn off the GPS power ************
// sim808.detachGPS();
}
}

it seems that the location is not accurate enough

You'll need to explain that. How far off is the returned lat/lon from what you expect them to be?

sorry about that, these are my datas:

my location base on google map and phone GPS:

10.738492, 122.969957 (10°44'18.6"N 122°58'11.9"E)

my code/GSM808 results:

10.443071, 122.581890 (10°26'35.1"N 122°34'54.8"E)

 while(!sim808.getGPS())
    {
     if (sim808.getGPS()){
      Serial.print("speed_kph :");
      Serial.println(sim808.GPSdata.speed_kph);
      delay(2000);
     }
    }

While you can't get any data, see if you can get some data. You need to explain that!

Once you do get a text message, you never call getGPS() again, so you are responding to the text message with old data.

I need that speed information continuously because I need the data that if the device detects a low speed (meaning it is stationary), it will turn off our sensor but if not, then our sensor will turn on. That is the only thing I could think about for making conditions using the GPS data.

If all you care about is speed, why are you concerned about accuracy of position?

Why, if you do care about speed, are you not sending CURRENT information?

That's why I'm asking if you could help me improve my codes. As I mention in my question, I just get the code in a DFRobot sim808 library, and getting the GPS reading and Speed is one of the parameters I need for my project. But after all these trials, I observe that this library, even without the speed, doesn't give even a close enough location of my current location. The speed purpose is only for me to have maybe a reading for me to determine and adjust my conditions when the car is stationary or not.

I do not know if I don't put that speed and I make any conditions using it, will it run anyways? sorry for being a newbie.

Isn't it obvious that the ONLY thing that gets data from the GPS is the call to getGPS()? EVERY time you want current information, you must call that function.

ALL of the other calls get you stale information.

but can I ask the main issue, the error in location? here is the original code for that :

#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define PIN_TX 10
#define PIN_RX 11
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

//DFRobot_SIM808 sim808(&Serial);

void setup() {
mySerial.begin(9600);
Serial.begin(9600);

//******** Initialize sim808 module *************
while(!sim808.init()) {
delay(1000);
Serial.print(“Sim808 init error\r\n”);
}

//************* Turn on the GPS power************
if( sim808.attachGPS())
Serial.println(“Open the GPS power success”);
else
Serial.println(“Open the GPS power failure”);

}

void loop() {
//************** Get GPS data *******************
if (sim808.getGPS()) {
Serial.print(sim808.GPSdata.year);
Serial.print("/");
Serial.print(sim808.GPSdata.month);
Serial.print("/");
Serial.print(sim808.GPSdata.day);
Serial.print(" “);
Serial.print(sim808.GPSdata.hour);
Serial.print(”:");
Serial.print(sim808.GPSdata.minute);
Serial.print(":");
Serial.print(sim808.GPSdata.second);
Serial.print(":");
Serial.println(sim808.GPSdata.centisecond);

Serial.print(“latitude :”);
Serial.println(sim808.GPSdata.lat,6);

sim808.latitudeConverToDMS();
Serial.print(“latitude :”);
Serial.print(sim808.latDMS.degrees);
Serial.print("^");
Serial.print(sim808.latDMS.minutes);
Serial.print("’");
Serial.print(sim808.latDMS.seconeds,6);
Serial.println(""");
Serial.print(“longitude :”);
Serial.println(sim808.GPSdata.lon,6);
sim808.LongitudeConverToDMS();
Serial.print(“longitude :”);
Serial.print(sim808.longDMS.degrees);
Serial.print("^");
Serial.print(sim808.longDMS.minutes);
Serial.print("’");
Serial.print(sim808.longDMS.seconeds,6);
Serial.println(""");

Serial.print(“speed_kph :”);
Serial.println(sim808.GPSdata.speed_kph);
Serial.print(“heading :”);
Serial.println(sim808.GPSdata.heading);

//************* Turn off the GPS power ************
sim808.detachGPS();
}

}

but can I ask the main issue, the error in location?

Are you running that code outside?

I'm going to guess that the problem is that the GPS chip/antenna on the SIM808 board is very tiny, and can't determine, very accurately, it position relative to the GPS satellites. More accurate systems use antennas that are at least an order of magnitude larger.

I really don’t know if the chip is the main problem, and yes I’m running it outside. Because we have another code that gives accurate reading but we can’t extract it’s speed.

here is the code :

#include <SoftwareSerial.h>
SoftwareSerial lat_long(10,11); //rx, tx - 9,10 for arduino uno - 10,11 for arduino mega rx, tx
char messageminor= “Message Content: Minor”;
char messagemajor= “Message Content: Help!”;
String data[5];

#define DEBUG true

String state, timegps, latitude, longitude;
int pb_minor = 52;
int sendsmsminor;
int sendsmsmajor;
int accelero;

void setup() {
lat_long.begin(9600);
Serial.begin(9600);
pinMode(52,INPUT);
delay(50);
// lat_long.print(“AT+CSMP=17,167,0,0”); // set this parameter if empty SMS received
delay(100);
lat_long.print(“AT+CMGF=1\r”);
delay(400);
sendData(“AT+CGNSPWR=1”,1000,DEBUG);
delay(50);
sendData(“AT+CGNSSEQ=RMC”,1000,DEBUG);
delay(150);
}

void loop() {
pb_minor = digitalRead(52);
if (pb_minor==LOW) {
sendTabData(“AT+CGNSINF”,1000,DEBUG);
sendsmsminor=1;
}
/* else if (accelero==LOW) {
sendTabData(“AT+CGNSINF”,1000,DEBUG);
sendsmsmajor=1;
}
*/
else {
sendsmsminor=0;
sendsmsmajor=0;
}

if (state != 0 && sendsmsminor==1) {
Serial.println(“State :”+state);
Serial.println(“Time :”+timegps);
Serial.println(“Latitude :”+latitude);
Serial.println(“Longitude :”+longitude);
lat_long.print(“AT+CMGS=“09096637389”\r”);
delay(300);
lat_long.println(messageminor);
delay(200);
lat_long.print(“Location:”);
lat_long.print(“http://maps.google.com/maps?q=loc:”);
lat_long.print(latitude);
lat_long.print(",");
lat_long.print(longitude);
delay(200);
lat_long.println((char)26); //End AT command with a ^Z, ASCII code 26
delay(200);
lat_long.println();
delay(10000);
lat_long.flush();
}
else if (state != 0 && sendsmsmajor==1) {
Serial.println(“State :”+state);
Serial.println(“Time :”+timegps);
Serial.println(“Latitude :”+latitude);
Serial.println(“Longitude :”+longitude);
lat_long.print(“AT+CMGS=“09096637389”\r”);
delay(300);
lat_long.println(messagemajor);
delay(200);
lat_long.print(“Location:”);
lat_long.print(“http://maps.google.com/maps?q=loc:”);
lat_long.print(latitude);
lat_long.print(",");
lat_long.print(longitude);
delay(200);
lat_long.println((char)26); //End AT command with a ^Z, ASCII code 26
delay(200);
lat_long.println();
delay(10000);
lat_long.flush();
}
else {
Serial.println(“GPS Initializing…”);
delay(200);
}
}
void sendTabData(String command, const int timeout, boolean debug){

lat_long.println(command);
long int time = millis();
int i = 0;

while((time+timeout) > millis()){
while(lat_long.available()){
char c = lat_long.read();
if(c != ‘,’){ //read characters until you find comma, if found increment
data*+=c;*

  • delay(100);*

  • }else{*

  • i++; *

  • }*

  • if(i == 5){*

  • delay(100);*

  • goto exitL;*

  • } *

  • } *

  • }exitL: *

  • if(debug){*
    _ /or you just can return whole table, in case if its not global/_

  • state = data[1]; //state = recieving data - 1, not recieving - 0*

  • timegps = data[2];*

  • latitude = data[3]; //latitude*

  • longitude = data[4]; //longitude*

  • }*
    }

  • String sendData (String command , const int timeout , boolean debug){*

  • String response = “”;*

  • lat_long.println(command);*

  • long int time = millis();*

  • int i=0;*

  • while ((time+timeout) > millis()) {*

  • while (lat_long.available()){*

  • char c = lat_long.read();*

  • response +=c;*

  • }*

  • }*

  • if(debug){*

  • Serial.print(response);*

  • }*

  • return response;*

  • }*

Now, can you see why we ask you to use code tags when posting code?

I really don't know though, I just register here recently to find some help.

mackert00:
I really don't know though, I just register here recently to find some help.

So, help us to help you AND USE CODE TAGS.

This is the first one that gives inaccurate GPS location.

resutls: 10.443082,122.581901
expected values: 10.738469, 122.969930

/*
### Get GPS data
1. This example is used to test SIM808 GPS/GPRS/GSM Shield's reading GPS data.
2. Open the SIM808_GetGPS example or copy these code to your project
3. Download and dial the function switch to Arduino
4. open serial helper
4. Place it outside, waiting for a few minutes and then it will send GPS data to serial

create on 2016/09/23, version: 1.0
by jason

*/
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

//#define PIN_TX    10
//#define PIN_RX    11
//SoftwareSerial mySerial(PIN_TX,PIN_RX);
//DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

DFRobot_SIM808 sim808(&Serial);

void setup() {
  //mySerial.begin(9600);
  Serial.begin(9600);

  //******** Initialize sim808 module *************
  while(!sim808.init()) { 
      delay(1000);
      Serial.print("Sim808 init error\r\n");
  }

  //************* Turn on the GPS power************
  if( sim808.attachGPS())
      Serial.println("Open the GPS power success");
  else 
      Serial.println("Open the GPS power failure");
  
}

void loop() {
   //************** Get GPS data *******************
   if (sim808.getGPS()) {
    Serial.print(sim808.GPSdata.year);
    Serial.print("/");
    Serial.print(sim808.GPSdata.month);
    Serial.print("/");
    Serial.print(sim808.GPSdata.day);
    Serial.print(" ");
    Serial.print(sim808.GPSdata.hour);
    Serial.print(":");
    Serial.print(sim808.GPSdata.minute);
    Serial.print(":");
    Serial.print(sim808.GPSdata.second);
    Serial.print(":");
    Serial.println(sim808.GPSdata.centisecond);
    
    Serial.print("latitude :");
    Serial.println(sim808.GPSdata.lat,6);
    
    sim808.latitudeConverToDMS();
    Serial.print("latitude :");
    Serial.print(sim808.latDMS.degrees);
    Serial.print("\^");
    Serial.print(sim808.latDMS.minutes);
    Serial.print("\'");
    Serial.print(sim808.latDMS.seconeds,6);
    Serial.println("\"");
    Serial.print("longitude :");
    Serial.println(sim808.GPSdata.lon,6);
    sim808.LongitudeConverToDMS();
    Serial.print("longitude :");
    Serial.print(sim808.longDMS.degrees);
    Serial.print("\^");
    Serial.print(sim808.longDMS.minutes);
    Serial.print("\'");
    Serial.print(sim808.longDMS.seconeds,6);
    Serial.println("\"");
    
    Serial.print("speed_kph :");
    Serial.println(sim808.GPSdata.speed_kph);
    Serial.print("heading :");
    Serial.println(sim808.GPSdata.heading);

    //************* Turn off the GPS power ************
    sim808.detachGPS();
  }

}

This second code gives accurate GPS location but we can’t extract or display it’s speed value

#include <SoftwareSerial.h>
SoftwareSerial lat_long(10,11); //rx, tx - 9,10 for arduino uno - 10,11 for arduino mega rx, tx
char messageminor[]= "Message Content: Minor";
char messagemajor[]= "Message Content: Help!";
String data[5];

#define DEBUG true

String state, timegps, latitude, longitude;
int pb_minor = 52;
int sendsmsminor;
int sendsmsmajor;
int accelero;

void setup() {
  lat_long.begin(9600);
  Serial.begin(9600);
  pinMode(52,INPUT);
  delay(50);
//  lat_long.print("AT+CSMP=17,167,0,0"); // set this parameter if empty SMS received
  delay(100);
  lat_long.print("AT+CMGF=1\r");
  delay(400);
  sendData("AT+CGNSPWR=1",1000,DEBUG);
  delay(50);
  sendData("AT+CGNSSEQ=RMC",1000,DEBUG);
  delay(150);
}

void loop() {
 pb_minor = digitalRead(52);
 if (pb_minor==LOW) {
  sendTabData("AT+CGNSINF",1000,DEBUG);
  sendsmsminor=1;
 }
/* else if (accelero==LOW) {
  sendTabData("AT+CGNSINF",1000,DEBUG);
  sendsmsmajor=1;
  }
  */
 else {
  sendsmsminor=0;
  sendsmsmajor=0;
 }
 
  if (state != 0 && sendsmsminor==1) {
    Serial.println("State :"+state);             
    Serial.println("Time :"+timegps);
    Serial.println("Latitude :"+latitude);
    Serial.println("Longitude :"+longitude);
    lat_long.print("AT+CMGS=\"09096637389\"\r");
    delay(300);
    lat_long.println(messageminor);  
    delay(200);
    lat_long.print("Location:");
    lat_long.print("http://maps.google.com/maps?q=loc:");
    lat_long.print(latitude);
    lat_long.print(",");
    lat_long.print(longitude);
    delay(200);
    lat_long.println((char)26); //End AT command with a ^Z, ASCII code 26
    delay(200);  
    lat_long.println();
    delay(10000);
    lat_long.flush();
    }
   else if (state != 0 && sendsmsmajor==1) {
    Serial.println("State :"+state);             
    Serial.println("Time :"+timegps);
    Serial.println("Latitude :"+latitude);
    Serial.println("Longitude :"+longitude);
    lat_long.print("AT+CMGS=\"09096637389\"\r");
    delay(300);
    lat_long.println(messagemajor);  
    delay(200);
    lat_long.print("Location:");
    lat_long.print("http://maps.google.com/maps?q=loc:");
    lat_long.print(latitude);
    lat_long.print(",");
    lat_long.print(longitude);
    delay(200);
    lat_long.println((char)26); //End AT command with a ^Z, ASCII code 26
    delay(200);  
    lat_long.println();
    delay(10000);
    lat_long.flush();
    }
  else {
    Serial.println("GPS Initializing...");
    delay(200);
  }
}
  void sendTabData(String command, const int timeout, boolean debug){
 
    lat_long.println(command); 
    long int time = millis();
    int i = 0;   
    
    while((time+timeout) > millis()){
      while(lat_long.available()){       
        char c = lat_long.read();
        if(c != ','){ //read characters until you find comma, if found increment
          data[i]+=c;
          delay(100);
        }else{
          i++;        
        }
        if(i == 5){
          delay(100);
          goto exitL;
        }       
      }    
    }exitL:    
    if(debug){ 
      /*or you just can return whole table, in case if its not global*/ 
      state = data[1];  //state = recieving data - 1, not recieving - 0
      timegps = data[2];
      latitude = data[3];     //latitude
      longitude = data[4];    //longitude
    }
}
  
  String sendData (String command , const int timeout , boolean debug){
    String response = "";
    lat_long.println(command);
    long int time = millis();
    int i=0;
    while ((time+timeout) > millis()) {
      while (lat_long.available()){
        char c = lat_long.read();
        response +=c;
        }
    }
    if(debug){
      Serial.print(response);
    }
    return response;
  }

This second code gives accurate GPS location but we can't extract or display it's speed value

Speed is calculated from (distance traveled)/(time to travel), which is what GPS modules do.

So, get two successive locations, calculate the distance between them in meters, and divide that by the number of seconds transpired between readings, to get the velocity in m/s.

This won't work well with standard Arduinos, which are limited to 32 bit, single precision floats.