Skip to content

Commit 544d2ac

Browse files
authored
Merge pull request #374 from openbikesensor/neo8m_experiments
Changes to the GPS logic for newer GPS.
2 parents de7fde5 + ae10650 commit 544d2ac

File tree

6 files changed

+210
-29
lines changed

6 files changed

+210
-29
lines changed

src/OpenBikeSensorFirmware.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,10 @@ void setup() {
399399
esp_bt_mem_release(ESP_BT_MODE_BTDM)); // no bluetooth at all here.
400400

401401
delay(200);
402-
startServer(&cfg);
402+
obsDisplay->showTextOnGrid(2, obsDisplay->newLine(), "Start GPS...");
403403
gps.begin();
404404
gps.setStatisticsIntervalInSeconds(2); // ??
405+
startServer(&cfg);
405406
while (true) {
406407
yield();
407408
serverLoop();
@@ -446,7 +447,6 @@ void setup() {
446447
gps.handle();
447448

448449
setupBluetooth(cfg, trackUniqueIdentifier);
449-
450450
obsDisplay->showTextOnGrid(2, obsDisplay->newLine(), "Wait for GPS");
451451
obsDisplay->newLine();
452452
gps.handle();

src/configServer.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ static const char* const development =
230230
static const char* const rebootIndex =
231231
"<h3>Device reboots now.</h3>";
232232

233+
static const char* const gpsColdIndex =
234+
"<h3>GPS cold start</h3>";
235+
233236
// #########################################
234237
// Wifi
235238
// #########################################
@@ -456,6 +459,7 @@ static void handleNotFound(HTTPRequest * req, HTTPResponse * res);
456459
static void handleIndex(HTTPRequest * req, HTTPResponse * res);
457460
static void handleAbout(HTTPRequest * req, HTTPResponse * res);
458461
static void handleReboot(HTTPRequest * req, HTTPResponse * res);
462+
static void handleColdStartGPS(HTTPRequest * req, HTTPResponse * res);
459463
static void handleBackup(HTTPRequest * req, HTTPResponse * res);
460464
static void handleBackupDownload(HTTPRequest * req, HTTPResponse * res);
461465
static void handleBackupRestore(HTTPRequest * req, HTTPResponse * res);
@@ -546,6 +550,7 @@ void registerPages(HTTPServer * httpServer) {
546550
httpServer->registerNode(new ResourceNode("/", HTTP_GET, handleIndex));
547551
httpServer->registerNode(new ResourceNode("/about", HTTP_GET, handleAbout));
548552
httpServer->registerNode(new ResourceNode("/reboot", HTTP_GET, handleReboot));
553+
httpServer->registerNode(new ResourceNode("/cold", HTTP_GET, handleColdStartGPS));
549554
httpServer->registerNode(new ResourceNode("/settings/backup", HTTP_GET, handleBackup));
550555
httpServer->registerNode(new ResourceNode("/settings/backup.json", HTTP_GET, handleBackupDownload));
551556
httpServer->registerNode(new ResourceNode("/settings/restore", HTTP_POST, handleBackupRestore));
@@ -724,7 +729,8 @@ static void wifiConnectedActions() {
724729
if (WiFiClass::status() == WL_CONNECTED) {
725730
TimeUtils::setClockByNtpAndWait(WiFi.gatewayIP().toString().c_str());
726731
}
727-
if (SD.begin() && WiFiClass::status() == WL_CONNECTED) {
732+
if (SD.begin() && WiFiClass::status() == WL_CONNECTED
733+
&& (!gps.moduleIsAlive() || gps.is_neo6())) {
728734
AlpData::update(obsDisplay);
729735
}
730736

@@ -1065,6 +1071,8 @@ static void handleAbout(HTTPRequest *req, HTTPResponse * res) {
10651071
page += keyValue("GPS satellites", gps.getValidSatellites());
10661072
page += keyValue("GPS uptime", gps.getUptime(), "ms");
10671073
page += keyValue("GPS noise level", gps.getLastNoiseLevel());
1074+
page += keyValue("GPS Antenna Gain", gps.getLastAntennaGain());
1075+
page += keyValue("GPS Jamming Level", gps.getLastJamInd());
10681076
page += keyValue("GPS baud rate", gps.getBaudRate());
10691077
page += keyValue("GPS ALP bytes", gps.getNumberOfAlpBytesSent());
10701078
page += keyValue("GPS messages", gps.getMessagesHtml());
@@ -1123,6 +1131,14 @@ static void handleReboot(HTTPRequest *, HTTPResponse * res) {
11231131
ESP.restart();
11241132
}
11251133

1134+
static void handleColdStartGPS(HTTPRequest *, HTTPResponse * res) {
1135+
String html = createPage(gpsColdIndex);
1136+
html = replaceDefault(html, "Navigation");
1137+
sendHtml(res, html);
1138+
gps.coldStartGps();
1139+
res->finalize();
1140+
}
1141+
11261142

11271143
static void handleBackup(HTTPRequest *, HTTPResponse * res) {
11281144
String html = createPage(backupIndex, xhrUpload);

src/gps.cpp

Lines changed: 143 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,63 @@ const String Gps::INF_SEVERITY_STRING[] = {
3131
String("TST"), String("DBG")
3232
};
3333

34+
bool Gps::is_neo6() const {
35+
if (String(hwString).substring(0,4) == String("0004")) {
36+
return true;
37+
}
38+
return false;
39+
}
40+
41+
bool Gps::is_neo8() const {
42+
if (String(hwString).substring(0,4) == String("0008")) {
43+
return true;
44+
}
45+
return false;
46+
}
47+
48+
bool Gps::is_neo10() const {
49+
if (String(hwString).substring(0,4) == String("000A")) {
50+
return true;
51+
}
52+
return false;
53+
}
54+
55+
String Gps::hw() const {
56+
if (is_neo6()){
57+
return "Neo6";
58+
}
59+
if (is_neo8()){
60+
return "Neo8";
61+
}
62+
if (is_neo10()) {
63+
return "NeoA";
64+
}
65+
return "Neo" + String(hwString).substring(3,4);
66+
}
67+
3468
void Gps::begin() {
3569
setBaud();
3670
softResetGps();
3771
if (mGpsNeedsConfigUpdate) {
3872
configureGpsModule();
3973
}
40-
enableAlpIfDataIsAvailable();
4174
pollStatistics();
75+
if((!is_neo6()) || (!SD.exists(AID_INI_DATA_FILE_NAME))) {
76+
// we're on a non-6 neo and avoid AID_INI because is deprecated
77+
// or we're on a neo6 but last boot we didn't get far enough to receive fresh
78+
// ALP_INI data after initializing
79+
// so restart GPS for good measure.
80+
if (is_neo6()) log_i("We found no AID_INI on with neo6 on boot - coldstart gps in case its in a state where it doesn't get fixes");
81+
if (!is_neo6()) log_i("Coldstart because we found that newer neos profit from that.");
82+
83+
coldStartGps();
84+
}
85+
pollStatistics();
86+
87+
if (is_neo6()) {
88+
enableAlpIfDataIsAvailable();
89+
}
90+
4291
if (mLastTimeTimeSet == 0) {
4392
#ifdef UBX_M10
4493
setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1, 1);
@@ -293,7 +342,6 @@ void Gps::softResetGps() {
293342
log_i("Soft-RESET GPS!");
294343
handle();
295344
const uint8_t UBX_CFG_RST[] = {0x00, 0x00, 0x02, 0x00}; // WARM START
296-
// const uint8_t UBX_CFG_RST[] = {0xFF, 0xFF, 0x02, 0x00}; // Cold START
297345
// we had the case where the reset took several seconds
298346
// see https://github.com/openbikesensor/OpenBikeSensorFirmware/issues/309
299347
// Newer firmware (like M10 and likely also M8) will not ack this
@@ -304,6 +352,20 @@ void Gps::softResetGps() {
304352
log_i("Soft-RESET GPS! Done");
305353
}
306354

355+
void Gps::coldStartGps() {
356+
log_i("Cold-Start GPS!");
357+
handle();
358+
const uint8_t UBX_CFG_RST[] = {0xFF, 0xFF, 0x00, 0x00};
359+
// we had the case where the reset took several seconds
360+
// see https://github.com/openbikesensor/OpenBikeSensorFirmware/issues/309
361+
// Newer firmware (like M10 and likely also M8) will not ack this
362+
// message so we do not wait for the ACK
363+
sendUbx(UBX_MSG::CFG_RST, UBX_CFG_RST, 4);
364+
waitForData(3000);
365+
handle();
366+
log_i("Cold Start GPS! Done");
367+
}
368+
307369
/* There had been changes for the satellites used for SBAS
308370
* in europe since the firmware of our GPS module was built
309371
* we configure the module to use the 2 satellites that are
@@ -344,11 +406,15 @@ void Gps::enableAlpIfDataIsAvailable() {
344406
/* Poll or refresh one time statistics, also spends some time
345407
* to collect the results.
346408
*/
409+
347410
void Gps::pollStatistics() {
348-
handle();
349-
sendUbx(UBX_MSG::AID_ALP);
350411
handle();
351412
sendUbx(UBX_MSG::MON_VER);
413+
handle(20);
414+
if (is_neo6()){
415+
// AID_ALP is a neo6-only thing
416+
sendUbx(UBX_MSG::AID_ALP);
417+
}
352418
handle();
353419
sendUbx(UBX_MSG::MON_HW);
354420
handle();
@@ -777,21 +843,35 @@ int32_t Gps::getMessagesWithFailedCrcCount() const {
777843
}
778844

779845
void Gps::showWaitStatus(DisplayDevice const * display) const {
846+
static bool clear = false;
847+
if (!is_neo6() && !clear) {
848+
obsDisplay->clear();
849+
clear = true;
850+
}
780851
String satellitesString[2];
781852
if (mValidMessagesReceived == 0) { // could not get any valid char from GPS module
782853
satellitesString[0] = "OFF?";
783854
} else if (mLastTimeTimeSet == 0) {
784-
satellitesString[0] = String(mCurrentGpsRecord.mSatellitesUsed) + "sats SN:" + String(mLastNoiseLevel);
855+
satellitesString[0] = "aGain:" + String(mLastGain);
856+
satellitesString[1] = String(mCurrentGpsRecord.mSatellitesUsed) + "sats SN:" + String(mLastNoiseLevel);
785857
} else {
786-
satellitesString[0] = "GPS " + TimeUtils::timeToString();
858+
satellitesString[0] = String(hw()).substring(1) + TimeUtils::timeToString();
787859
satellitesString[1] = String(mCurrentGpsRecord.mSatellitesUsed) + "sats SN:" + String(mLastNoiseLevel);
788860
}
861+
obsDisplay->showTextOnGrid(2, display->currentLine() - 1, satellitesString[0]);
862+
obsDisplay->showTextOnGrid(2, display->currentLine(), satellitesString[1]);
863+
if (!is_neo6()){
864+
obsDisplay->showTextOnGrid(0, 1, String(hw())+" GPS");
865+
obsDisplay->showTextOnGrid(2, 1, "HDOP: " + getHdopAsString() + "D");
789866

790-
if (satellitesString[1].isEmpty()) {
791-
obsDisplay->showTextOnGrid(2, display->currentLine(), satellitesString[0]);
792-
} else {
793-
obsDisplay->showTextOnGrid(2, display->currentLine() - 1, satellitesString[0]);
794-
obsDisplay->showTextOnGrid(2, display->currentLine(), satellitesString[1]);
867+
obsDisplay->showTextOnGrid(0, 2, "Jam: " + String(mLastJamInd));
868+
obsDisplay->showTextOnGrid(2, 2, "Msgs: " + String(mValidMessagesReceived));
869+
obsDisplay->showTextOnGrid(2, 3, "Fix: " + String(mCurrentGpsRecord.mFixStatus) + "D");
870+
obsDisplay->showTextOnGrid(0, 3, "lat,lon:");
871+
872+
873+
obsDisplay->showTextOnGrid(0, 4, String(mCurrentGpsRecord.mLatitude));
874+
obsDisplay->showTextOnGrid(0, 5, String(mCurrentGpsRecord.mLongitude));
795875
}
796876
}
797877

@@ -1098,12 +1178,40 @@ void Gps::parseUbxMessage() {
10981178
String(mGpsBuffer.monVer.swVersion).c_str(),
10991179
String(mGpsBuffer.monVer.hwVersion).c_str(),
11001180
mGpsBuffer.ubxHeader.length);
1181+
for (int i = 0; i < sizeof(hwString) && i < sizeof(mGpsBuffer.monVer.hwVersion) ; i++) {
1182+
hwString[i]=mGpsBuffer.monVer.hwVersion[i];
1183+
}
11011184
}
11021185
break;
11031186
case (uint16_t) UBX_MSG::MON_HW: {
1104-
log_v("MON-HW Antenna Status %d, noise level %d", mGpsBuffer.monHw.aStatus,
1105-
mGpsBuffer.monHw.noisePerMs);
1106-
mLastNoiseLevel = mGpsBuffer.monHw.noisePerMs;
1187+
const char* aStatus;
1188+
if (is_neo6()) {
1189+
switch (mGpsBuffer.monHw.aStatus) {
1190+
case mGpsBuffer.monHw.INIT: aStatus = "init"; break;
1191+
case mGpsBuffer.monHw.DONTKNOW: aStatus = "?"; break;
1192+
case mGpsBuffer.monHw.OK: aStatus = "ok"; break;
1193+
case mGpsBuffer.monHw.SHORT: aStatus = "short"; break;
1194+
case mGpsBuffer.monHw.OPEN: aStatus = "open"; break;
1195+
default: aStatus = "invalid";
1196+
}
1197+
log_d("MON-HW Antenna Status %d %s, Antenna Power %d, Gain (0-8191) %d, noise level %d", mGpsBuffer.monHw.aStatus, aStatus, mGpsBuffer.monHw.aPower, mGpsBuffer.monHw.agcCnt, mGpsBuffer.monHw.noisePerMs);
1198+
mLastNoiseLevel = mGpsBuffer.monHw.noisePerMs;
1199+
mLastGain = mGpsBuffer.monHw.agcCnt;
1200+
mLastJamInd = mGpsBuffer.monHw.jamInd;
1201+
} else {
1202+
switch (mGpsBuffer.monHwNew.aStatus) {
1203+
case mGpsBuffer.monHwNew.INIT: aStatus = "init"; break;
1204+
case mGpsBuffer.monHwNew.DONTKNOW: aStatus = "?"; break;
1205+
case mGpsBuffer.monHwNew.OK: aStatus = "ok"; break;
1206+
case mGpsBuffer.monHwNew.SHORT: aStatus = "short"; break;
1207+
case mGpsBuffer.monHwNew.OPEN: aStatus = "open"; break;
1208+
default: aStatus = "invalid";
1209+
}
1210+
log_d("MON-HW Antenna Status %d %s, Antenna Power %d, Gain (0-8191) %d, noise level %d", mGpsBuffer.monHwNew.aStatus, aStatus, mGpsBuffer.monHwNew.aPower, mGpsBuffer.monHwNew.agcCnt, mGpsBuffer.monHwNew.noisePerMs);
1211+
mLastNoiseLevel = mGpsBuffer.monHwNew.noisePerMs;
1212+
mLastGain = mGpsBuffer.monHwNew.agcCnt;
1213+
mLastJamInd = mGpsBuffer.monHwNew.jamInd;
1214+
}
11071215
}
11081216
break;
11091217
case (uint16_t) UBX_MSG::NAV_STATUS: {
@@ -1113,7 +1221,7 @@ void Gps::parseUbxMessage() {
11131221
mGpsUptime = mGpsBuffer.navStatus.msss;
11141222
if (mGpsBuffer.navStatus.ttff != 0) {
11151223
addStatisticsMessage("TimeToFix: " + String(mGpsBuffer.navStatus.ttff) + "ms");
1116-
} else if (!mAidIniSent) {
1224+
} else if (!mAidIniSent and is_neo6()) {
11171225
mAidIniSent = true;
11181226
aidIni();
11191227
}
@@ -1130,7 +1238,7 @@ void Gps::parseUbxMessage() {
11301238
}
11311239
break;
11321240
case (uint16_t) UBX_MSG::NAV_SOL: {
1133-
log_v("SOL: iTOW: %u, gpsFix: %d, flags: %02x, numSV: %d, pDop: %04d.",
1241+
log_d("SOL: iTOW: %u, gpsFix: %d, flags: %02x, numSV: %d, pDop: %04d.",
11341242
mGpsBuffer.navSol.iTow, mGpsBuffer.navSol.gpsFix, mGpsBuffer.navSol.flags,
11351243
mGpsBuffer.navSol.numSv, mGpsBuffer.navSol.pDop);
11361244
if (mGpsBuffer.navSol.flags & 4) { // WKNSET
@@ -1148,15 +1256,15 @@ void Gps::parseUbxMessage() {
11481256
}
11491257
break;
11501258
case (uint16_t) UBX_MSG::NAV_PVT: {
1151-
log_v("PVT: iTOW: %u, fixType: %d, flags: %02x, numSV: %d, pDop: %04d.",
1259+
log_d("PVT: iTOW: %u, fixType: %d, flags: %02x, numSV: %d, pDop: %04d.",
11521260
mGpsBuffer.navPvt.iTow, mGpsBuffer.navPvt.fixType, mGpsBuffer.navPvt.flags,
11531261
mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.pDOP);
11541262
prepareGpsData(mGpsBuffer.navPvt.iTow, mMessageStarted);
11551263
mIncomingGpsRecord.setInfo(mGpsBuffer.navPvt.numSV, mGpsBuffer.navPvt.fixType, mGpsBuffer.navPvt.flags);
11561264
}
11571265
break;
11581266
case (uint16_t) UBX_MSG::NAV_VELNED: {
1159-
log_v("VELNED: iTOW: %u, speed: %d cm/s, gSpeed: %d cm/s, heading: %d,"
1267+
log_d("VELNED: iTOW: %u, speed: %d cm/s, gSpeed: %d cm/s, heading: %d,"
11601268
" speedAcc: %d, cAcc: %d",
11611269
mGpsBuffer.navVelned.iTow, mGpsBuffer.navVelned.speed, mGpsBuffer.navVelned.gSpeed,
11621270
mGpsBuffer.navVelned.heading, mGpsBuffer.navVelned.sAcc, mGpsBuffer.navVelned.cAcc);
@@ -1289,7 +1397,7 @@ void Gps::parseUbxMessage() {
12891397
log_d("CFG_GNSS");
12901398
break;
12911399
default:
1292-
log_e("Got UBX_MESSAGE! Id: 0x%04x Len %d iTOW %d", mGpsBuffer.ubxHeader.ubxMsgId,
1400+
log_e("Got unparsed UBX_MESSAGE! Id: 0x%04x Len %d iTOW %d", mGpsBuffer.ubxHeader.ubxMsgId,
12931401
mGpsBuffer.ubxHeader.length, mGpsBuffer.navStatus.iTow);
12941402
}
12951403
}
@@ -1314,10 +1422,10 @@ void Gps::handleUbxNavTimeGps(const GpsBuffer::UbxNavTimeGps &message, const uin
13141422
mIncomingGpsRecord.setWeek(mLastGpsWeek);
13151423
}
13161424
if ((message.valid & 0x03) == 0x03 // WEEK && TOW
1317-
&& delayMs < 250
1425+
&& delayMs < 1000
13181426
&& message.tAcc < (20 * 1000 * 1000 /* 20ms */)
1319-
&& (mLastTimeTimeSet == 0
1320-
|| (mLastTimeTimeSet + (2 * 60 * 1000 /* 2 minutes */)) < receivedMs)) {
1427+
&& ((mLastTimeTimeSet == 0)
1428+
|| ((mLastTimeTimeSet + (2 * 60 * 1000 /* 2 minutes */)) < receivedMs))) {
13211429
String oldTime = TimeUtils::dateTimeToString();
13221430
TimeUtils::setClockByGps(message.iTow, message.fTow, message.week);
13231431
String newTime = TimeUtils::dateTimeToString();
@@ -1328,10 +1436,12 @@ void Gps::handleUbxNavTimeGps(const GpsBuffer::UbxNavTimeGps &message, const uin
13281436
+ "ms. tAcc:" + String(message.tAcc) + "ns");
13291437
}
13301438
if (mLastTimeTimeSet == 0) {
1331-
mLastTimeTimeSet = receivedMs;
1332-
// This triggers another NAV-TIMEGPS message!
1439+
if (delayMs < 100) { // keep mLastTimeTimeSet at 0 unless reasonable delayMs
1440+
mLastTimeTimeSet = receivedMs;
1441+
}
1442+
// This triggers another NAV-TIMEGPS message! more often until good time is received
13331443
#ifdef UBX_M6
1334-
setMessageInterval(UBX_MSG::NAV_TIMEGPS, 240, false); // every 4 minutes
1444+
setMessageInterval(UBX_MSG::NAV_TIMEGPS, (delayMs>100) ? 5 : 240, false); // every 4 minutes
13351445
#endif
13361446
#ifdef UBX_M10
13371447
setMessageInterval(UBX_CFG_KEY_ID::CFG_MSGOUT_UBX_NAV_TIMEGPS_UART1, 240, false); // every 4 minutes
@@ -1411,6 +1521,14 @@ uint16_t Gps::getLastNoiseLevel() const {
14111521
return mLastNoiseLevel;
14121522
}
14131523

1524+
uint16_t Gps::getLastAntennaGain() const {
1525+
return mLastGain;
1526+
}
1527+
1528+
uint8_t Gps::getLastJamInd() const {
1529+
return mLastJamInd;
1530+
}
1531+
14141532
uint32_t Gps::getBaudRate() {
14151533
return mSerial.baudRate();
14161534
}

0 commit comments

Comments
 (0)