Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #155 from sparkfun/release_candidate
Browse files Browse the repository at this point in the history
Merging release_candidate: updates for v1.8.8
  • Loading branch information
PaulZC authored Dec 5, 2020
2 parents 97bd455 + 0d34d12 commit 9fc9c03
Show file tree
Hide file tree
Showing 25 changed files with 6,158 additions and 588 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,6 @@ Temporary Items
*~
[._]*.un~
*.swp

# Zephyr build files
examples/Zephyr/*/build/*
11 changes: 8 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
### How to Contribute
# How to Contribute

Thank you so *much* for offering to help out. We truly appreciate it.

If you'd like to contribute, start by searching through the [issues](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/issues) and [pull requests](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/pulls) to see whether someone else has raised a similar idea or question.
Please check the [closed issues](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/issues?q=is%3Aissue+is%3Aclosed)
and [closed pull requests](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/pulls?q=is%3Apr+is%3Aclosed) too - you may find that your issue or feature has already been discussed.

If you decide to add a feature to this library, please create a PR and follow these best practices:

* Change as little as possible. Do not sumbit a PR that changes 100 lines of whitespace. Break up into multiple PRs if necessary.
* Change as little as possible. Do not submit a PR that changes 100 lines of whitespace. Break up into multiple PRs if necessary.
* If you've added a new feature document it with a simple example sketch. This serves both as a test of your PR and as a quick way for users to quickly learn how to use your new feature.
* If you add new functions also add them to keywords.txt so that they are properly highlighted in Arduino. [Read more](https://www.arduino.cc/en/Hacking/libraryTutorial).
* If you add new functions also add them to _keywords.txt_ so that they are properly highlighted in Arduino. [Read more](https://www.arduino.cc/en/Hacking/libraryTutorial).
* **Important:** Please submit your PR using the [release_candidate branch](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/tree/release_candidate). That way, we can merge and test your PR quickly without changing the _master_ branch

![Contributing.JPG](./img/Contributing.JPG)

## Style guide

Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,32 @@ Thanks to:
* [averywallis](https://github.com/averywallis) for adding good comments to the various constants.
* [blazczak](https://github.com/blazczak) and [geeksville](https://github.com/geeksville) for adding support for the series 6 and 7 modules.
* [bjorn@unsurv](https://github.com/unsurv) for adding powerOff and powerOffWithInterrupt.
* [dotMorten](https://github.com/dotMorten) for the MSGOUT keys, autoHPPOSLLH, autoDOP and upgrades to autoPVT.
* [markuckermann](https://github.com/markuckermann) for spotting the config layer gremlins
* [vid553](https://github.com/vid553) for the Zephyr port
* [balamuruganky](https://github.com/balamuruganky) for the NAV-PVT velocity parameters
* [nelarsen](https://github.com/nelarsen) for the buffer overrun improvements
* [mstranne](https://github.com/mstranne) and [shaneperera](https://github.com/shaneperera) for the pushRawData suggestion
* [rubienr](https://github.com/rubienr) for spotting the logical AND issues

Need a Python version for Raspberry Pi? Checkout the [Qwiic Ublox GPS Py module](https://github.com/sparkfun/Qwiic_Ublox_Gps_Py).

Need a library for the Ublox and Particle? Checkout the [Particle library](https://github.com/aseelye/SparkFun_Ublox_Particle_Library) fork.

Contributing
--------------

If you would like to contribute to this library: please do, we truly appreciate it, but please follow [these guidelines](./CONTRIBUTING.md). Thanks!

Repository Contents
-------------------

* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE.
* **/src** - Source files for the library (.cpp, .h).
* **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE.
* **library.properties** - General library properties for the Arduino package manager.
* **[keywords.txt](./keywords.txt)** - Keywords from this library that will be highlighted in the Arduino IDE.
* **[library.properties](./library.properties)** - General library properties for the Arduino package manager.
* **[CONTRIBUTING.md](./CONTRIBUTING.md)** - Guidelines on how to contribute to this library.
* **[Theory.md](./Theory.md)** - provides detail on how data is processed by the library.

Documentation
--------------
Expand Down
13 changes: 10 additions & 3 deletions Theory.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ A method will call **sendCommand()**. This will begin waiting for a response wit

