Skip to content

Commit 3e7e112

Browse files
committed
Add support for new elevation and CNR commands
1 parent 277f689 commit 3e7e112

File tree

5 files changed

+198
-3
lines changed

5 files changed

+198
-3
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
Configuring minimum elevation and CNR used in the positioning engine
3+
By: Nathan Seidle + Mikal Hart
4+
SparkFun Electronics
5+
Date: 20 May 2025
6+
License: MIT. Please see LICENSE.md for more information.
7+
8+
This example shows how to configure the min elevation and CNR used for the position engine.
9+
10+
It is a known practice to raise the minimum elevation from the default of 5 degrees to 10 or even 15 degrees
11+
when in an urban environment to exclude satellites that are too low and may be blocked by structures causing
12+
multipath errors. Similarly, increasing the minimum CNR from 10 dBHz to 20 or 25 dBHz can exclude satellites
13+
with lower signal strength from being used in the position calculation.
14+
15+
The LG290P firmware must be v5 ("LG290P03AANR01A05S") or higher for these commands to work. We recommend using the QGNSS software
16+
to update the LG290P firmware.
17+
Latest Firmware: https://github.com/sparkfun/SparkFun_RTK_Postcard/tree/main/Firmware
18+
Docs: https://docs.sparkfun.com/SparkFun_LG290P_Quadband_GNSS_RTK_Breakout/software_overview/#qgnss-software
19+
20+
These examples are targeted for an ESP32 platform but any platform that has multiple
21+
serial UARTs should be compatible.
22+
23+
Feel like supporting open source hardware?
24+
Buy a board from SparkFun!
25+
SparkFun Quadband GNSS RTK Breakout - LG290P (GPS-26620) https://www.sparkfun.com/products/26620
26+
27+
Hardware Connections:
28+
Connect RX3 (green wire) of the LG290P to pin 14 on the ESP32
29+
Connect TX3 (orange wire) of the LG290P to pin 13 on the ESP32
30+
To make this easier, a 4-pin locking JST cable can be purchased here: https://www.sparkfun.com/products/17240
31+
Note: Almost any ESP32 pins can be used for serial.
32+
Connect a multi-band GNSS antenna: https://www.sparkfun.com/products/21801
33+
*/
34+
35+
#include <SparkFun_LG290P_GNSS.h> // Click here to get the library: http://librarymanager/All#SparkFun_LG290P
36+
37+
// Adjust these values according to your configuration
38+
int pin_UART1_TX = 14;
39+
int pin_UART1_RX = 13;
40+
int gnss_baud = 460800;
41+
42+
LG290P myGNSS;
43+
HardwareSerial SerialGNSS(1); // Use UART1 on the ESP32
44+
45+
void setup()
46+
{
47+
Serial.begin(115200);
48+
delay(250);
49+
Serial.println();
50+
Serial.println("SparkFun Elevation and CNR example");
51+
Serial.println("Initializing device...");
52+
53+
// We must start the serial port before using it in the library
54+
// Increase buffer size to handle high baud rate streams
55+
SerialGNSS.setRxBufferSize(1024);
56+
SerialGNSS.begin(gnss_baud, SERIAL_8N1, pin_UART1_RX, pin_UART1_TX);
57+
58+
// myGNSS.enableDebugging(Serial); // Print all debug to Serial
59+
if (myGNSS.begin(SerialGNSS) == false) // Give the serial port over to the library
60+
{
61+
Serial.println("LG290P failed to respond. Check ports and baud rates. Freezing...");
62+
while (true);
63+
}
64+
Serial.println("LG290P detected!");
65+
66+
int elevationAngle = 0;
67+
if (myGNSS.getElevationAngle(elevationAngle) == false)
68+
{
69+
Serial.println("Failed to read elevation angle. Do you have version 5 or newer of the LG290P firmware installed?");
70+
}
71+
else
72+
{
73+
Serial.printf("Successfully checked elevation angle: %d degrees\r\n", elevationAngle);
74+
75+
// 5 is default meaning any satellite 5 degrees above the horizon or higher will be used
76+
// 90 to -90 is allowed
77+
if (myGNSS.setElevationAngle(10) == false)
78+
Serial.println("Failed to set elevation angle");
79+
else
80+
{
81+
if (myGNSS.getElevationAngle(elevationAngle) == false)
82+
Serial.println("Failed to read elevation angle.");
83+
else
84+
{
85+
Serial.printf("Elevation angle set to %d degrees.\r\n", elevationAngle);
86+
}
87+
}
88+
}
89+
90+
float cnr = 0;
91+
if (myGNSS.getCNR(cnr) == false)
92+
{
93+
Serial.println("Failed to read CNR. Do you have version 5 or newer of the LG290P firmware installed?");
94+
}
95+
else
96+
{
97+
Serial.printf("Successfully checked CNR: %0.1f dBHz\r\n", cnr);
98+
99+
// 10.0 is default meaning any satellite with greater than 10 dBHz signal level will be included in the position fix calculation
100+
// 0.0 to 99.0 dBHz is allowed
101+
if (myGNSS.setCNR(15.0) == false)
102+
Serial.println("Failed to set CNR");
103+
else
104+
{
105+
if (myGNSS.getCNR(cnr) == false)
106+
Serial.println("Failed to read CNR.");
107+
else
108+
{
109+
Serial.printf("CNR set to %0.1f dBHz.\r\n", cnr);
110+
}
111+
}
112+
}
113+
}
114+
115+
void loop()
116+
{
117+
118+
}

