MediaTek GPS accuracy. what is different

Hi Guys

Im working on two libraries of GPS code one just prints to terminal and the other savs to SD card , but i have a problem that i cant get solved.

the first sketch is the code I want to get working now but cant , and the second sketch is how I want it to work.

My problem is when running the first Sketch my GPS is accurate with in 10-14km ,when I runthe second sketch is accurate to with in a few feet . I have noticed that the first skecth does not have the same amount of decimals after the "." as the second skecth but i dont understand why since they are both set to floats and both Buff size set to 256.

help please ?

//Add the Mikal Hart Libraries
#include <SoftwareSerial.h>
#include <TinyGPS.h>

//Add the SdFat Libraries
#include <SdFat.h>
#include <SdFatUtil.h> 



#include <ctype.h>

//Create the variables to be used by SdFat Library
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define BUFFSIZE 256
char buffer[BUFFSIZE]; //This will be a data buffer for writing contents to the file.
char in_char=0;
char filename[]="log.txt";

//Intialize TinyGPS and NewSoftSerial
TinyGPS gps;
SoftwareSerial nss(3, 2);

//Intialize GPS variables
float lat  , lon  ;
float flat  , flon  , falt;
unsigned long age, date, time, chars;
int year;
byte month, day, hour, minute, second, hundredths;
unsigned short sentences, failed;

bool newdata = false;
bool feedgps(); 

void setup()
{
  Serial.begin(9600);
  nss.begin(38400); //GPS's Buad Rate
  pinMode(3, INPUT);
  pinMode(2, OUTPUT);
  pinMode(10, OUTPUT); 
  pinMode(8, OUTPUT); //LED Pin 
  
  digitalWrite(8, LOW); // Ensure LED starts as off 
  
  card.init();            //Initialize the SD card and configure the I/O pins.
  volume.init(card);      //Initialize a volume on the SD card.
  root.openRoot(volume);  //Open the root directory in the volume. 
  
  //Create file with defined filename
  file.open(root, filename, O_CREAT | O_APPEND | O_WRITE);    //Open or create the file 'name' in 'root' for writing to the end of the file
  file.println("yr,mth,day,     hr,min,sec,     lat,    long,   alt\n");    //Write the header array to the end of the file.
  file.close(); //Close the file.
  
  // flash LED 5 times when setup is finished
  for (int i=0; i<4; i++){    
    digitalWrite(8, HIGH);   // set the LED on
    delay(1000);              // wait for a second
    digitalWrite(8, LOW);    // set the LED off 
  }   
}

void loop()
{
  bool newdata = false; // check if data is coming in
    if (feedgps())
      newdata = true;
      Serial.println(newdata);
  if (newdata)
  { 
    //Pull gps data
    gps.f_get_position(&flat  , &flon  , &age);
    feedgps(); //used to keep gps "awake"
    gps.crack_datetime(&year,&month,&day,   &hour,&minute,&second,  &hundredths, &age);
    feedgps();
    falt = gps.f_altitude();
    feedgps();
    
    //Break up float values into whole numbers(var) and decimals(var1) to be added to data
    int flat1 = (flat - (int)flat) * 10000;
    int flon1 = (flon - (int)flon) * 100000;
    int alt1 = 0;
    if (falt >= 10000000.00){ //when gps cant get altitude
      falt = 0; //set to 0         
    }else{
      falt = falt * 1; //cm to feet
      alt1 = (falt - (int)falt) * 1;
    } 
   
    //Create then write the char array "buffer" to the end of the file
    file.open(root, filename, O_WRITE | O_APPEND);  //Open the file in write mode and append the data to the end of the file.
    sprintf(buffer, "%d,%d,%d,   %d,%d,%d,   %0d.%d   ,    %0d.%d   ,    %0d.%d\n", year,month,day,hour,minute,second,(int)flat,abs(flat1),(int)flon,abs(flon1),(int)falt,abs(alt1));
    file.println(buffer); //Write the 'contents' array to the end of the file.
    file.close();  //Close the file
    
    //flash LED
    digitalWrite(8, HIGH);   // set the LED on
    delay(500);
    digitalWrite(8, LOW);    // set the LED off     
    delay(5000); // wait 10 sec before writing next data point
  }
}