Once **waitForACKResponse()** or **waitForNoACKResponse()** is called the library will start checking the ublox module for new bytes. These bytes may be part of a NMEA sentence, an RTCM sentence, or a UBX packet. The library will file each byte into the appropriate container. Once a given sentence or packet is complete, the appropriate processUBX(), processNMEA() will be called. These functions deal with specific processing for each type.

Note: When interfacing to a ublox module over I2C **checkUbloxI2C()** will read all bytes currently sitting in the I2C buffer. This may pick up multiple UBX packets. For example, an ACK for a VALSET may be mixed in with an auto-PVT response. We cannot tell **checkUbloxI2C()** to stop once a given ACK is found because we run the risk of leaving bytes in the I2C buffer and losing them. We don't have this issue with **checkUbloxSerial()**.
Note: When interfacing to a ublox module over I2C **checkUbloxI2C()** will read all bytes currently sitting in the I2C buffer. This may pick up multiple UBX packets. For example, an ACK for a VALSET may be mixed in with an **AutoPVT** response. We cannot tell **checkUbloxI2C()** to stop once a given ACK is found because we run the risk of leaving unprocessed bytes in the I2C buffer and losing them. We don't have this issue with **checkUbloxSerial()**.

**processUBX()** will check the CRC of the UBX packet. If validated, the packet will be marked as valid. Once a packet is marked as valid then **processUBXpacket()** is called to extract the contents. This is most commonly used to get the position, velocity, and time (PVT) out of the packet but is also used to check the nature of an ACK packet.

Once a packet has been processed, **waitForACKResponse()/waitForNoACKResponse()** makes the appropriate decision what to do with it. If a packet satisfies the CLS/ID and characteristics of what **waitForACKResponse()/waitForNoACKResponse()** is waiting for, then it returns back to sendCommand. If the packet didn't match or was invalid then **waitForACKResponse()/waitForNoACKResponse()** will continue to wait until the correct packet is received or we time out. **sendCommand()** then returns with a value from the **sfe_ublox_status_e** enum depending on the success of **waitForACKResponse()/waitForNoACKResponse()**.
Once a packet has been processed, **waitForACKResponse()/waitForNoACKResponse()** makes the appropriate decision what to do with it. If a packet satisfies the CLS/ID and characteristics of what **waitForACKResponse()/waitForNoACKResponse()** is waiting for, then it returns back to **sendCommand()**. If the packet didn't match or was invalid then **waitForACKResponse()/waitForNoACKResponse()** will continue to wait until the correct packet is received or we time out. **sendCommand()** then returns with a value from the **sfe_ublox_status_e** enum depending on the success of **waitForACKResponse()/waitForNoACKResponse()**.

If we are getting / polling data from the module, **sendCommand()** will return **SFE_UBLOX_STATUS_DATA_RECEIVED** if the get was successful.

If we are setting / writing data to the module, **sendCommand()** will return **SFE_UBLOX_STATUS_DATA_SENT** if the set was successful.

There are circumstances where the library can get the data it is expecting from the module, but it is overwritten (e.g. by an auto-PVT packet) before **sendCommand()** is able to return. In this case, **sendCommand()** will return the error **SFE_UBLOX_STATUS_DATA_OVERWRITTEN**. We should simply call the library function again, but we will need to reset the packet contents first as they will indeed have been overwritten as the error implies.
We are proud that this library still compiles and runs on the original RedBoard (ATmega328P). We achieve that by being very careful about how much RAM we allocate to packet storage. We use only three buffers or containers to store the incoming data:
- **packetBuf** (packetBuffer) - is small and is used to store only the head (and tail) of incoming UBX packets until we know they are. If the packet is _expected_ (i.e. it matches the Class and ID in the packet passed in **sendCommand()**) then the incoming bytes are diverted into **packetCfg** or **packetAck**. Unexpected packets are ignored.
- **packetCfg** (packetConfiguration) - is used to store an _expected_ incoming UBX packet of up to 256 bytes. E.g. **getProtocolVersion()** returns about 220 bytes. Message data requested by a higher function is returned in packetCfg.
- **packetAck** (packetAcknowledge) - is small and is used to store the ACK or NACK accompanying any _expected_ packetCfg.

