|
| 1 | +/* |
| 2 | + Use ESP32 WiFi to get AssistNow Online data from u-blox Thingstream |
| 3 | + By: SparkFun Electronics / Paul Clark |
| 4 | + Date: November 24th, 2021 |
| 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 AssistNow Online data from u-blox Thingstream over WiFi |
| 9 | + and push it to a u-blox module using Serial. |
| 10 | +
|
| 11 | + You will need to have a token to be able to access Thingstream. See the AssistNow README for more details. |
| 12 | +
|
| 13 | + Update secrets.h with your: |
| 14 | + - WiFi credentials |
| 15 | + - AssistNow token string |
| 16 | +
|
| 17 | + Uncomment the "#define USE_MGA_ACKs" below to test the more robust method of using the |
| 18 | + UBX_MGA_ACK_DATA0 acknowledgements to confirm that each MGA message has been accepted. |
| 19 | +
|
| 20 | + Feel like supporting open source hardware? |
| 21 | + Buy a board from SparkFun! |
| 22 | + SparkFun Thing Plus - ESP32 WROOM: https://www.sparkfun.com/products/15663 |
| 23 | + ZED-F9P RTK2: https://www.sparkfun.com/products/16481 |
| 24 | + SparkFun GPS Breakout - ZOE-M8Q (Qwiic): https://www.sparkfun.com/products/15193 |
| 25 | +
|
| 26 | + Hardware Connections: |
| 27 | + Plug a Qwiic cable into the GNSS and a ESP32 Thing Plus |
| 28 | + If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425) |
| 29 | + Open the serial monitor at 115200 baud to see the output |
| 30 | +*/ |
| 31 | + |
| 32 | +//#define USE_MGA_ACKs // Uncomment this line to use the UBX_MGA_ACK_DATA0 acknowledgements |
| 33 | + |
| 34 | +#include <WiFi.h> |
| 35 | +#include <HTTPClient.h> |
| 36 | +#include "secrets.h" |
| 37 | + |
| 38 | +const char assistNowServer[] = "https://online-live1.services.u-blox.com"; |
| 39 | +//const char assistNowServer[] = "https://online-live2.services.u-blox.com"; // Alternate server |
| 40 | + |
| 41 | +const char getQuery[] = "GetOnlineData.ashx?"; |
| 42 | +const char tokenPrefix[] = "token="; |
| 43 | +const char tokenSuffix[] = ";"; |
| 44 | +const char getGNSS[] = "gnss=gps,glo;"; // GNSS can be: gps,qzss,glo,bds,gal |
| 45 | +const char getDataType[] = "datatype=eph,alm,aux;"; // Data type can be: eph,alm,aux,pos |
| 46 | + |
| 47 | +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 48 | + |
| 49 | +#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS |
| 50 | +SFE_UBLOX_GNSS myGNSS; |
| 51 | + |
| 52 | +#define mySerial Serial1 // Use Serial1 to communicate with the GNSS module |
| 53 | + |
| 54 | +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 55 | + |
| 56 | +void setup() |
| 57 | +{ |
| 58 | + delay(1000); |
| 59 | + |
| 60 | + Serial.begin(115200); |
| 61 | + Serial.println(F("AssistNow Example")); |
| 62 | + |
| 63 | + while (Serial.available()) Serial.read(); // Empty the serial buffer |
| 64 | + Serial.println(F("Press any key to begin...")); |
| 65 | + while (!Serial.available()); // Wait for a keypress |
| 66 | + |
| 67 | + mySerial.begin(9600); // Use 9600 baud (for u-blox M8) |
| 68 | + |
| 69 | + //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 70 | + // Connect to the GNSS. |
| 71 | + |
| 72 | + if (myGNSS.begin(mySerial) == false) //Connect to the Ublox module using mySerial |
| 73 | + { |
| 74 | + Serial.println(F("u-blox GPS not detected. Please check wiring. Freezing.")); |
| 75 | + while (1); |
| 76 | + } |
| 77 | + Serial.println(F("u-blox module connected")); |
| 78 | + |
| 79 | + myGNSS.setUART1Output(COM_TYPE_UBX); //Set the UART port to output UBX only |
| 80 | + |
| 81 | + //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 82 | + // Connect to WiFi. |
| 83 | + |
| 84 | + Serial.print(F("Connecting to local WiFi")); |
| 85 | + |
| 86 | + WiFi.begin(ssid, password); |
| 87 | + while (WiFi.status() != WL_CONNECTED) { |
| 88 | + delay(500); |
| 89 | + Serial.print(F(".")); |
| 90 | + } |
| 91 | + Serial.println(); |
| 92 | + |
| 93 | + Serial.println(F("WiFi connected!")); |
| 94 | + |
| 95 | + //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 96 | + // Use HTTP GET to receive the AssistNow_Online data |
| 97 | + |
| 98 | + const int URL_BUFFER_SIZE = 256; |
| 99 | + char theURL[URL_BUFFER_SIZE]; // This will contain the HTTP URL |
| 100 | + int payloadSize = 0; // This will be updated with the length of the data we get from the server |
| 101 | + String payload; // This will store the data we get from the server |
| 102 | + |
| 103 | + // Assemble the URL |
| 104 | + // Note the slash after the first %s (assistNowServer) |
| 105 | + snprintf(theURL, URL_BUFFER_SIZE, "%s/%s%s%s%s%s%s", |
| 106 | + assistNowServer, |
| 107 | + getQuery, |
| 108 | + tokenPrefix, |
| 109 | + myAssistNowToken, |
| 110 | + tokenSuffix, |
| 111 | + getGNSS, |
| 112 | + getDataType); |
| 113 | + |
| 114 | + Serial.print(F("HTTP URL is: ")); |
| 115 | + Serial.println(theURL); |
| 116 | + |
| 117 | + HTTPClient http; |
| 118 | + |
| 119 | + http.begin(theURL); |
| 120 | + |
| 121 | + int httpCode = http.GET(); // HTTP GET |
| 122 | + |
| 123 | + // httpCode will be negative on error |
| 124 | + if(httpCode > 0) |
| 125 | + { |
| 126 | + // HTTP header has been sent and Server response header has been handled |
| 127 | + Serial.printf("[HTTP] GET... code: %d\r\n", httpCode); |
| 128 | + |
| 129 | + // If the GET was successful, read the data |
| 130 | + if(httpCode == HTTP_CODE_OK) // Check for code 200 |
| 131 | + { |
| 132 | + payloadSize = http.getSize(); |
| 133 | + Serial.printf("Server returned %d bytes\r\n", payloadSize); |
| 134 | + |
| 135 | + payload = http.getString(); // Get the payload |
| 136 | + |
| 137 | + // Pretty-print the payload as HEX |
| 138 | + /* |
| 139 | + int i; |
| 140 | + for(i = 0; i < payloadSize; i++) |
| 141 | + { |
| 142 | + if (payload[i] < 0x10) // Print leading zero |
| 143 | + Serial.print("0"); |
| 144 | + Serial.print(payload[i], HEX); |
| 145 | + Serial.print(" "); |
| 146 | + if ((i % 16) == 15) |
| 147 | + Serial.println(); |
| 148 | + } |
| 149 | + if ((i % 16) != 15) |
| 150 | + Serial.println(); |
| 151 | + */ |
| 152 | + } |
| 153 | + } |
| 154 | + else |
| 155 | + { |
| 156 | + Serial.printf("[HTTP] GET... failed, error: %s\r\n", http.errorToString(httpCode).c_str()); |
| 157 | + } |
| 158 | + |
| 159 | + http.end(); |
| 160 | + |
| 161 | + //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 162 | + // Push the AssistNow data to the module |
| 163 | + |
| 164 | + if (payloadSize > 0) |
| 165 | + { |
| 166 | + // Uncomment the next line to enable the 'major' debug messages on Serial so you can see what AssistNow data is being sent |
| 167 | + //myGNSS.enableDebugging(Serial, true); |
| 168 | + |
| 169 | +#ifndef USE_MGA_ACKs |
| 170 | + |
| 171 | + // ***** Don't use the UBX_MGA_ACK_DATA0 messages ***** |
| 172 | + |
| 173 | + // Push all the AssistNow data. Don't use UBX_MGA_ACK_DATA0's. Use the default delay of 7ms between messages. |
| 174 | + myGNSS.pushAssistNowData(payload, (size_t)payloadSize); |
| 175 | + |
| 176 | +#else |
| 177 | + |
| 178 | + // ***** Use the UBX_MGA_ACK_DATA0 messages ***** |
| 179 | + |
| 180 | + // Tell the module to return UBX_MGA_ACK_DATA0 messages when we push the AssistNow data |
| 181 | + myGNSS.setAckAiding(1); |
| 182 | + |
| 183 | + // Push all the AssistNow data. |
| 184 | + // We have called setAckAiding(1) to instruct the module to return MGA-ACK messages. |
| 185 | + // So, we could set the pushAssistNowData mgaAck parameter to SFE_UBLOX_MGA_ASSIST_ACK_YES. |
| 186 | + // But, just for giggles, let's use SFE_UBLOX_MGA_ASSIST_ACK_ENQUIRE just to confirm that the |
| 187 | + // MGA-ACK messages are actually enabled. |
| 188 | + // Wait for up to 100ms for each ACK to arrive! 100ms is a bit excessive... 7ms is nearer the mark. |
| 189 | + myGNSS.pushAssistNowData(payload, (size_t)payloadSize, SFE_UBLOX_MGA_ASSIST_ACK_ENQUIRE, 100); |
| 190 | + |
| 191 | +#endif |
| 192 | + |
| 193 | + } |
| 194 | + |
| 195 | + Serial.println(F("Here we go!")); |
| 196 | +} |
| 197 | + |
| 198 | +//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= |
| 199 | + |
| 200 | +void loop() |
| 201 | +{ |
| 202 | + // Print the UBX-NAV-PVT data so we can see how quickly the fixType goes to 3D |
| 203 | + |
| 204 | + long latitude = myGNSS.getLatitude(); |
| 205 | + Serial.print(F("Lat: ")); |
| 206 | + Serial.print(latitude); |
| 207 | + |
| 208 | + long longitude = myGNSS.getLongitude(); |
| 209 | + Serial.print(F(" Long: ")); |
| 210 | + Serial.print(longitude); |
| 211 | + Serial.print(F(" (degrees * 10^-7)")); |
| 212 | + |
| 213 | + long altitude = myGNSS.getAltitude(); |
| 214 | + Serial.print(F(" Alt: ")); |
| 215 | + Serial.print(altitude); |
| 216 | + Serial.print(F(" (mm)")); |
| 217 | + |
| 218 | + byte SIV = myGNSS.getSIV(); |
| 219 | + Serial.print(F(" SIV: ")); |
| 220 | + Serial.print(SIV); |
| 221 | + |
| 222 | + byte fixType = myGNSS.getFixType(); |
| 223 | + Serial.print(F(" Fix: ")); |
| 224 | + if(fixType == 0) Serial.print(F("No fix")); |
| 225 | + else if(fixType == 1) Serial.print(F("Dead reckoning")); |
| 226 | + else if(fixType == 2) Serial.print(F("2D")); |
| 227 | + else if(fixType == 3) Serial.print(F("3D")); |
| 228 | + else if(fixType == 4) Serial.print(F("GNSS + Dead reckoning")); |
| 229 | + else if(fixType == 5) Serial.print(F("Time only")); |
| 230 | + |
| 231 | + Serial.println(); |
| 232 | +} |
0 commit comments