Skip to content

Commit 9de604c

Browse files
authored
Create Example18_PointPerfectClient.ino
1 parent 081c9cb commit 9de604c

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
Use ESP32 WiFi to get SPARTN data from PointPerfect (broker) as a Client
3+
By: u-blox AG / Michael Ammann
4+
Date: January 27th, 2022
5+
License: MIT. See license file for more information but you can
6+
basically do whatever you want with this code.
7+
8+
This example shows how to obtain SPARTN data from a PointPerfect Broker over WiFi
9+
and push it over I2C to a ZED-F9x.
10+
It's confusing, but the Arduino is acting as a 'client' to the PointPerfect SSR correction service.
11+
12+
You will need to have a valid u-blox Thingstream account and have a PointPerfect Thinng and Plan.
13+
Thingstream offers continetal SSR corrections to SPARTN cabalble RTK receivers such as the u-blox
14+
ZED-F9 sweries in continental Europ and US. There Network is planned to be expanded to ther regions
15+
over next years. To see sign up go to https://portal.thingstream.io/app/location-services/things
16+
17+
This is a proof of concept to show how to connect via MQTT to get SPARTN SSR correction.
18+
Using WiFi for a rover is generally a bad idea because of limited WiFi range in the field.
19+
20+
For more information about MQTT, SPARTN and PointPerfect Correction Services
21+
please see: https://www.u-blox.com/en/product/pointperfect?lang=de
22+
23+
Feel like supporting open source hardware?
24+
Buy a board from SparkFun!
25+
ZED-F9P RTK2: https://www.sparkfun.com/products/16481
26+
RTK Surveyor: https://www.sparkfun.com/products/18443
27+
RTK Express: https://www.sparkfun.com/products/18442
28+
29+
Hardware Connections:
30+
Plug a Qwiic cable into the GNSS and a ESP32 Thing Plus
31+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
32+
Open the serial monitor at 115200 baud to see the output
33+
*/
34+
#include <WiFi.h>
35+
#include <WiFiClientSecure.h>
36+
#include <ArduinoMqttClient.h>
37+
#include "secrets.h"
38+
39+
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
40+
SFE_UBLOX_GNSS myGNSS;
41+
42+
//Global variables
43+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
44+
long lastReceived_ms = 0; //5 RTCM messages take approximately ~300ms to arrive at 115200bps
45+
int maxTimeBeforeHangup_ms = 10000; //If we fail to get a complete RTCM frame after 10s, then disconnect from caster
46+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
47+
48+
void setup()
49+
{
50+
Serial.begin(115200);
51+
while (!Serial);
52+
Serial.println(F("PointPerfect testing"));
53+
54+
Wire.begin(); //Start I2C
55+
Wire.setClock(100000);
56+
57+
if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
58+
{
59+
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
60+
while (1);
61+
}
62+
63+
Serial.println(F("u-blox module connected"));
64+
myGNSS.setI2COutput(COM_TYPE_UBX); //Turn off NMEA noise
65+
myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_SPARTN); // Be sure SPARTN input is enabled.
66+
67+
myGNSS.setNavigationFrequency(1); //Set output in Hz.
68+
Serial.print(F("Connecting to local WiFi"));
69+
WiFi.begin(ssid, password);
70+
while (WiFi.status() != WL_CONNECTED) {
71+
delay(500);
72+
Serial.print(F("."));
73+
}
74+
Serial.println();
75+
76+
Serial.print(F("WiFi connected with IP: "));
77+
Serial.println(WiFi.localIP());
78+
79+
while (Serial.available()) Serial.read();
80+
}
81+
82+
void loop()
83+
{
84+
if (Serial.available())
85+
{
86+
beginClient();
87+
while (Serial.available()) Serial.read(); //Empty buffer of any newline chars
88+
}
89+
90+
Serial.println(F("Press any key to start MQTT/SPARTN Client."));
91+
92+
delay(1000);
93+
}
94+
95+
WiFiClientSecure wifiClient = WiFiClientSecure();
96+
MqttClient mqttClient(wifiClient);
97+
98+
void mqttMessageHandler(int messageSize) {
99+
uint8_t spartnData[512 * 4]; //Most incoming data is around 500 bytes but may be larger
100+
int spartnCount = 0;
101+
Serial.print(F("Pushed data from "));
102+
Serial.print(mqttClient.messageTopic());
103+
Serial.println(F(" topic to ZED"));
104+
while (mqttClient.available())
105+
{
106+
char ch = mqttClient.read();
107+
//Serial.write(ch); //Pipe to serial port is fine but beware, it's a lot of binary data
108+
spartnData[spartnCount++] = ch;
109+
if (spartnCount == sizeof(spartnData))
110+
break;
111+
}
112+
113+
if (spartnCount > 0)
114+
{
115+
//Push KEYS or SPARTN data to GNSS module over I2C
116+
myGNSS.pushRawData(spartnData, spartnCount, false);
117+
lastReceived_ms = millis();
118+
}
119+
}
120+
121+
//Connect to STARTN MQTT broker, receive RTCM, and push to ZED module over I2C
122+
void beginClient()
123+
{
124+
Serial.println(F("Subscribing to Broker. Press key to stop"));
125+
delay(10); //Wait for any serial to arrive
126+
while (Serial.available()) Serial.read(); //Flush
127+
128+
while (Serial.available() == 0)
129+
{
130+
//Connect if we are not already
131+
if (wifiClient.connected() == false)
132+
{
133+
// Connect to AWS IoT
134+
wifiClient.setCACert(AWS_CERT_CA);
135+
wifiClient.setCertificate(AWS_CERT_CRT);
136+
wifiClient.setPrivateKey(AWS_CERT_PRIVATE);
137+
if (!mqttClient.connect(AWS_IOT_ENDPOINT, AWS_IOT_PORT)) {
138+
Serial.print(F("MQTT connection failed! Error code = "));
139+
Serial.println(mqttClient.connectError());
140+
return;
141+
} else {
142+
Serial.println(F("You're connected to the PointPerfect MQTT broker: "));
143+
Serial.println(AWS_IOT_ENDPOINT);
144+
// Subscribe to MQTT and register a callback
145+
Serial.println(F("Subscribe to Topics"));
146+
mqttClient.onMessage(mqttMessageHandler);
147+
mqttClient.subscribe(MQTT_TOPIC_KEY);
148+
mqttClient.subscribe(MQTT_TOPIC_SPARTN);
149+
lastReceived_ms = millis();
150+
} //End attempt to connect
151+
} //End connected == false
152+
else {
153+
mqttClient.poll();
154+
}
155+
//Close socket if we don't have new data for 10s
156+
if (millis() - lastReceived_ms > maxTimeBeforeHangup_ms)
157+
{
158+
Serial.println(F("SPARTN timeout. Disconnecting..."));
159+
if (mqttClient.connected() == true)
160+
mqttClient.stop();
161+
return;
162+
}
163+
164+
delay(10);
165+
}
166+
167+
Serial.println(F("User pressed a key"));
168+
Serial.println(F("Disconnecting..."));
169+
wifiClient.stop();
170+
}

0 commit comments

Comments
 (0)