**AutoPVT**, **AutoHPPOSLLH** and **AutoDOP** packets can arrive at any time. They too _have_ to be stored and processed in **packetCfg**. This means there are circumstances where the library can get the data it is expecting from the module, but it is overwritten (e.g. by an **AutoPVT** packet) before **sendCommand()** is able to return. In this case, **sendCommand()** will return the error **SFE_UBLOX_STATUS_DATA_OVERWRITTEN**. We should simply call the library function again, but we will need to reset the packet contents first as they will indeed have been overwritten as the error implies.

Need a command that is not currently "built-in" to the library? You can do that using a Custom Command. Check out [Example20_SendCustomCommand](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/blob/master/examples/Example20_SendCustomCommand/Example20_SendCustomCommand.ino) for further details. Note: this will of course increase your RAM use.
27 changes: 26 additions & 1 deletion examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,32 @@ void loop()
int PDOP = myGPS.getPDOP();
Serial.print(F(" PDOP: "));
Serial.print(PDOP);
Serial.print(F(" (10^-2)"));
Serial.print(F(" (10^-2)"));

int nedNorthVel = myGPS.getNedNorthVel();
Serial.print(F(" VelN: "));
Serial.print(nedNorthVel);
Serial.print(F(" (mm/s)"));

int nedEastVel = myGPS.getNedEastVel();
Serial.print(F(" VelE: "));
Serial.print(nedEastVel);
Serial.print(F(" (mm/s)"));

int nedDownVel = myGPS.getNedDownVel();
Serial.print(F(" VelD: "));
Serial.print(nedDownVel);
Serial.print(F(" (mm/s)"));

int verticalAccEst = myGPS.getVerticalAccEst();
Serial.print(F(" VAccEst: "));
Serial.print(verticalAccEst);
Serial.print(F(" (mm)"));

int horizontalAccEst = myGPS.getHorizontalAccEst();
Serial.print(F(" HAccEst: "));
Serial.print(horizontalAccEst);
Serial.print(F(" (mm)"));

