Skip to content

Commit 729a88d

Browse files
authored
Merge pull request #130 from sparkfun/release_candidate
v2.2.7
2 parents 727e1b0 + 57f4189 commit 729a88d

File tree

13 files changed

+1038
-130
lines changed

13 files changed

+1038
-130
lines changed

examples/AssistNow/AssistNow_Online/Example5_AssistNowOnline_MQTT/Example5_AssistNowOnline_MQTT.ino

+31-15
Original file line numberDiff line numberDiff line change
@@ -93,27 +93,43 @@ void loop()
9393
WiFiClientSecure wifiClient = WiFiClientSecure();
9494
MqttClient mqttClient(wifiClient);
9595

96-
void mqttMessageHandler(int messageSize) {
97-
uint8_t mgaData[512 * 4]; //Most incoming data is around 500 bytes but may be larger
98-
int mgaCount = 0;
99-
Serial.print(F("Pushed data from "));
96+
void mqttMessageHandler(int messageSize)
97+
{
98+
const uint16_t mqttLimit = 512;
99+
uint8_t *mqttData = new uint8_t[mqttLimit]; // Allocate memory to hold the MQTT data
100+
if (mqttData == NULL)
101+
{
102+
Serial.println(F("Memory allocation for mqttData failed!"));
103+
return;
104+
}
105+
106+
Serial.print(F("Pushing data from "));
100107
Serial.print(mqttClient.messageTopic());
101108
Serial.println(F(" topic to ZED"));
109+
102110
while (mqttClient.available())
103111
{
104-
char ch = mqttClient.read();
105-
//Serial.write(ch); //Pipe to serial port is fine but beware, it's a lot of binary data
106-
mgaData[mgaCount++] = ch;
107-
if (mgaCount == sizeof(mgaData))
108-
break;
109-
}
112+
uint16_t mqttCount = 0;
110113

111-
if (mgaCount > 0)
112-
{
113-
//Push MGA data to GNSS module over I2C
114-
myGNSS.pushRawData(mgaData, mgaCount, false);
115-
lastReceived_ms = millis();
114+
while (mqttClient.available())
115+
{
116+
char ch = mqttClient.read();
117+
//Serial.write(ch); //Pipe to serial port is fine but beware, it's a lot of binary data
118+
mqttData[mqttCount++] = ch;
119+
120+
if (mqttCount == mqttLimit)
121+
break;
122+
}
123+
124+
if (mqttCount > 0)
125+
{
126+
//Push KEYS or SPARTN data to GNSS module over I2C
127+
myGNSS.pushRawData(mqttData, mqttCount, false);
128+
lastReceived_ms = millis();
129+
}
116130
}
131+
132+
delete[] mqttData;
117133
}
118134

119135
//Connect to MQTT broker, receive MGA, and push to ZED module over I2C

examples/Example30_NEO-D9S/Example30_NEO-D9S.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
Feel like supporting open source hardware?
1111
Buy a board from SparkFun!
1212
ZED-F9P RTK2: https://www.sparkfun.com/products/16481
13-
NEO-D9S: Coming soon!
13+
NEO-D9S Correction Data Receiver: https://www.sparkfun.com/products/19390
1414
1515
Hardware Connections:
1616
Use a Qwiic cable to connect the NEO-D9S L-Band corection data receiver to your board

examples/ZED-F9P/Example18_PointPerfectClient/Example18_PointPerfectClient.ino

+197-28
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
3737
Open the serial monitor at 115200 baud to see the output
3838
*/
39+
3940
#include <WiFi.h>
4041
#include <WiFiClientSecure.h>
4142
#include <ArduinoMqttClient.h> // Click here to get the library: http://librarymanager/All#ArduinoMqttClient
@@ -44,10 +45,137 @@
4445
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS
4546
SFE_UBLOX_GNSS myGNSS;
4647

47-
//Global variables
48+
#define OK(ok) (ok ? F(" -> OK") : F(" -> ERROR!")) // Convert uint8_t into OK/ERROR
49+
4850
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
51+
52+
//Global variables
53+
4954
long lastReceived_ms = 0; //5 RTCM messages take approximately ~300ms to arrive at 115200bps
5055
int maxTimeBeforeHangup_ms = 10000; //If we fail to get a complete RTCM frame after 10s, then disconnect from caster
56+
57+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
58+
59+
// Callback: printPVTdata will be called when new NAV PVT data arrives
60+
// See u-blox_structs.h for the full definition of UBX_NAV_PVT_data_t
61+
// _____ You can use any name you like for the callback. Use the same name when you call setAutoPVTcallbackPtr
62+
// / _____ This _must_ be UBX_NAV_PVT_data_t
63+
// | / _____ You can use any name you like for the struct
64+
// | | /
65+
// | | |
66+
void printPVTdata(UBX_NAV_PVT_data_t *ubxDataStruct)
67+
{
68+
double latitude = ubxDataStruct->lat; // Print the latitude
69+
Serial.print(F("Lat: "));
70+
Serial.print(latitude / 10000000.0, 7);
71+
72+
double longitude = ubxDataStruct->lon; // Print the longitude
73+
Serial.print(F(" Long: "));
74+
Serial.print(longitude / 10000000.0, 7);
75+
76+
double altitude = ubxDataStruct->hMSL; // Print the height above mean sea level
77+
Serial.print(F(" Height: "));
78+
Serial.print(altitude / 1000.0, 3);
79+
80+
uint8_t fixType = ubxDataStruct->fixType; // Print the fix type
81+
Serial.print(F(" Fix: "));
82+
Serial.print(fixType);
83+
if (fixType == 0)
84+
Serial.print(F(" (None)"));
85+
else if (fixType == 1)
86+
Serial.print(F(" (Dead Reckoning)"));
87+
else if (fixType == 2)
88+
Serial.print(F(" (2D)"));
89+
else if (fixType == 3)
90+
Serial.print(F(" (3D)"));
91+
else if (fixType == 3)
92+
Serial.print(F(" (GNSS + Dead Reckoning)"));
93+
else if (fixType == 5)
94+
Serial.print(F(" (Time Only)"));
95+
else
96+
Serial.print(F(" (UNKNOWN)"));
97+
98+
uint8_t carrSoln = ubxDataStruct->flags.bits.carrSoln; // Print the carrier solution
99+
Serial.print(F(" Carrier Solution: "));
100+
Serial.print(carrSoln);
101+
if (carrSoln == 0)
102+
Serial.print(F(" (None)"));
103+
else if (carrSoln == 1)
104+
Serial.print(F(" (Floating)"));
105+
else if (carrSoln == 2)
106+
Serial.print(F(" (Fixed)"));
107+
else
108+
Serial.print(F(" (UNKNOWN)"));
109+
110+
uint32_t hAcc = ubxDataStruct->hAcc; // Print the horizontal accuracy estimate
111+
Serial.print(F(" Horizontal Accuracy Estimate: "));
112+
Serial.print(hAcc);
113+
Serial.print(F(" (mm)"));
114+
115+
Serial.println();
116+
}
117+
118+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
119+
120+
// Callback: printRXMCOR will be called when new RXM COR data arrives
121+
// See u-blox_structs.h for the full definition of UBX_RXM_COR_data_t
122+
// _____ You can use any name you like for the callback. Use the same name when you call setRXMCORcallbackPtr
123+
// / _____ This _must_ be UBX_RXM_COR_data_t
124+
// | / _____ You can use any name you like for the struct
125+
// | | /
126+
// | | |
127+
void printRXMCOR(UBX_RXM_COR_data_t *ubxDataStruct)
128+
{
129+
Serial.print(F("UBX-RXM-COR: ebno: "));
130+
Serial.print(ubxDataStruct->ebno);
131+
132+
Serial.print(F(" protocol: "));
133+
if (ubxDataStruct->statusInfo.bits.protocol == 1)
134+
Serial.print(F("RTCM3"));
135+
else if (ubxDataStruct->statusInfo.bits.protocol == 2)
136+
Serial.print(F("SPARTN"));
137+
else if (ubxDataStruct->statusInfo.bits.protocol == 29)
138+
Serial.print(F("PMP (SPARTN)"));
139+
else if (ubxDataStruct->statusInfo.bits.protocol == 30)
140+
Serial.print(F("QZSSL6"));
141+
else
142+
Serial.print(F("Unknown"));
143+
144+
Serial.print(F(" errStatus: "));
145+
if (ubxDataStruct->statusInfo.bits.errStatus == 1)
146+
Serial.print(F("Error-free"));
147+
else if (ubxDataStruct->statusInfo.bits.errStatus == 2)
148+
Serial.print(F("Erroneous"));
149+
else
150+
Serial.print(F("Unknown"));
151+
152+
Serial.print(F(" msgUsed: "));
153+
if (ubxDataStruct->statusInfo.bits.msgUsed == 1)
154+
Serial.print(F("Not used"));
155+
else if (ubxDataStruct->statusInfo.bits.msgUsed == 2)
156+
Serial.print(F("Used"));
157+
else
158+
Serial.print(F("Unknown"));
159+
160+
Serial.print(F(" msgEncrypted: "));
161+
if (ubxDataStruct->statusInfo.bits.msgEncrypted == 1)
162+
Serial.print(F("Not encrypted"));
163+
else if (ubxDataStruct->statusInfo.bits.msgEncrypted == 2)
164+
Serial.print(F("Encrypted"));
165+
else
166+
Serial.print(F("Unknown"));
167+
168+
Serial.print(F(" msgDecrypted: "));
169+
if (ubxDataStruct->statusInfo.bits.msgDecrypted == 1)
170+
Serial.print(F("Not decrypted"));
171+
else if (ubxDataStruct->statusInfo.bits.msgDecrypted == 2)
172+
Serial.print(F("Successfully decrypted"));
173+
else
174+
Serial.print(F("Unknown"));
175+
176+
Serial.println();
177+
}
178+
51179
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
52180

53181
void setup()
@@ -58,17 +186,32 @@ void setup()
58186

59187
Wire.begin(); //Start I2C
60188

61-
if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
189+
//myGNSS.enableDebugging(); // Uncomment this line to enable debug messages on Serial
190+
191+
while (myGNSS.begin() == false) //Connect to the u-blox module using Wire port
62192
{
63-
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
64-
while (1);
193+
Serial.println(F("u-blox GNSS module not detected at default I2C address. Please check wiring."));
194+
delay(2000);
65195
}
66-
67-
Serial.println(F("u-blox module connected"));
68-
myGNSS.setI2COutput(COM_TYPE_UBX); //Turn off NMEA noise
69-
myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_SPARTN); // Be sure SPARTN input is enabled.
70-
71-
myGNSS.setNavigationFrequency(1); //Set output in Hz.
196+
Serial.println(F("u-blox GNSS module connected"));
197+
198+
uint8_t ok = myGNSS.setI2COutput(COM_TYPE_UBX); //Turn off NMEA noise
199+
if (ok) ok = myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_SPARTN); // Be sure SPARTN input is enabled.
200+
201+
if (ok) ok = myGNSS.setDGNSSConfiguration(SFE_UBLOX_DGNSS_MODE_FIXED); // Set the differential mode - ambiguities are fixed whenever possible
202+
if (ok) ok = myGNSS.setNavigationFrequency(1); //Set output in Hz.
203+
if (ok) ok = myGNSS.setVal8(UBLOX_CFG_SPARTN_USE_SOURCE, 0); // Use IP source (default). Change this to 1 for L-Band (PMP)
204+
205+
if (ok) ok = myGNSS.setAutoPVTcallbackPtr(&printPVTdata); // Enable automatic NAV PVT messages with callback to printPVTdata so we can watch the carrier solution go to fixed
206+
207+
if (ok) ok = myGNSS.setVal8(UBLOX_CFG_MSGOUT_UBX_RXM_COR_I2C, 1); // Enable UBX-RXM-COR messages on I2C
208+
if (ok) ok = myGNSS.setRXMCORcallbackPtr(&printRXMCOR); // Print the contents of UBX-RXM-COR messages so we can check if the SPARTN data is being decrypted successfully
209+
210+
//if (ok) ok = myGNSS.saveConfiguration(VAL_CFG_SUBSEC_IOPORT | VAL_CFG_SUBSEC_MSGCONF); //Optional: Save the ioPort and message settings to NVM
211+
212+
Serial.print(F("GNSS: configuration "));
213+
Serial.println(OK(ok));
214+
72215
Serial.print(F("Connecting to local WiFi"));
73216
WiFi.begin(ssid, password);
74217
while (WiFi.status() != WL_CONNECTED) {
@@ -81,45 +224,66 @@ void setup()
81224
Serial.println(WiFi.localIP());
82225

83226
while (Serial.available()) Serial.read();
227+
228+
Serial.println(F("Press any key to start MQTT/SPARTN Client."));
229+
84230
}
85231

