Skip to content

Commit

Permalink
Fixed problem reported by dbrooke where small positive latitudes and …
Browse files Browse the repository at this point in the history
…longitudes (less than 1 degree) were reported as negative.
  • Loading branch information
mikalhart-intel committed Nov 26, 2013
1 parent ba04655 commit d05250f
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 43 deletions.
35 changes: 15 additions & 20 deletions TinyGPS++.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,14 @@ int32_t TinyGPSPlus::parseDecimal(const char *term)

// static
// Parse degrees in that funny NMEA format DDMM.MMMM
void TinyGPSPlus::parseDegrees(const char *term, int16_t &degrees, uint32_t &billionths)
void TinyGPSPlus::parseDegrees(const char *term, RawDegrees &deg)
{
uint32_t leftOfDecimal = (uint32_t)atol(term);
uint16_t minutes = (uint16_t)(leftOfDecimal % 100);
uint32_t multiplier = 10000000UL;
uint32_t tenMillionthsOfMinutes = minutes * multiplier;

degrees = (int16_t)(leftOfDecimal / 100);
deg.deg = (int16_t)(leftOfDecimal / 100);

while (isdigit(*term))
++term;
Expand All @@ -146,7 +146,8 @@ void TinyGPSPlus::parseDegrees(const char *term, int16_t &degrees, uint32_t &bil
tenMillionthsOfMinutes += (*term - '0') * multiplier;
}

billionths = (5 * tenMillionthsOfMinutes + 1) / 3;
deg.billionths = (5 * tenMillionthsOfMinutes + 1) / 3;
deg.negative = false;
}

#define COMBINE(sentence_type, term_number) (((unsigned)(sentence_type) << 5) | term_number)
Expand Down Expand Up @@ -233,21 +234,19 @@ bool TinyGPSPlus::endOfTermHandler()
break;
case COMBINE(GPS_SENTENCE_GPRMC, 3): // Latitude
case COMBINE(GPS_SENTENCE_GPGGA, 2):
location.setLatitude(term);
location.setLatitude(term);
break;
case COMBINE(GPS_SENTENCE_GPRMC, 4): // N/S
case COMBINE(GPS_SENTENCE_GPGGA, 3):
if (term[0] == 'S')
location.iNewLatDegrees = -location.iNewLatDegrees;
location.rawNewLatData.negative = term[0] == 'S';
break;
case COMBINE(GPS_SENTENCE_GPRMC, 5): // Longitude
case COMBINE(GPS_SENTENCE_GPGGA, 4):
location.setLongitude(term);
break;
case COMBINE(GPS_SENTENCE_GPRMC, 6): // E/W
case COMBINE(GPS_SENTENCE_GPGGA, 5):
if (term[0] == 'W')
location.iNewLngDegrees = -location.iNewLngDegrees;
location.rawNewLngData.negative = term[0] == 'W';
break;
case COMBINE(GPS_SENTENCE_GPRMC, 7): // Speed (GPRMC)
speed.set(term);
Expand Down Expand Up @@ -335,38 +334,34 @@ const char *TinyGPSPlus::cardinal(double course)

void TinyGPSLocation::commit()
{
iLatDegrees = iNewLatDegrees;
uLatBillionths = uNewLatBillionths;
iLngDegrees = iNewLngDegrees;
uLngBillionths = uNewLngBillionths;
rawLatData = rawNewLatData;
rawLngData = rawNewLngData;
lastCommitTime = millis();
valid = updated = true;
}

void TinyGPSLocation::setLatitude(const char *term)
{
TinyGPSPlus::parseDegrees(term, iNewLatDegrees, uNewLatBillionths);
TinyGPSPlus::parseDegrees(term, rawNewLatData);
}

void TinyGPSLocation::setLongitude(const char *term)
{
TinyGPSPlus::parseDegrees(term, iNewLngDegrees, uNewLngBillionths);
TinyGPSPlus::parseDegrees(term, rawNewLngData);
}

double TinyGPSLocation::lat()
{
updated = false;
return iLatDegrees > 0 ?
(iLatDegrees + uLatBillionths / 1000000000.0) :
(iLatDegrees - uLatBillionths / 1000000000.0);
double ret = rawLatData.deg + rawLatData.billionths / 1000000000.0;
return rawLatData.negative ? -ret : ret;
}

double TinyGPSLocation::lng()
{
updated = false;
return iLngDegrees > 0 ?
(iLngDegrees + uLngBillionths / 1000000000.0) :
(iLngDegrees - uLngBillionths / 1000000000.0);
double ret = rawLngData.deg + rawLngData.billionths / 1000000000.0;
return rawLngData.negative ? -ret : ret;
}

void TinyGPSDate::commit()
Expand Down
25 changes: 15 additions & 10 deletions TinyGPS++.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,34 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define _GPS_FEET_PER_METER 3.2808399
#define _GPS_MAX_FIELD_SIZE 15

struct RawDegrees
{
uint16_t deg;
uint32_t billionths;
bool negative;
public:
RawDegrees() : deg(0), billionths(0), negative(false)
{}
};

