if the timestamp is a float and the latitude and longitude as well, then sure a
float gpsRecords[100][3];
would do but it's not the best approach and you would need to know that index 0 is the timestamp, index 1 is the latitude etc... It does not make the code very readable
Floats (and doubles on some Arduinos) can be a bad choice for latitude and longitude because the "float data type has only 6-7 decimal digits of precision" so you only can store positions with maybe 100-1000m precision. Storing microdegrees in a long would get you 9 significant figures and 11cm precision.
Many GPS using NMEA outputs coordinates in the ddmm.mmmmm format so only with 5 digits, si if you want more u-blox (and others probably) offers a setting to increase the NMEA precision from 5 decimal places to 7 (the "High precision NMEA" checkbox in their tool)
u-blox has also a binary protocol (UBX protocol) which can output up to 8 digits of precision
Yes. Parallel arrays work well enough and builds only on knowing what an array is. The syntax for using them remains simple.
Then one day it gets a bit out of hand, or you start using pointers and throwing structured variables all over the place and now the code will be simpler if it uses structs.
Easier for beginners and in some cases for not-anymore-beginnners… in the same sense that I might still just copy/paste/edit a code block knowing I should be yelling at myself to think rather in terms of writing a function.
Yes. i am facing the question here, I can take GPS coordinates by:
String dataStringA = (gps.location.lat(), 8); got me 8 decimal number, is this a true coordinate?
I am using neo6m.
can't get long or double coordinates numbers: double dataStringA = (gps.location.lat(), 8); got nothing.
and long dataStringA = (gps.location.lat(), 8); got nothing.
Yes.
I used TinyGPSPlus.h example FullExample, which works well to PRINT Latitude/Longitude every thing.
if I like to use the number of Latitude/Longitude, got stucked.
the code has: dataString2 = String(gps.location.lat(), 6); // got 6 decimal number;
I tested: long ss = gps.location.lat(); // got 2 decimal; double ss = gps.location.lat(); // got 2 decimal;
#include <TinyGPSPlus.h>
#include <SPI.h>
#define RXD2 16
#define TXD2 17
HardwareSerial neogps(1);
//......................................
int GPSdataA[2] = {};
int GPSdataAI;
//........................................
//static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 4800;
// The TinyGPSPlus object
TinyGPSPlus gps;
// The serial connection to the GPS device
//SoftwareSerial ss(RXPin, TXPin);
void setup()
{
Serial.begin(115200);
//ss.begin(GPSBaud);
neogps.begin(9600, SERIAL_8N1, RXD2, TXD2);
delay(2000);
Serial.println(F("FullExample.ino"));
Serial.println(F("An extensive example of many interesting TinyGPSPlus features"));
Serial.print(F("Testing TinyGPSPlus library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
Serial.println(F("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"));
Serial.println(F(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail"));
Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));
}
void loop()
{
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printInt(gps.location.age(), gps.location.isValid(), 5);
printDateTime(gps.date, gps.time);
printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);
//...........................
long ss2 = gps.location.lat(); //got 2 decimal;
double ss3 = gps.location.lat(); //got 2 decimal;
long ss4 = long(gps.location.lat()); //got 2 decimal;
double ss5 = double(gps.location.lat()); //got 2 decimal;
Serial.print("82ss2=");
Serial.println(ss2);
Serial.print("85ss3=");
Serial.println(ss3);
Serial.print("88ss4=");
Serial.println(ss4);
Serial.print("91ss5=");
Serial.println(ss5);
//.............................
unsigned long distanceKmToLondon =
(unsigned long)TinyGPSPlus::distanceBetween(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON) / 1000;
printInt(distanceKmToLondon, gps.location.isValid(), 9);
double courseToLondon =
TinyGPSPlus::courseTo(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON);
printFloat(courseToLondon, gps.location.isValid(), 7, 2);
const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);
printInt(gps.charsProcessed(), true, 6);
printInt(gps.sentencesWithFix(), true, 10);
printInt(gps.failedChecksum(), true, 9);
Serial.println();
smartDelay(1000);
if (millis() > 5000 && gps.charsProcessed() < 10)
Serial.println(F("No GPS data received: check wiring"));
}
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (neogps.available())
gps.encode(neogps.read());
} while (millis() - start < ms);
}
static void printFloat(float val, bool valid, int len, int prec)
{
if (!valid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i = flen; i < len; ++i)
Serial.print(' ');
}
smartDelay(0);
}
static void printInt(unsigned long val, bool valid, int len)
{
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i = strlen(sz); i < len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len - 1] = ' ';
Serial.print(sz);
smartDelay(0);
}
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
if (!d.isValid())
{
Serial.print(F("********** "));
}
else
{
char sz[32];
//sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
sprintf(sz, "%02d_%02d_%04d ", d.month(), d.day(), d.year());
//.........................................
GPSdataAI = atoi(sz);
GPSdataA[0] = GPSdataAI;
Serial.print("192GPSdataA[0] ="); //
Serial.println(GPSdataA[0]);
// Serial.print("197GPSdataA[0] ="); // gps.date
// Serial.println(gps.date);
Serial.print("200sz ="); //
Serial.println(sz);
//......................................
Serial.print(sz);
}
if (!t.isValid())
{
Serial.print(F("******** "));
}
else
{
char sz[32];
sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
//.........................................
GPSdataAI = atoi(sz);
GPSdataA[1] = GPSdataAI;
Serial.print("212GPSdataA[1] =");
Serial.println(GPSdataA[1]);
//......................................
Serial.print(sz);
}
printInt(d.age(), d.isValid(), 5);
smartDelay(0);
}
static void printStr(const char *str, int len)
{
int slen = strlen(str);
for (int i = 0; i < len; ++i)
Serial.print(i < slen ? str[i] : ' ');
smartDelay(0);
}
also, I got GPS data on SD as:
......................
the first few lines always missing some data when used: if (gps.location.isValid()) , how to avoid it?
but if use: if (gps.satellites.value() > 4) never get any thing, why?