Serial.println();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,9 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
switch (msg->cls)
{
case UBX_CLASS_NAV:
if (msg->id == UBX_NAV_PVT && msg->len == 92)
//u-blox8 length == 92
//u-blox7 length == 84
if ((msg->id == UBX_NAV_PVT) && ((msg->len == 92) || (msg->len == 84)))
{
//Parse various byte fields into global vars
constexpr int startingSpot = 0; //fixed value used in processUBX
Expand All @@ -915,6 +917,7 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
gpsNanosecond = extractLong(16); //Includes milliseconds

fixType = extractByte(20 - startingSpot);
//Note: the u-blox7 does not support carrSoln. carrierSolution will be zero.
carrierSolution = extractByte(21 - startingSpot) >> 6; //Get 6th&7th bits of this byte
SIV = extractByte(23 - startingSpot);
longitude = extractLong(24 - startingSpot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void setup()
Wire.begin();

//myGPS.enableDebugging(); // Uncomment this line to enable lots of helpful debug messages
//myGPS.enableDebugging(Serial, true); // Uncomment this line to enable the minimum of helpful debug messages

if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
{
Expand All @@ -55,21 +56,21 @@ void setup()

myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR

myGPS.setNavigationFrequency(1); //Produce one solution per second


// The acid test: all four of these combinations should work seamlessly :-)

//myGPS.setAutoPVT(false); // Library will poll each reading
//myGPS.setAutoHPPOSLLH(false); // Library will poll each reading

//myGPS.setAutoPVT(true); // Tell the GPS to "send" each solution automatically
//myGPS.setAutoHPPOSLLH(false); // Library will poll each reading

//myGPS.setAutoPVT(false); // Library will poll each reading
//myGPS.setAutoHPPOSLLH(true); // Tell the GPS to "send" each hi res solution automatically

myGPS.setAutoPVT(true); // Tell the GPS to "send" each solution automatically
myGPS.setAutoHPPOSLLH(true); // Tell the GPS to "send" each hi res solution automatically
}
Expand All @@ -81,31 +82,31 @@ void loop()
if ((myGPS.getHPPOSLLH()) || (myGPS.getPVT()))
{
Serial.println();

long highResLatitude = myGPS.getHighResLatitude();
Serial.print(F("Hi Res Lat: "));
Serial.print(highResLatitude);

int highResLatitudeHp = myGPS.getHighResLatitudeHp();
Serial.print(F(" "));
Serial.print(highResLatitudeHp);

long highResLongitude = myGPS.getHighResLongitude();
Serial.print(F(" Hi Res Long: "));
Serial.print(highResLongitude);

int highResLongitudeHp = myGPS.getHighResLongitudeHp();
Serial.print(F(" "));
Serial.print(highResLongitudeHp);

unsigned long horizAccuracy = myGPS.getHorizontalAccuracy();
Serial.print(F(" Horiz accuracy: "));
Serial.print(horizAccuracy);

long latitude = myGPS.getLatitude();
Serial.print(F(" Lat: "));
Serial.print(latitude);

long longitude = myGPS.getLongitude();
Serial.print(F(" Long: "));
Serial.println(longitude);
Expand Down
19 changes: 17 additions & 2 deletions examples/ZED-F9P/Example3_StartRTCMBase/Example3_StartRTCMBase.ino
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
SFE_UBLOX_GPS myGPS;

//#define USE_SERIAL1 // Uncomment this line to push the RTCM data to Serial1

void setup()
{
Serial.begin(115200);
while (!Serial); //Wait for user to open terminal
Serial.println("Ublox Base station example");

#ifdef USE_SERIAL1
// If our board supports it, we can output the RTCM data on Serial1
Serial1.begin(115200);
#endif

Wire.begin();
Wire.setClock(400000); //Increase I2C clock speed to 400kHz

Expand All @@ -44,8 +51,11 @@ void setup()
while (1);
}

// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
//myGPS.factoryDefault(); delay(5000);

myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR

while (Serial.available()) Serial.read(); //Clear any latent chars in serial buffer
Serial.println("Press any key to send commands to begin Survey-In");
Expand Down Expand Up @@ -153,7 +163,12 @@ void loop()
//Useful for passing the RTCM correction data to a radio, Ntrip broadcaster, etc.
void SFE_UBLOX_GPS::processRTCM(uint8_t incoming)
{
//Let's just pretty-print the HEX values for now
#ifdef USE_SERIAL1
//Push the RTCM data to Serial1
Serial1.write(incoming);
#endif

//Pretty-print the HEX values to Serial
if (myGPS.rtcmFrameCounter % 16 == 0) Serial.println();
Serial.print(" ");
if (incoming < 0x10) Serial.print("0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,21 @@
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
SFE_UBLOX_GPS myGPS;

//#define USE_SERIAL1 // Uncomment this line to push the RTCM data from Serial1 to the module via I2C

size_t numBytes = 0; // Record the number os bytes received from Serial1

void setup()
{
Serial.begin(115200);
while (!Serial); //Wait for user to open terminal
Serial.println("Ublox Base station example");

#ifdef USE_SERIAL1
// If our board supports it, we can receive the RTCM data on Serial1
Serial1.begin(115200);
#endif

Wire.begin();
Wire.setClock(400000); //Increase I2C clock speed to 400kHz

Expand All @@ -40,6 +49,15 @@ void setup()
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
while (1);
}

// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
//myGPS.factoryDefault(); delay(5000);

#ifdef USE_SERIAL1
Serial.print(F("Enabling UBX and RTCM input on I2C. Result: "));
Serial.print(myGPS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_RTCM3)); //Enable UBX and RTCM input on I2C
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save the communications port settings to flash and BBR
#endif
}

void loop()
Expand Down Expand Up @@ -121,5 +139,23 @@ void loop()
else
Serial.println("RELPOS request failed");

delay(4000);
for (int i = 0; i < 500; i++)
{
#ifdef USE_SERIAL1
uint8_t store[256];
while ((Serial1.available()) && (numBytes < 256)) // Check if data has been received
{
store[numBytes++] = Serial1.read(); // Read a byte from Serial1 and store it
}
if (numBytes > 0) // Check if data was received
{
//Serial.print("Pushing ");
//Serial.print(numBytes);
//Serial.println(" bytes via I2C");
myGPS.pushRawData(((uint8_t *)&store), numBytes); // Push the RTCM data via I2C
numBytes = 0; // Reset numBytes
}
#endif
delay(10);
}
}
Loading

0 comments on commit 9fc9c03

Please sign in to comment.