86232
void loop()
87233
{
88234
if (Serial.available())
89235
{
90236
beginClient();
237+
91238
while (Serial.available()) Serial.read(); //Empty buffer of any newline chars
239+
240+
Serial.println(F("Press any key to start MQTT/SPARTN Client."));
92241
}
93242

94-
Serial.println(F("Press any key to start MQTT/SPARTN Client."));
95-
96-
delay(1000);
243+
myGNSS.checkUblox(); // Check for the arrival of new GNSS data and process it.
244+
myGNSS.checkCallbacks(); // Check if any GNSS callbacks are waiting to be processed.
97245
}
98246

99247
WiFiClientSecure wifiClient = WiFiClientSecure();
100248
MqttClient mqttClient(wifiClient);
101249

102-
void mqttMessageHandler(int messageSize) {
103-
uint8_t spartnData[512 * 4]; //Most incoming data is around 500 bytes but may be larger
104-
int spartnCount = 0;
105-
Serial.print(F("Pushed data from "));
250+
void mqttMessageHandler(int messageSize)
251+
{
252+
const uint16_t mqttLimit = 512;
253+
uint8_t *mqttData = new uint8_t[mqttLimit]; // Allocate memory to hold the MQTT data
254+
if (mqttData == NULL)
255+
{
256+
Serial.println(F("Memory allocation for mqttData failed!"));
257+
return;
258+
}
259+
260+
Serial.print(F("Pushing data from "));
106261
Serial.print(mqttClient.messageTopic());
107262
Serial.println(F(" topic to ZED"));
263+
108264
while (mqttClient.available())
109265
{
110-
char ch = mqttClient.read();
111-
//Serial.write(ch); //Pipe to serial port is fine but beware, it's a lot of binary data
112-
spartnData[spartnCount++] = ch;
113-
if (spartnCount == sizeof(spartnData))
114-
break;
115-
}
266+
uint16_t mqttCount = 0;
116267

117-
if (spartnCount > 0)
118-
{
119-
//Push KEYS or SPARTN data to GNSS module over I2C
120-
myGNSS.pushRawData(spartnData, spartnCount, false);
121-
lastReceived_ms = millis();
268+
while (mqttClient.available())
269+
{
270+
char ch = mqttClient.read();
271+
//Serial.write(ch); //Pipe to serial port is fine but beware, it's a lot of binary data
272+
mqttData[mqttCount++] = ch;
273+
274+
if (mqttCount == mqttLimit)
275+
break;
276+
}
277+
278+
if (mqttCount > 0)
279+
{
280+
//Push KEYS or SPARTN data to GNSS module over I2C
281+
myGNSS.pushRawData(mqttData, mqttCount, false);
282+
lastReceived_ms = millis();
283+
}
122284
}
285+
286+
delete[] mqttData;
123287
}
124288

125289
//Connect to STARTN MQTT broker, receive RTCM, and push to ZED module over I2C
@@ -153,12 +317,14 @@ void beginClient()
153317
mqttClient.onMessage(mqttMessageHandler);
154318
mqttClient.subscribe(MQTT_TOPIC_KEY);
155319
mqttClient.subscribe(MQTT_TOPIC_SPARTN);
320+
mqttClient.subscribe(MQTT_TOPIC_ASSISTNOW);
156321
lastReceived_ms = millis();
157322
} //End attempt to connect
158323
} //End connected == false
159324
else {
160325
mqttClient.poll();
161326
}
327+
162328
//Close socket if we don't have new data for 10s
163329
if (millis() - lastReceived_ms > maxTimeBeforeHangup_ms)
164330
{
@@ -168,6 +334,9 @@ void beginClient()
168334
return;
169335
}
170336