struct TinyGPSLocation
{
friend class TinyGPSPlus;
public:
bool isValid() const { return valid; }
bool isUpdated() const { return updated; }
uint32_t age() const { return valid ? millis() - lastCommitTime : (uint32_t)ULONG_MAX; }

int16_t rawLatDegrees() { updated = false; return iLatDegrees; }
int16_t rawLngDegrees() { updated = false; return iLngDegrees; }
uint32_t rawLatBillionths() { updated = false; return uLatBillionths; }
uint32_t rawLngBillionths() { updated = false; return uLngBillionths; }
const RawDegrees &rawLat() { updated = false; return rawLatData; }
const RawDegrees &rawLng() { updated = false; return rawLngData; }
double lat();
double lng();

TinyGPSLocation() : valid(false), updated(false),
iLatDegrees(0), iLngDegrees(0), uLatBillionths(0), uLngBillionths(0)
TinyGPSLocation() : valid(false), updated(false)
{}

private:
bool valid, updated;
int16_t iLatDegrees, iNewLatDegrees, iLngDegrees, iNewLngDegrees;
uint32_t uLatBillionths, uNewLatBillionths, uLngBillionths, uNewLngBillionths;
RawDegrees rawLatData, rawLngData, rawNewLatData, rawNewLngData;
uint32_t lastCommitTime;
void commit();
void setLatitude(const char *term);
Expand Down Expand Up @@ -229,7 +234,7 @@ class TinyGPSPlus
static const char *cardinal(double course);

static int32_t parseDecimal(const char *term);
static void parseDegrees(const char *term, int16_t &degrees, uint32_t &billionths);
static void parseDegrees(const char *term, RawDegrees &deg);

uint32_t charsProcessed() const { return encodedCharCount; }
uint32_t sentencesWithFix() const { return sentencesWithFixCount; }
Expand Down
2 changes: 1 addition & 1 deletion examples/BasicExample/BasicExample.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

// A sample NMEA stream.
char *gpsStream =
const char *gpsStream =
"$GPRMC,045103.000,A,3014.1984,N,09749.2872,W,0.67,161.46,030913,,,A*7C\r\n"
"$GPGGA,045104.000,3014.1985,N,09749.2873,W,1,09,1.2,211.6,M,-22.5,M,,0000*62\r\n"
"$GPRMC,045200.000,A,3014.3820,N,09748.9514,W,36.88,65.02,030913,,,A*77\r\n"
Expand Down
2 changes: 1 addition & 1 deletion examples/DeviceExample/DeviceExample.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const unsigned long GPSBaud = 4800;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;
Expand Down
2 changes: 1 addition & 1 deletion examples/FullExample/FullExample.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const unsigned long GPSBaud = 4800;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;
Expand Down
16 changes: 9 additions & 7 deletions examples/KitchenSink/KitchenSink.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const unsigned long GPSBaud = 4800;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;
Expand Down Expand Up @@ -40,13 +40,15 @@ void loop()
Serial.print(F("LOCATION Fix Age="));
Serial.print(gps.location.age());
Serial.print(F("ms Raw Lat="));
Serial.print(gps.location.rawLatDegrees());
Serial.print(gps.location.rawLat().negative ? "-" : "+");
Serial.print(gps.location.rawLat().deg);
Serial.print("[+");
Serial.print(gps.location.rawLatBillionths());
Serial.print(gps.location.rawLat.billionths());
Serial.print(F(" billionths], Raw Long="));
Serial.print(gps.location.rawLngDegrees());
Serial.print(gps.location.rawLng().negative ? "-" : "+");
Serial.print(gps.location.rawLng().deg);
Serial.print("[+");
Serial.print(gps.location.rawLngBillionths());
Serial.print(gps.location.rawLng.billionths());
Serial.print(F(" billionths], Lat="));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" Long="));
Expand Down Expand Up @@ -85,7 +87,7 @@ void loop()

else if (gps.speed.isUpdated())
{
Serial.print(F("SPEED Fix Age=%ulms Raw=%ul Knots=%f MPH=%f m/s=%f km/h=%f"));
Serial.print(F("SPEED Fix Age="));
Serial.print(gps.speed.age());
Serial.print(F("ms Raw="));
Serial.print(gps.speed.value());
Expand Down Expand Up @@ -184,4 +186,4 @@ void loop()
last = millis();
Serial.println();
}
}
}
2 changes: 1 addition & 1 deletion examples/SatElevTracker/SatElevTracker.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
4800-baud serial GPS device hooked up on pins 4(RX) and 3(TX).
*/
static const int RXPin = 4, TXPin = 3;
static const unsigned long GPSBaud = 4800;
static const uint32_t GPSBaud = 4800;
static const int MAX_SATELLITES = 40;
static const int PAGE_LENGTH = 40;

Expand Down
2 changes: 1 addition & 1 deletion examples/SatelliteTracker/SatelliteTracker.ino
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
4800-baud serial GPS device hooked up on pins 4(RX) and 3(TX).
*/
static const int RXPin = 4, TXPin = 3;
static const unsigned long GPSBaud = 4800;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;
Expand Down
2 changes: 1 addition & 1 deletion examples/UsingCustomFields/UsingCustomFields.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
4800-baud serial GPS device hooked up on pins 4(RX) and 3(TX).
*/
static const int RXPin = 4, TXPin = 3;
static const unsigned long GPSBaud = 4800;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;
Expand Down

0 comments on commit d05250f

Please sign in to comment.