keywords.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ getProtLevelEastVelocity KEYWORD2
146146
getProtLevelDownVelocity KEYWORD2
147147
getProtLevelTime KEYWORD2
148148

149+
setElevationAngle KEYWORD2
150+
getElevationAngle KEYWORD2
151+
setCNR KEYWORD2
152+
getCNR KEYWORD2
153+
149154
#######################################
150155
# Constants (LITERAL1)
151156
#######################################

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SparkFun LG290P Quadband RTK GNSS Arduino Library
2-
version=1.0.4
2+
version=1.0.5
33
author=SparkFun Electronics
44
maintainer=SparkFun Electronics <sparkfun.com>
55
sentence=Library for Serial Communication and Configuration of the LG290P

src/SparkFun_LG290P_GNSS.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,46 @@ bool LG290P::getMessageRate(const char *msgName, int &rate, int msgVer)
665665
return ret;
666666
}
667667

668+
// Configures the elevation threshold for position engine. Available in v5 and above.
669+
bool LG290P::setElevationAngle(int elevationAngle)
670+
{
671+
char parms[50];
672+
snprintf(parms, sizeof parms, ",W,%d", elevationAngle);
673+
return sendOkCommand("PQTMCFGELETHD", parms) && hotStart();
674+
}
675+
676+
bool LG290P::getElevationAngle(int &elevationAngle)
677+
{
678+
bool ret = sendCommand("PQTMCFGELETHD", ",R");
679+
if (ret)
680+
{
681+
auto packet = getCommandResponse();
682+
ret = packet[1] == "OK";
683+
elevationAngle = atoi(packet[2].c_str());
684+
}
685+
return ret;
686+
}
687+
688+
// Configures the CNR threshold for position engine. Available in v5 and above.
689+
bool LG290P::setCNR(float cnr)
690+
{
691+
char parms[50];
692+
snprintf(parms, sizeof parms, ",W,%0.2f", cnr);
693+
return sendOkCommand("PQTMCFGCNRTHD", parms) && hotStart();
694+
}
695+
696+
bool LG290P::getCNR(float &cnr)
697+
{
698+
bool ret = sendCommand("PQTMCFGCNRTHD", ",R");
699+
if (ret)
700+
{
701+
auto packet = getCommandResponse();
702+
ret = packet[1] == "OK";
703+
cnr = atof(packet[2].c_str());
704+
}
705+
return ret;
706+
}
707+
668708
bool LG290P::scanForMsgsEnabled()
669709
{
670710
bool ok = getMessageRate("GGA", devState.ggaRate);

src/SparkFun_LG290P_GNSS.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,40 @@ class LG290P
407407
bool getFixInterval(uint16_t &fixInterval);
408408

409409
/**
410-
* @brief Sets a new fix interval.
411-
* @details Uses the PQTMCFGFIXRATE command. Use a value between 25 and 1000
410+
* @brief Sets a new elevation threshold for position engine.
411+
* @details Uses the PQTMCFGELETHD command. Use a value between -90 and 90. Default is 5 degrees.
412+
* @param elevationAngle The new elevation threshold for the position engine.
413+
* @return true if successful, false otherwise.
414+
*/
415+
bool setElevationAngle(int elevationAngle);
416+
417+
/**
418+
* @brief Gets the elevation threshold for position engine.
419+
* @details Uses the PQTMCFGELETHD command.
420+
* @param elevationAngle Reference to a int where the elevation angle (degrees) will be stored.
421+
* @return true if successful, false otherwise.
422+
*/
423+
bool getElevationAngle(int &elevationAngle);
424+
425+
/**
426+
* @brief Sets the CNR threshold for position engine.
427+
* @details Uses the PQTMCFGCNRTHD command. Use a value between 0.0 and 99.0. Default is 10.0 dBHz.
428+
* @param cnr The new CNR threshold for the position engine.
429+
* @return true if successful, false otherwise.
430+
*/
431+
bool setCNR(float cnr);
432+
433+
/**
434+
* @brief Gets the CNR threshold for position engine.
435+
* @details Uses the PQTMCFGCNRTHD command.
436+
* @param cnr Reference to a float where the CNR value will be stored.
437+
* @return true if successful, false otherwise.
438+
*/
439+
bool getCNR(float &cnr);
440+
441+
/**
442+
* @brief Sets a new elevation threshold for position engine.
443+
* @details Uses the PQTMCFGELETHD command. Use a value between -90 and 90
412444
* @param fixInterval The new fix interval to set.
413445
* @return true if successful, false otherwise.
414446
*/

0 commit comments

Comments
 (0)