Add AssistNow MQTT example
This commit is contained in:
+170
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
Use ESP32 WiFi to get AssistNow Online (MGA) data from PointPerfect (broker) as a Client using MQTT
|
||||||
|
By: Paul Clark / SparkFun
|
||||||
|
Date: March 9th, 2022
|
||||||
|
Based on original code by: u-blox AG / Michael Ammann
|
||||||
|
License: MIT. See license file for more information but you can
|
||||||
|
basically do whatever you want with this code.
|
||||||
|
|
||||||
|
This example shows how to obtain AssistNow Online (MGA) data from a PointPerfect Broker over WiFi
|
||||||
|
and push it over I2C to a ZED-F9x.
|
||||||
|
It's confusing, but the Arduino is acting as a 'client' to the PointPerfect service.
|
||||||
|
|
||||||
|
You will need to have a valid u-blox Thingstream account and have a PointPerfect Thing and payed plan.
|
||||||
|
To sign up, go to: https://portal.thingstream.io/app/location-services/things
|
||||||
|
|
||||||
|
This is a proof of concept to show how to connect via MQTT to get AssistNow MGA data.
|
||||||
|
|
||||||
|
For more information about MQTT, SPARTN and PointPerfect Correction Services
|
||||||
|
please see: https://www.u-blox.com/en/product/pointperfect
|
||||||
|
|
||||||
|
Feel like supporting open source hardware?
|
||||||
|
Buy a board from SparkFun!
|
||||||
|
SparkFun Thing Plus - ESP32 WROOM: https://www.sparkfun.com/products/15663
|
||||||
|
ZED-F9P RTK2: https://www.sparkfun.com/products/16481
|
||||||
|
SparkFun GPS Breakout - ZOE-M8Q (Qwiic): https://www.sparkfun.com/products/15193
|
||||||
|
|
||||||
|
Hardware Connections:
|
||||||
|
Plug a Qwiic cable into the GNSS and a ESP32 Thing Plus
|
||||||
|
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||||
|
Open the serial monitor at 115200 baud to see the output
|
||||||
|
*/
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
#include <ArduinoMqttClient.h> // Click here to get the library: http://librarymanager/All#ArduinoMqttClient
|
||||||
|
#include "secrets.h"
|
||||||
|
|
||||||
|
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> // Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||||
|
SFE_UBLOX_GNSS myGNSS;
|
||||||
|
|
||||||
|
//Global variables
|
||||||
|
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
long lastReceived_ms = 0; //5 RTCM messages take approximately ~300ms to arrive at 115200bps
|
||||||
|
int maxTimeBeforeHangup_ms = 10000; //If we fail to get a complete RTCM frame after 10s, then disconnect from caster
|
||||||
|
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial);
|
||||||
|
Serial.println(F("PointPerfect AssistNow testing"));
|
||||||
|
|
||||||
|
Wire.begin(); //Start I2C
|
||||||
|
|
||||||
|
if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
|
||||||
|
{
|
||||||
|
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println(F("u-blox module connected"));
|
||||||
|
myGNSS.setI2COutput(COM_TYPE_UBX); //Turn off NMEA noise
|
||||||
|
myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_SPARTN);
|
||||||
|
|
||||||
|
myGNSS.setNavigationFrequency(1); //Set output in Hz.
|
||||||
|
|
||||||
|
Serial.print(F("Connecting to local WiFi"));
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(F("."));
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial.print(F("WiFi connected with IP: "));
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
while (Serial.available()) Serial.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
if (Serial.available())
|
||||||
|
{
|
||||||
|
beginClient();
|
||||||
|
while (Serial.available()) Serial.read(); //Empty buffer of any newline chars
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println(F("Press any key to start MQTT Client."));
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiClientSecure wifiClient = WiFiClientSecure();
|
||||||
|
MqttClient mqttClient(wifiClient);
|
||||||
|
|
||||||
|
void mqttMessageHandler(int messageSize) {
|
||||||
|
uint8_t mgaData[512 * 4]; //Most incoming data is around 500 bytes but may be larger
|
||||||
|
int mgaCount = 0;
|
||||||
|
Serial.print(F("Pushed data from "));
|
||||||
|
Serial.print(mqttClient.messageTopic());
|
||||||
|
Serial.println(F(" topic to ZED"));
|
||||||
|
while (mqttClient.available())
|
||||||
|
{
|
||||||
|
char ch = mqttClient.read();
|
||||||
|
//Serial.write(ch); //Pipe to serial port is fine but beware, it's a lot of binary data
|
||||||
|
mgaData[mgaCount++] = ch;
|
||||||
|
if (mgaCount == sizeof(mgaData))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mgaCount > 0)
|
||||||
|
{
|
||||||
|
//Push MGA data to GNSS module over I2C
|
||||||
|
myGNSS.pushRawData(mgaData, mgaCount, false);
|
||||||
|
lastReceived_ms = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Connect to MQTT broker, receive MGA, and push to ZED module over I2C
|
||||||
|
void beginClient()
|
||||||
|
{
|
||||||
|
Serial.println(F("Subscribing to Broker. Press key to stop"));
|
||||||
|
delay(10); //Wait for any serial to arrive
|
||||||
|
while (Serial.available()) Serial.read(); //Flush
|
||||||
|
|
||||||
|
while (Serial.available() == 0)
|
||||||
|
{
|
||||||
|
//Connect if we are not already
|
||||||
|
if (wifiClient.connected() == false)
|
||||||
|
{
|
||||||
|
// Connect to AWS IoT
|
||||||
|
wifiClient.setCACert(AWS_CERT_CA);
|
||||||
|
wifiClient.setCertificate(AWS_CERT_CRT);
|
||||||
|
wifiClient.setPrivateKey(AWS_CERT_PRIVATE);
|
||||||
|
mqttClient.setId(MQTT_CLIENT_ID);
|
||||||
|
mqttClient.setKeepAliveInterval(60*1000);
|
||||||
|
mqttClient.setConnectionTimeout( 5*1000);
|
||||||
|
if (!mqttClient.connect(AWS_IOT_ENDPOINT, AWS_IOT_PORT)) {
|
||||||
|
Serial.print(F("MQTT connection failed! Error code = "));
|
||||||
|
Serial.println(mqttClient.connectError());
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Serial.println(F("You're connected to the PointPerfect MQTT broker: "));
|
||||||
|
Serial.println(AWS_IOT_ENDPOINT);
|
||||||
|
// Subscribe to MQTT and register a callback
|
||||||
|
Serial.println(F("Subscribe to Topics"));
|
||||||
|
mqttClient.onMessage(mqttMessageHandler);
|
||||||
|
mqttClient.subscribe(MQTT_TOPIC_ASSISTNOW);
|
||||||
|
lastReceived_ms = millis();
|
||||||
|
} //End attempt to connect
|
||||||
|
} //End connected == false
|
||||||
|
else {
|
||||||
|
mqttClient.poll();
|
||||||
|
}
|
||||||
|
//Close socket if we don't have new data for 10s
|
||||||
|
if (millis() - lastReceived_ms > maxTimeBeforeHangup_ms)
|
||||||
|
{
|
||||||
|
Serial.println(F("Timeout. Disconnecting..."));
|
||||||
|
if (mqttClient.connected() == true)
|
||||||
|
mqttClient.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println(F("User pressed a key"));
|
||||||
|
Serial.println(F("Disconnecting..."));
|
||||||
|
wifiClient.stop();
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
//Your WiFi credentials
|
||||||
|
const char ssid[] = "<YOUR SSID>";
|
||||||
|
const char password[] = "<YOUR PASSWORD>";
|
||||||
|
|
||||||
|
// Below infomation you can set after signing up with u-blox Thingstream portal
|
||||||
|
// and after add a new New PointPerfect Thing
|
||||||
|
// https://portal.thingstream.io/app/location-services/things
|
||||||
|
// in the new PointPerfect Thing you go to the credentials page and copy past the values and certificate into this.
|
||||||
|
|
||||||
|
// <Your PointPerfect Thing> -> Credentials -> Hostname
|
||||||
|
const char AWS_IOT_ENDPOINT[] = "pp.services.u-blox.com";
|
||||||
|
const unsigned short AWS_IOT_PORT = 8883;
|
||||||
|
// <Your PointPerfect Thing> -> Credentials -> AssistNow (MGA) topic
|
||||||
|
const char MQTT_TOPIC_ASSISTNOW[] = "/pp/ubx/mga";
|
||||||
|
|
||||||
|
// <Your PointPerfect Thing> -> Credentials -> Client Id
|
||||||
|
static const char MQTT_CLIENT_ID[] = "<ADD YOUR CLIENT ID HERE>";
|
||||||
|
|
||||||
|
// <Your PointPerfect Thing> -> Credentials -> Amazon Root Certificate
|
||||||
|
static const char AWS_CERT_CA[] PROGMEM = R"EOF(
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
<ADD YOUR CERTICICATE HERE>
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
)EOF";
|
||||||
|
|
||||||
|
// <Your PointPerfect Thing> -> Credentials -> Client Certificate
|
||||||
|
static const char AWS_CERT_CRT[] PROGMEM = R"KEY(
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
<ADD YOUR CERTICICATE HERE>
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
)KEY";
|
||||||
|
|
||||||
|
// Get this from Thingstream Portal
|
||||||
|
// <Your PointPerfect Thing> -> Credentials -> Client Key
|
||||||
|
static const char AWS_CERT_PRIVATE[] PROGMEM = R"KEY(
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
<ADD YOUR KEY HERE>
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
)KEY";
|
||||||
Reference in New Issue
Block a user