bool feedgps()
{
  while (nss.available())
  {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}

second sketch.

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

#define RXPIN 2
#define TXPIN 3
//Set this value equal to the baud rate of your GPS
#define GPSBAUD 38400
// Create an instance of the TinyGPS object
TinyGPS gps;
// Initialize the NewSoftSerial library to the pins you defined above
SoftwareSerial uart_gps(RXPIN, TXPIN);
// This is where you declare prototypes for the functions that will be 
// using the TinyGPS library.
void getgps(TinyGPS &gps);
#include <LiquidCrystal.h> // we need this library for the LCD commands // initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4,5,6,7,8,9); // define our LCD and which pins to user
/*
 * setup() - this function runs once when you turn your Arduino on
 * We initialize the serial connection with the computer
 */
void setup()
{
  Serial.begin(115200);  //Start the serial connection with the computer
                       //to view the result open the serial monitor 
                       lcd.begin(16, 2); // need to specify how many columns and rows are in the LCD unit
lcd.clear();      // this clears the LCD. You can use this at any time
 uart_gps.begin(GPSBAUD);
   Serial.println("");
  Serial.println("GPS in acquisition");
  Serial.println("...waiting for lock...");
  Serial.println("");
}
 
void loop()                     // run over and over again
{
while(uart_gps.available())     // While there is data on the RX pin...
  {
      int c = uart_gps.read();    // load the data into a variable...
      if(gps.encode(c))      // if there is a new valid sentence...
      {
        getgps(gps);         // then grab the data.
      }
  }
}

// The getgps function will get and print the values we want.
void getgps(TinyGPS &gps)
{
  // To get all of the data into varialbes that you can use in your code, 
  // all you need to do is define variables and query the object for the 
  // data. To see the complete list of functions see keywords.txt file in 
  // the TinyGPS and NewSoftSerial libs.
  
  // Define the variables that will be used
  float latitude, longitude;
  // Then call this function
  gps.f_get_position(&latitude, &longitude);
  // You can now print variables latitude and longitude
  Serial.print("Lat/Long: "); 
  Serial.print(latitude,5); 
  Serial.print(", "); 
  Serial.println(longitude,5);
  
  // Same goes for date and time
  int year;
  byte month, day, hour, minute, second, hundredths;
  gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
  // Print data and time
  Serial.print("Date: "); Serial.print(month, DEC); Serial.print("/"); 
  Serial.print(day, DEC); Serial.print("/"); Serial.print(year);
  Serial.print("  Time: "); Serial.print(hour, DEC); Serial.print(":"); 
  Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC); 
  Serial.print("."); Serial.println(hundredths, DEC);
  //Since month, day, hour, minute, second, and hundr
  
  // Here you can print the altitude and course values directly since 
  // there is only one value for the function
  Serial.print("Altitude (meters): "); Serial.println(gps.f_altitude());  
  /* Same goes for course
  Serial.print("Course (degrees): "); Serial.println(gps.f_course()); 
  // And same goes for speed
  Serial.print("Speed(kmph): "); Serial.println(gps.f_speed_kmph()); */
  Serial.println();
  
  // Here you can print statistics on the sentences.
  unsigned long chars;
  unsigned short sentences, failed_checksum;
  gps.stats(&chars, &sentences, &failed_checksum);
  //Serial.print("Failed Checksums: ");Serial.print(failed_checksum);
  //Serial.println(); Serial.println();
 
 lcd.clear();


lcd.setCursor(0,0);
//lcd.print("Lat/Long: ");
lcd.print(latitude,4);
  lcd.print(", "); 
  lcd.println(longitude,4);

 

lcd.setCursor(0,1);
//lcd.print("Date: "); lcd.print(month, DEC); lcd.print("/"); 
//  lcd.print(day, DEC); lcd.print("/"); lcd.print(year);
  //lcd.print("  Time: "); 
  lcd.print(hour, DEC); lcd.print(":"); 
  lcd.print(minute, DEC); lcd.print(":"); lcd.print(second, DEC); 
  lcd.print("."); lcd.print(hundredths, DEC);


}

thank you for any advice

What Arduino are you using? The SD library writes to the card in 512 byte blocks, so it needs a significant buffer to hold the data. You are reserving a lot of space to hold the GPS data, too. Perhaps you need to search for the FreeMemory function to see if memory (or the lack thereof) is an issue.

In the second sketch, you are printing lat and lon as floats. In the first, you are converting them to ints. Why?

Hi Paul

I have R2 uno board . I had trouble with the date format when the Buff size was 64. so I just went max to make sure i dont loose anything . i can make it smaller probably without trouble but would that cause GPS to be inaccurate ? since both sketchs run at 256?

Im not sure why im converting them . would thing be the reason for strange output ? this code is snippets of other example codes so it could have kreped in like that how would you state it?

thanx

Never mind I see what you mean . i changed it to float aswell now will see if it makes a difference. is there a way to print more of the decimal digits then the current 4 or 6 it does now ? accuracy for this sketch is a must have .

is there a way to print more of the decimal digits then the current 4 or 6 it does now ? accuracy for this sketch is a must have .

Printing more decimal places does not increase accuracy, if the value being printed is not accurate.

Where I guess I am at a loss to understand what you are doing is here. The GPS spits out a location as text. You convert that text string to a float, and then convert that to an int, and save the int. There is precision loss in each conversion. The most accurate data would be that spit out by the GPS. Just write that data to the SD card.

Hi Paul thank you for that comment now i know what you are looking at .

I tried pumping it straight to to the SD as it came from GPS but the format that was printing to the SD card was unreadable . by doing this . it was the only why i could get actual Lats and Longs from the SD card .

I actaul dont know of other way how to send it straight to the SD card .?

 //Break up float values into whole numbers(var) and decimals(var1) to be added to data
    int flat1 = (flat - (int)flat) * 10000;
    int flon1 = (flon - (int)flon) * 100000;

how would you do it ?

I tried pumping it straight to to the SD as it came from GPS but the format that was printing to the SD card was unreadable

Using what code?

In the second sketch, you are reading the data in the while loop in the loop() function. The characters are passed to the TinyGPS instance, using gps.encode().

If all you are trying to do is log the GPS data, it might be better not to use the TinyGPS class at all. Just collect the data in an array. When the incoming character is a $, the previous record is complete, so the collected data can be dumped to the SD card. Parsing the data when/where you use it would be faster than parsing it on the Arduino.

You might also look at the TinyGPS library, to see if there is a method to get the collected sentence, to log to the SD card. If not, add one.