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

Add support for TMOD3 fixed position. #135

Merged
merged 2 commits into from
Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
Set the static position of the receiver.
By: SparkFun Electronics / Nathan Seidle
Date: September 26th, 2020
License: MIT. See license file for more information but you can
basically do whatever you want with this code.

This example shows how to set the static position of a receiver
using an Earth-Centered, Earth-Fixed (ECEF) location. This is the
output from a long (24 hour+) survey-in. Setting the static position
immediately causes the receiver to begin outputting RTCM data (if
enabled), perfect for setting up your own RTCM NTRIP caster or CORS.

Feel like supporting open source hardware?
Buy a board from SparkFun!
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
NEO-M8P RTK: https://www.sparkfun.com/products/15005
SAM-M8Q: https://www.sparkfun.com/products/15106

Hardware Connections:
Plug a Qwiic cable into the GPS and a BlackBoard
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 <Wire.h> //Needed for I2C to GPS

#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS
SFE_UBLOX_GPS myGPS;

void setup()
{
Serial.begin(115200); // You may need to increase this for high navigation rates!
while (!Serial)
; //Wait for user to open terminal
Serial.println(F("SparkFun u-blox Example"));

Wire.begin();

//myGPS.enableDebugging(); // Uncomment this line to enable debug messages

if (myGPS.begin() == false) //Connect to the u-blox module using Wire port
{
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
while (1)
;
}

myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)

//-1280208.308,-4716803.847,4086665.811 is SparkFun HQ so...

//Units are cm so 1234 = 12.34m
//myGPS.setStaticPosition(-128020831, -471680385, 408666581);

//Units are cm with a high precision extension so -1234.5678 should be called: (-123456, -78)
myGPS.setStaticPosition(-128020830, -80, -471680384, -70, 408666581, 10, true, 250); //With high precision 0.1mm parts

//We can also set via lat/long
//40.09029751,-105.18507900,1560.238
//myGPS.setStaticPosition(400902975, -1051850790, 156024, true); //True at end enables lat/long input
//myGPS.setStaticPosition(400902975, 10, -1051850790, 0, 156023, 80, true);

//Now let's use getVals to read back the data
//long ecefX = myGPS.getVal32(0x40030003);
//Serial.print("ecefX: ");
//Serial.println(ecefX);

Serial.println(F("Done!"));
}

void loop()
{
}
1 change: 1 addition & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ getVehAtt KEYWORD2
setI2CTransactionSize KEYWORD2
getI2CTransactionSize KEYWORD2

setStaticPosition KEYWORD2

#######################################
# Constants (LITERAL1)
Expand Down
57 changes: 57 additions & 0 deletions src/SparkFun_Ublox_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3533,3 +3533,60 @@ boolean SFE_UBLOX_GPS::getVehAtt(uint16_t maxWait)

return (true);
}

//Set the ECEF coordinates of a receiver
//This imediately puts the receiver in TIME mode (fixed) and will begin outputting RTCM sentences if enabled
//This is helpful once an antenna's position has been established. See this tutorial: https://learn.sparkfun.com/tutorials/how-to-build-a-diy-gnss-reference-station#gather-raw-gnss-data
bool SFE_UBLOX_GPS::setStaticPosition(int32_t ecefX, int8_t ecefXHP, int32_t ecefY, int8_t ecefYHP, int32_t ecefZ, int8_t ecefZHP, bool latLong, uint16_t maxWait)
{
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_TMODE3;
packetCfg.len = 0;
packetCfg.startingSpot = 0;

//Ask module for the current TimeMode3 settings. Loads into payloadCfg.
if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED)
return (false);

packetCfg.len = 40;

//Clear packet payload
for (uint8_t x = 0; x < packetCfg.len; x++)
payloadCfg[x] = 0;

//customCfg should be loaded with poll response. Now modify only the bits we care about
payloadCfg[2] = 2; //Set mode to fixed. Use ECEF (not LAT/LON/ALT).

if (latLong == true)
payloadCfg[3] = (uint8_t)(1 << 0); //Set mode to fixed. Use LAT/LON/ALT.

//Set ECEF X
payloadCfg[4] = (ecefX >> 8 * 0) & 0xFF; //LSB
payloadCfg[5] = (ecefX >> 8 * 1) & 0xFF;
payloadCfg[6] = (ecefX >> 8 * 2) & 0xFF;
payloadCfg[7] = (ecefX >> 8 * 3) & 0xFF; //MSB

//Set ECEF Y
payloadCfg[8] = (ecefY >> 8 * 0) & 0xFF; //LSB
payloadCfg[9] = (ecefY >> 8 * 1) & 0xFF;
payloadCfg[10] = (ecefY >> 8 * 2) & 0xFF;
payloadCfg[11] = (ecefY >> 8 * 3) & 0xFF; //MSB

//Set ECEF Z
payloadCfg[12] = (ecefZ >> 8 * 0) & 0xFF; //LSB
payloadCfg[13] = (ecefZ >> 8 * 1) & 0xFF;
payloadCfg[14] = (ecefZ >> 8 * 2) & 0xFF;
payloadCfg[15] = (ecefZ >> 8 * 3) & 0xFF; //MSB

//Set ECEF high precision bits
payloadCfg[16] = ecefXHP;
payloadCfg[17] = ecefYHP;
payloadCfg[18] = ecefZHP;

return ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
}

bool SFE_UBLOX_GPS::setStaticPosition(int32_t ecefX, int32_t ecefY, int32_t ecefZ, bool latlong, uint16_t maxWait)
{
return (setStaticPosition(ecefX, 0, ecefY, 0, ecefZ, 0, latlong, maxWait));
}
6 changes: 5 additions & 1 deletion src/SparkFun_Ublox_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ class SFE_UBLOX_GPS
//Control the size of the internal I2C transaction amount
void setI2CTransactionSize(uint8_t bufferSize);
uint8_t getI2CTransactionSize(void);

//Set the max number of bytes set in a given I2C transaction
uint8_t i2cTransactionSize = 32; //Default to ATmega328 limit

Expand Down Expand Up @@ -641,6 +641,10 @@ class SFE_UBLOX_GPS
sfe_ublox_status_e getSensState(uint8_t sensor, uint16_t maxWait = 1100);
boolean getVehAtt(uint16_t maxWait = 1100);

//Given coordinates, put receiver into static position. Set latlong to true to pass in lat/long values instead of ecef.
bool setStaticPosition(int32_t ecefX, int8_t ecefXHP, int32_t ecefY, int8_t ecefYHP, int32_t ecefZ, int8_t ecefZHP, bool latLong = false, uint16_t maxWait = 250);
bool setStaticPosition(int32_t ecefX, int32_t ecefY, int32_t ecefZ, bool latlong = true, uint16_t maxWait = 250);

//Survey-in specific controls
struct svinStructure
{
Expand Down