Skip to content

Commit 512833e

Browse files
committed
Add Neo 6M GPS support - see below for notes
WIP, before anyone uses it besides Meshtastic the neo6M flag needs to be made a constructor parameter.
1 parent eb31fa3 commit 512833e

File tree

2 files changed

+127
-14
lines changed

2 files changed

+127
-14
lines changed

Diff for: src/SparkFun_Ublox_Arduino_Library.cpp

+123-14
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,45 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
746746
moduleQueried.headingOfMotion = true;
747747
moduleQueried.pDOP = true;
748748
}
749+
else if (msg->id == UBX_NAV_TIMEUTC && msg->len == 20)
750+
{
751+
timeOfWeek = extractLong(0);
752+
gpsMillisecond = extractLong(0) % 1000; //Get last three digits of iTOW
753+
// extractLong(4); // time accuracy estimate
754+
gpsYear = extractInt(12);
755+
gpsMonth = extractByte(14);
756+
gpsDay = extractByte(15);
757+
gpsHour = extractByte(16);
758+
gpsMinute = extractByte(17);
759+
gpsSecond = extractByte(18);
760+
gpsNanosecond = extractLong(8); //Includes milliseconds
761+
uint8_t valid = extractByte(19);
762+
bool gotTime = (valid & 4) ? true : false; // assume all other fields filled once we have TUTC
763+
764+
//Mark all datums as fresh (not read before)
765+
moduleQueried.gpsiTOW = gotTime; // valid tow
766+
moduleQueried.gpsYear = gotTime; // valid week num
767+
moduleQueried.gpsMonth = gotTime;
768+
moduleQueried.gpsDay = gotTime; // valid UTC
769+
moduleQueried.gpsHour = gotTime;
770+
moduleQueried.gpsMinute = gotTime;
771+
moduleQueried.gpsSecond = gotTime;
772+
moduleQueried.gpsNanosecond = gotTime;
773+
}
774+
else if (msg->id == UBX_NAV_POSLLH && msg->len == 28)
775+
{
776+
timeOfWeek = extractLong(0);
777+
longitude = extractLong(4);
778+
latitude = extractLong(8);
779+
altitude = extractLong(12);
780+
altitudeMSL = extractLong(16);
781+
782+
moduleQueried.gpsiTOW = true;
783+
moduleQueried.longitude = true;
784+
moduleQueried.latitude = true;
785+
moduleQueried.altitude = true;
786+
moduleQueried.altitudeMSL = true;
787+
}
749788
else if (msg->id == UBX_NAV_HPPOSLLH && msg->len == 36)
750789
{
751790
timeOfWeek = extractLong(4);
@@ -795,6 +834,12 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
795834
_debugSerial->print(F(" "));
796835
}
797836
}
837+
else {
838+
if (_printDebug == true)
839+
{
840+
_debugSerial->printf("Unexpected nav packet 0x%x\n", msg->id);
841+
}
842+
}
798843
break;
799844
}
800845
}
@@ -1232,7 +1277,7 @@ boolean SFE_UBLOX_GPS::saveConfigSelective(uint32_t configMask, uint16_t maxWait
12321277
packetCfg.payload[6] = (configMask >> 16) & 0xFF;
12331278
packetCfg.payload[7] = (configMask >> 24) & 0xFF;
12341279

1235-
if (sendCommand(packetCfg, maxWait) == false)
1280+
if (sendCommand(packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_SENT)
12361281
return (false); //If command send fails then bail
12371282

12381283
return (true);
@@ -2229,7 +2274,7 @@ uint8_t SFE_UBLOX_GPS::extractByte(uint8_t spotToStart)
22292274
uint16_t SFE_UBLOX_GPS::getYear(uint16_t maxWait)
22302275
{
22312276
if (moduleQueried.gpsYear == false)
2232-
getPVT(maxWait);
2277+
getT(maxWait);
22332278
moduleQueried.gpsYear = false; //Since we are about to give this to user, mark this data as stale
22342279
return (gpsYear);
22352280
}
@@ -2238,7 +2283,7 @@ uint16_t SFE_UBLOX_GPS::getYear(uint16_t maxWait)
22382283
uint8_t SFE_UBLOX_GPS::getMonth(uint16_t maxWait)
22392284
{
22402285
if (moduleQueried.gpsMonth == false)
2241-
getPVT(maxWait);
2286+
getT(maxWait);
22422287
moduleQueried.gpsMonth = false; //Since we are about to give this to user, mark this data as stale
22432288
return (gpsMonth);
22442289
}
@@ -2247,7 +2292,7 @@ uint8_t SFE_UBLOX_GPS::getMonth(uint16_t maxWait)
22472292
uint8_t SFE_UBLOX_GPS::getDay(uint16_t maxWait)
22482293
{
22492294
if (moduleQueried.gpsDay == false)
2250-
getPVT(maxWait);
2295+
getT(maxWait);
22512296
moduleQueried.gpsDay = false; //Since we are about to give this to user, mark this data as stale
22522297
return (gpsDay);
22532298
}
@@ -2256,7 +2301,7 @@ uint8_t SFE_UBLOX_GPS::getDay(uint16_t maxWait)
22562301
uint8_t SFE_UBLOX_GPS::getHour(uint16_t maxWait)
22572302
{
22582303
if (moduleQueried.gpsHour == false)
2259-
getPVT(maxWait);
2304+
getT(maxWait);
22602305
moduleQueried.gpsHour = false; //Since we are about to give this to user, mark this data as stale
22612306
return (gpsHour);
22622307
}
@@ -2265,7 +2310,7 @@ uint8_t SFE_UBLOX_GPS::getHour(uint16_t maxWait)
22652310
uint8_t SFE_UBLOX_GPS::getMinute(uint16_t maxWait)
22662311
{
22672312
if (moduleQueried.gpsMinute == false)
2268-
getPVT(maxWait);
2313+
getT(maxWait);
22692314
moduleQueried.gpsMinute = false; //Since we are about to give this to user, mark this data as stale
22702315
return (gpsMinute);
22712316
}
@@ -2274,7 +2319,7 @@ uint8_t SFE_UBLOX_GPS::getMinute(uint16_t maxWait)
22742319
uint8_t SFE_UBLOX_GPS::getSecond(uint16_t maxWait)
22752320
{
22762321
if (moduleQueried.gpsSecond == false)
2277-
getPVT(maxWait);
2322+
getT(maxWait);
22782323
moduleQueried.gpsSecond = false; //Since we are about to give this to user, mark this data as stale
22792324
return (gpsSecond);
22802325
}
@@ -2283,7 +2328,7 @@ uint8_t SFE_UBLOX_GPS::getSecond(uint16_t maxWait)
22832328
uint16_t SFE_UBLOX_GPS::getMillisecond(uint16_t maxWait)
22842329
{
22852330
if (moduleQueried.gpsiTOW == false)
2286-
getPVT(maxWait);
2331+
getT(maxWait);
22872332
moduleQueried.gpsiTOW = false; //Since we are about to give this to user, mark this data as stale
22882333
return (gpsMillisecond);
22892334
}
@@ -2292,11 +2337,13 @@ uint16_t SFE_UBLOX_GPS::getMillisecond(uint16_t maxWait)
22922337
int32_t SFE_UBLOX_GPS::getNanosecond(uint16_t maxWait)
22932338
{
22942339
if (moduleQueried.gpsNanosecond == false)
2295-
getPVT(maxWait);
2340+
getT(maxWait);
22962341
moduleQueried.gpsNanosecond = false; //Since we are about to give this to user, mark this data as stale
22972342
return (gpsNanosecond);
22982343
}
22992344

2345+
bool neo6M = true;
2346+
23002347
//Get the latest Position/Velocity/Time solution and fill all global variables
23012348
boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait)
23022349
{
@@ -2338,10 +2385,72 @@ boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait)
23382385
}
23392386
}
23402387

