Skip to content

Commit de3fd81

Browse files
committed
Add support for UBX-MON-HW2. Add Example30_NEO-D9S
1 parent cf47a92 commit de3fd81

File tree

5 files changed

+175
-0
lines changed

5 files changed

+175
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
NEO-D9S L-Band receiver example
3+
By: SparkFun Electronics / Paul Clark
4+
Date: March 7th, 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 display the NEO-D9S's received signal imbalance and magnitude, plus a summary of any received PMP data.
9+
10+
Feel like supporting open source hardware?
11+
Buy a board from SparkFun!
12+
ZED-F9P RTK2: https://www.sparkfun.com/products/16481
13+
NEO-D9S: Coming soon!
14+
15+
Hardware Connections:
16+
Use a Qwiic cable to connect the NEO-D9S L-Band corection data receiver to your board
17+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
18+
Open the serial monitor at 115200 baud to see the output
19+
*/
20+
21+
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
22+
SFE_UBLOX_GNSS myLBand; // NEO-D9S
23+
24+
//const uint32_t myLBandFreq = 1556290000; // Uncomment this line to use the US SPARTN 1.8 service
25+
const uint32_t myLBandFreq = 1545260000; // Uncomment this line to use the EU SPARTN 1.8 service
26+
27+
#define OK(ok) (ok ? F(" -> OK") : F(" -> ERROR!")) // Convert uint8_t into OK/ERROR
28+
29+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
30+
31+
// Callback: printRXMPMP will be called when new PMP data arrives
32+
// See u-blox_structs.h for the full definition of UBX_RXM_PMP_data_t
33+
// _____ You can use any name you like for the callback. Use the same name when you call setRXMPMPcallbackPtr
34+
// / _____ This _must_ be UBX_RXM_PMP_data_t
35+
// | / _____ You can use any name you like for the struct
36+
// | | /
37+
// | | |
38+
void printRXMPMP(UBX_RXM_PMP_data_t *pmpData)
39+
{
40+
Serial.println(F("New PMP data received:"));
41+
42+
Serial.print(F("PMP message version: "));
43+
Serial.println(pmpData->version);
44+
45+
Serial.print(F("numBytesUserData : "));
46+
Serial.println(pmpData->numBytesUserData);
47+
48+
Serial.print(F("serviceIdentifier: "));
49+
Serial.println(pmpData->serviceIdentifier);
50+
51+
Serial.print(F("uniqueWordBitErrors: "));
52+
Serial.println(pmpData->uniqueWordBitErrors);
53+
54+
Serial.print(F("fecBits: "));
55+
Serial.println(pmpData->fecBits);
56+
57+
Serial.print(F("ebno: "));
58+
Serial.println(pmpData->ebno);
59+
60+
Serial.println();
61+
}
62+
63+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
64+
65+
void setup()
66+
{
67+
Serial.begin(115200);
68+
Serial.println(F("NEO-D9S Example"));
69+
70+
Wire.begin(); //Start I2C
71+
72+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
73+
// Begin and configure the NEO-D9S L-Band receiver
74+
75+
//myLBand.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
76+
77+
while (myLBand.begin(Wire, 0x43) == false) //Connect to the u-blox NEO-D9S using Wire port. The D9S default I2C address is 0x43 (not 0x42)
78+
{
79+
Serial.println(F("u-blox NEO-D9S not detected at default I2C address. Please check wiring."));
80+
delay(2000);
81+
}
82+
Serial.println(F("u-blox NEO-D9S connected"));
83+
84+
uint8_t ok = myLBand.setVal32(UBLOX_CFG_PMP_CENTER_FREQUENCY, myLBandFreq); // Default 1539812500 Hz
85+
if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_SEARCH_WINDOW, 2200); // Default 2200 Hz
86+
if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_SERVICE_ID, 0); // Default 1
87+
if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_SERVICE_ID, 21845); // Default 50821
88+
if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_DATA_RATE, 2400); // Default 2400 bps
89+
if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_DESCRAMBLER, 1); // Default 1
90+
if (ok) ok = myLBand.setVal16(UBLOX_CFG_PMP_DESCRAMBLER_INIT, 26969); // Default 23560
91+
if (ok) ok = myLBand.setVal8(UBLOX_CFG_PMP_USE_PRESCRAMBLING, 0); // Default 0
92+
if (ok) ok = myLBand.setVal64(UBLOX_CFG_PMP_UNIQUE_WORD, 16238547128276412563ull);
93+
if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_I2C, 1); // Ensure UBX-RXM-PMP is enabled on the I2C port
94+
if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART1, 1); // Output UBX-RXM-PMP on UART1
95+
if (ok) ok = myLBand.setVal(UBLOX_CFG_MSGOUT_UBX_RXM_PMP_UART2, 1); // Output UBX-RXM-PMP on UART2
96+
if (ok) ok = myLBand.setVal32(UBLOX_CFG_UART1_BAUDRATE, 38400); // match baudrate with ZED default
97+
if (ok) ok = myLBand.setVal32(UBLOX_CFG_UART2_BAUDRATE, 38400); // match baudrate with ZED default
98+
99+
Serial.print(F("L-Band: configuration "));
100+
Serial.println(OK(ok));
101+
102+
myLBand.softwareResetGNSSOnly(); // Do a restart
103+
104+
myLBand.setRXMPMPcallbackPtr(&printRXMPMP); // Call printRXMPMP when new PMP data arrives
105+
}
106+
107+
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
108+
109+
void loop()
110+
{
111+
myLBand.checkUblox(); // Check for the arrival of new PMP data and process it.
112+
myLBand.checkCallbacks(); // Check if any LBand callbacks are waiting to be processed.
113+
114+
UBX_MON_HW2_data_t hwStatus; // Create storage for the HW2 extended hardware status
115+
if (myLBand.getHW2status(&hwStatus)) // Request the extended hardware status
116+
{
117+
// Print the signal imbalance and magnitude
118+
Serial.print(F("Signal imbalance and magnitude: ofsI: "));
119+
Serial.print(hwStatus.ofsI);
120+
Serial.print(F(" magI: "));
121+
Serial.print(hwStatus.magI);
122+
Serial.print(F(" ofsQ: "));
123+
Serial.print(hwStatus.ofsQ);
124+
Serial.print(F(" magQ: "));
125+
Serial.println(hwStatus.magQ);
126+
}
127+
}

keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ UBX_ESF_STATUS_sensorStatus_t KEYWORD1
1919
UBX_CFG_ITFM_data_t KEYWORD1
2020
UBX_MON_RF_data_t KEYWORD1
2121
UBX_MON_HW_data_t KEYWORD1
22+
UBX_MON_HW2_data_t KEYWORD1
2223

2324
UBX_NAV_POSECEF_data_t KEYWORD1
2425
UBX_NAV_STATUS_data_t KEYWORD1
@@ -195,6 +196,7 @@ setJammingConfiguration KEYWORD2
195196
getRFinformation KEYWORD2
196197

197198
getHWstatus KEYWORD2
199+
getHW2status KEYWORD2
198200

199201
getAckAiding KEYWORD2
200202
setAckAiding KEYWORD2

src/SparkFun_u-blox_GNSS_Arduino_Library.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8232,6 +8232,32 @@ bool SFE_UBLOX_GNSS::getHWstatus(UBX_MON_HW_data_t *data, uint16_t maxWait)
82328232
return (true);
82338233
}
82348234

8235+
// Get the extended hardware status using UBX_MON_HW2
8236+
bool SFE_UBLOX_GNSS::getHW2status(UBX_MON_HW2_data_t *data, uint16_t maxWait)
8237+
{
8238+
if (data == NULL) // Check if the user forgot to include the data pointer
8239+
return (false); // Bail
8240+
8241+
packetCfg.cls = UBX_CLASS_MON;
8242+
packetCfg.id = UBX_MON_HW2;
8243+
packetCfg.len = 0;
8244+
packetCfg.startingSpot = 0;
8245+
8246+
if (sendCommand(&packetCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK
8247+
return (false);
8248+
8249+
// Extract the data
8250+
data->ofsI = extractSignedChar(&packetCfg, 0);
8251+
data->magI = extractByte(&packetCfg, 1);
8252+
data->ofsQ = extractSignedChar(&packetCfg, 2);
8253+
data->magQ = extractByte(&packetCfg, 3);
8254+
data->cfgSource = extractByte(&packetCfg, 4);
8255+
data->lowLevCfg = extractLong(&packetCfg, 8); // Low-level configuration (obsolete for protocol versions greater than 15.00)
8256+
data->postStatus = extractLong(&packetCfg, 20);
8257+
8258+
return (true);
8259+
}
8260+
82358261
// UBX-CFG-NAVX5 - get/set the ackAiding byte. If ackAiding is 1, UBX-MGA-ACK messages will be sent by the module to acknowledge the MGA data
82368262
uint8_t SFE_UBLOX_GNSS::getAckAiding(uint16_t maxWait) // Get the ackAiding byte - returns 255 if the sendCommand fails
82378263
{

src/SparkFun_u-blox_GNSS_Arduino_Library.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,9 @@ class SFE_UBLOX_GNSS
928928
// Hardware status (including jamming)
929929
bool getHWstatus(UBX_MON_HW_data_t *data = NULL, uint16_t maxWait = defaultMaxWait); // Get the hardware status using UBX_MON_HW
930930

931+
// Extended hardware status
932+
bool getHW2status(UBX_MON_HW2_data_t *data = NULL, uint16_t maxWait = defaultMaxWait); // Get the extended hardware status using UBX_MON_HW2
933+
931934
// UBX-CFG-NAVX5 - get/set the ackAiding byte. If ackAiding is 1, UBX-MGA-ACK messages will be sent by the module to acknowledge the MGA data
932935
uint8_t getAckAiding(uint16_t maxWait = defaultMaxWait); // Get the ackAiding byte - returns 255 if the sendCommand fails
933936
bool setAckAiding(uint8_t ackAiding, uint16_t maxWait = defaultMaxWait); // Set the ackAiding byte

src/u-blox_structs.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,23 @@ typedef struct
17341734
uint8_t pullL; // Mask of pins value using the PIO pull low resistor
17351735
} UBX_MON_HW_data_t;
17361736

1737+
// UBX-MON-HW2 (0x0A 0x0B): Extended hardware status
1738+
const uint16_t UBX_MON_HW2_LEN = 28;
1739+
1740+
typedef struct
1741+
{
1742+
int8_t ofsI; // Imbalance of I-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance)
1743+
uint8_t magI; // Magnitude of I-part of complex signal, scaled (0 = no signal, 255 = max. magnitude)
1744+
int8_t ofsQ; // Imbalance of Q-part of complex signal, scaled (-128 = max. negative imbalance, 127 = max. positive imbalance)
1745+
uint8_t magQ; // Magnitude of Q-part of complex signal, scaled (0 = no signal, 255 = max. magnitude)
1746+
uint8_t cfgSource; // Source of low-level configuration (114 = ROM, 111 = OTP, 112 = config pins, 102 = flash image)
1747+
uint8_t reserved0[3];
1748+
uint32_t lowLevCfg; // Low-level configuration (obsolete for protocol versions greater than 15.00)
1749+
uint8_t reserved1[8];
1750+
uint32_t postStatus; // POST status word
1751+
uint8_t reserved2[4]; // Reserved
1752+
} UBX_MON_HW2_data_t;
1753+
17371754
// UBX-MON-RF (0x0a 0x38): RF information
17381755
const uint16_t UBX_MON_RF_MAX_BLOCKS = 2; // 0 = L1; 1 = L2 / L5
17391756
const uint16_t UBX_MON_RF_MAX_LEN = 4 + (24 * UBX_MON_RF_MAX_BLOCKS);

0 commit comments

Comments
 (0)