337+
myGNSS.checkUblox(); // Check for the arrival of new GNSS data and process it.
338+
myGNSS.checkCallbacks(); // Check if any GNSS callbacks are waiting to be processed.
339+
171340
delay(10);
172341
}
173342

examples/ZED-F9P/Example18_PointPerfectClient/secrets.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@ const char password[] = "<YOUR PASSWORD>";
55
// Below infomation you can set after signing up with u-blox Thingstream portal
66
// and after add a new New PointPerfect Thing
77
// https://portal.thingstream.io/app/location-services/things
8-
// in the new PointPerfect Thing you go to the credentials page and copy past the values and certificate into this.
8+
// in the new PointPerfect Thing you go to the credentials page and copy paste the values and certificate into this.
99

1010
// <Your PointPerfect Thing> -> Credentials -> Hostname
1111
const char AWS_IOT_ENDPOINT[] = "pp.services.u-blox.com";
1212
const unsigned short AWS_IOT_PORT = 8883;
1313
// <Your PointPerfect Thing> -> Credentials -> IP key distribution topic
14-
const char MQTT_TOPIC_KEY[] = "/pp/key/ip";
14+
const char MQTT_TOPIC_KEY[] = "/pp/ubx/0236/ip"; // This topic provides the IP only dynamic keys in UBX format
15+
//const char MQTT_TOPIC_KEY[] = "/pp/ubx/0236/Lb"; // This topic provides the L-Band + IP dynamic keys in UBX format
1516
// <Your PointPerfect Thing> -> Credentials -> IP correction topic for EU/US region
16-
const char MQTT_TOPIC_SPARTN[] = "/pp/ip/us"; // choice of {eu, us}
17+
const char MQTT_TOPIC_SPARTN[] = "/pp/ip/us"; // This topic provides the SPARTN corrections for IP only: choice of {eu, us}
18+
//const char MQTT_TOPIC_SPARTN[] = "/pp/Lb/us"; // This topic provides the SPARTN corrections for L-Band and L-Band + IP: choice of {eu, us}
19+
// <Your PointPerfect Thing> -> Credentials -> AssistNow (MGA) topic
20+
const char MQTT_TOPIC_ASSISTNOW[] = "/pp/ubx/mga";
1721

1822
// <Your PointPerfect Thing> -> Credentials -> Client Id
1923
static const char MQTT_CLIENT_ID[] = "<ADD YOUR CLIENT ID HERE>";

0 commit comments

Comments
 (0)