2388+
// Update our time info (using correct call for the chipset)
2389+
boolean SFE_UBLOX_GPS::getT(uint16_t maxWait)
2390+
{
2391+
return !neo6M ? getPVT(maxWait) : getTIMEUTC(maxWait);
2392+
}
2393+
2394+
// Update our time info (using correct call for the chipset)
2395+
boolean SFE_UBLOX_GPS::getP(uint16_t maxWait)
2396+
{
2397+
return !neo6M ? getPVT(maxWait) : getPOSLLH(maxWait);
2398+
}
2399+
2400+
//Get time (supported on NEO 6M)
2401+
boolean SFE_UBLOX_GPS::getTIMEUTC(uint16_t maxWait)
2402+
{
2403+
debugPrintln((char *)F("getTIMEUTC: Polling"));
2404+
2405+
//The GPS is not automatically reporting navigation position so we have to poll explicitly
2406+
packetCfg.cls = UBX_CLASS_NAV;
2407+
packetCfg.id = UBX_NAV_TIMEUTC;
2408+
packetCfg.len = 0;
2409+
//packetCfg.startingSpot = 20; //Begin listening at spot 20 so we can record up to 20+MAX_PAYLOAD_SIZE = 84 bytes Note:now hard-coded in processUBX
2410+
2411+
//The data is parsed as part of processing the response
2412+
sfe_ublox_status_e retVal = sendCommand(packetCfg, maxWait);
2413+
2414+
if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
2415+
return (true);
2416+
2417+
if (_printDebug == true)
2418+
{
2419+
_debugSerial->print(F("getTIMEUTC retVal: "));
2420+
_debugSerial->println(statusString(retVal));
2421+
}
2422+
return (false);
2423+
}
2424+
2425+
//Get posllh (supported on NEO 6M)
2426+
boolean SFE_UBLOX_GPS::getPOSLLH(uint16_t maxWait)
2427+
{
2428+
debugPrintln((char *)F("getPOSLLH: Polling"));
2429+
2430+
//The GPS is not automatically reporting navigation position so we have to poll explicitly
2431+
packetCfg.cls = UBX_CLASS_NAV;
2432+
packetCfg.id = UBX_NAV_POSLLH;
2433+
packetCfg.len = 0;
2434+
//packetCfg.startingSpot = 20; //Begin listening at spot 20 so we can record up to 20+MAX_PAYLOAD_SIZE = 84 bytes Note:now hard-coded in processUBX
2435+
2436+
//The data is parsed as part of processing the response
2437+
sfe_ublox_status_e retVal = sendCommand(packetCfg, maxWait);
2438+
2439+
if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
2440+
return (true);
2441+
2442+
if (_printDebug == true)
2443+
{
2444+
_debugSerial->print(F("getPOSLLH retVal: "));
2445+
_debugSerial->println(statusString(retVal));
2446+
}
2447+
return (false);
2448+
}
2449+
23412450
uint32_t SFE_UBLOX_GPS::getTimeOfWeek(uint16_t maxWait /* = 250*/)
23422451
{
23432452
if (moduleQueried.gpsiTOW == false)
2344-
getPVT(maxWait);
2453+
getT(maxWait);
23452454
moduleQueried.gpsiTOW = false; //Since we are about to give this to user, mark this data as stale
23462455
return (timeOfWeek);
23472456
}
@@ -2439,7 +2548,7 @@ uint32_t SFE_UBLOX_GPS::getPositionAccuracy(uint16_t maxWait)
24392548
int32_t SFE_UBLOX_GPS::getLatitude(uint16_t maxWait)
24402549
{
24412550
if (moduleQueried.latitude == false)
2442-
getPVT(maxWait);
2551+
getP(maxWait);
24432552
moduleQueried.latitude = false; //Since we are about to give this to user, mark this data as stale
24442553
moduleQueried.all = false;
24452554

@@ -2451,7 +2560,7 @@ int32_t SFE_UBLOX_GPS::getLatitude(uint16_t maxWait)
24512560
int32_t SFE_UBLOX_GPS::getLongitude(uint16_t maxWait)
24522561
{
24532562
if (moduleQueried.longitude == false)
2454-
getPVT(maxWait);
2563+
getP(maxWait);
24552564
moduleQueried.longitude = false; //Since we are about to give this to user, mark this data as stale
24562565
moduleQueried.all = false;
24572566

@@ -2462,7 +2571,7 @@ int32_t SFE_UBLOX_GPS::getLongitude(uint16_t maxWait)
24622571
int32_t SFE_UBLOX_GPS::getAltitude(uint16_t maxWait)
24632572
{
24642573
if (moduleQueried.altitude == false)
2465-
getPVT(maxWait);
2574+
getP(maxWait);
24662575
moduleQueried.altitude = false; //Since we are about to give this to user, mark this data as stale
24672576
moduleQueried.all = false;
24682577

@@ -2475,7 +2584,7 @@ int32_t SFE_UBLOX_GPS::getAltitude(uint16_t maxWait)
24752584
int32_t SFE_UBLOX_GPS::getAltitudeMSL(uint16_t maxWait)
24762585
{
24772586
if (moduleQueried.altitudeMSL == false)
2478-
getPVT(maxWait);
2587+
getP(maxWait);
24792588
moduleQueried.altitudeMSL = false; //Since we are about to give this to user, mark this data as stale
24802589
moduleQueried.all = false;
24812590

Diff for: src/SparkFun_Ublox_Arduino_Library.h

+4
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,10 @@ class SFE_UBLOX_GPS
479479
boolean assumeAutoPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already
480480
boolean setAutoPVT(boolean enabled, uint16_t maxWait = 250); //Enable/disable automatic PVT reports at the navigation frequency
481481
boolean getPVT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
482+
boolean getT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
483+
boolean getP(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
484+
boolean getTIMEUTC(uint16_t maxWait = getPVTmaxWait); //Query module for current time Neo6M only. Retruns true if new PVT is available.
485+
boolean getPOSLLH(uint16_t maxWait = getPVTmaxWait); //Query module for current time Neo6M only. Retruns true if new PVT is available.
482486
boolean setAutoPVT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = 250); //Enable/disable automatic PVT reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update
483487
boolean getHPPOSLLH(uint16_t maxWait = getHPPOSLLHmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
484488
void flushPVT(); //Mark all the PVT data as read/stale. This is handy to get data alignment after CRC failure

0 commit comments

Comments
 (0)