1. Introduction
In the past, when people thought of high-precision centimeter-level RTK positioning, their first impressions were professional applications and high costs. Industry users might have thought of total stations, surveying instruments, handheld high-precision devices, etc., and it was only used in professional fields. However, with technological advancements and updates, RTK high-precision positioning technology is now increasingly recognized and applied across various scenarios. Traditional GPS and GNSS positioning accuracy can no longer meet the demands of some existing application scenarios. Based on this, DFRobot has launched an entry-level RTK positioning kit. It incorporates Quectel's LC29HDA rover module and LC29HBS base station module, combined with LoRa wireless transmission, enabling high-precision centimeter-level positioning within a radius of 1.5KM in open areas.
Both the base station and rover are L1/L5 dual-frequency modules, supporting simultaneous reception of GNSS, GPS, GLONASS, Galileo, BDS, and QZSS satellites. They can track GPS L1 C/A, GLONASS L1, Galileo E1, BDS B1I, QZSS L1 C/A, GPS L5, Galileo E5a, BDS B2a, and QZSS L5 frequency bands. The rover can quickly acquire latitude, longitude, time, altitude, and other information upon power-up; the base station rapidly converges after power-up to provide correction data. The base station transmits RTCM data wirelessly via LoRa, and after receiving the RTCM data, the rover performs differential calculations to achieve rapid centimeter-level positioning in open areas.
Unlike commonly available high-precision positioning modules on the market that require users to set up a data link after purchase—a process that could deter many beginners—this kit comes with a fully configured data link. As a ready-to-use kit, it can be employed for introductory learning of RTK high-precision positioning, device tracking in open areas, trajectory mapping, personnel positioning, and more.
Note: Due to the characteristics of the GNSS antenna and LoRa antenna, the device must be used in an open area, and the LoRa antenna should ideally be mounted at a height greater than 2 meters. Otherwise, positioning accuracy and range may be adversely affected.
2. Appearance and Interfaces
2.1 Mobile
Name | Description |
---|---|
RTK | RTK status LED: Blinks at 1Hz for state 5 (positioning); Steady for state 4; Off for other states. |
PWR | Power indicator |
UART I2C | Toggle switch for UART/I2C communication interface |
Gravity I2C&UART | Gravity interface for data output |
2.2 Base Station
Name | Description |
---|---|
Type-C | Type-C power interface |
PWR | Power indicator |
PWR IN | External terminal power (5~10V) |
3. Basics of Positioning
3.1 Common Positioning Systems
GPS
Basic GPS positioning uses four satellites to determine 3D coordinates. Signal delays through the ionosphere/troposphere cause errors (~10m).
GNSS
Global Navigation Satellite System (GNSS) provides global 3D position, velocity, and time data via satellite radio navigation.
BDS (China)
BeiDou Navigation Satellite System offers decimeter/cm-level accuracy, 0.2 m/s velocity precision, and 10 ns timing accuracy.
GPS (USA)
Global Positioning System delivers global location, speed, and time data.
GLONASS (Russia)
Russia’s global satellite navigation system, similar to GPS.
Galileo (EU)
EU’s global satellite navigation system.
QZSS (Japan)
Quasi-Zenith Satellite System enhances GPS in the Pacific region, especially in urban canyons.
RTK
Real Time Kinematic (RTK) uses carrier-phase differential measurements. A base station transmits correction data (RTCM) to rovers for real-time cm-level accuracy.
3.2 Data Transmission Diagram
3.3 Positioning Basics
- Control surveys (e.g., engineering, topography)
- Topographic mapping
- Construction staking
3.4 NMEA Data Parsing
Modules output NMEA 0183 messages (e.g., RMC, GGA). Example GGA data:
$GNGGA,063924.000,3037.643956,N,10348.010829,E,5,34,0.46,507.909,M,-32.181,M,1.0,3335*76
Field | Name | Description | Example |
---|---|---|---|
0 | Identifier | Start character ($ ) |
$ |
1 | System | $GP (GPS), $GL (GLONASS), $GN (GNSS) |
$GNGGA |
2 | Sentence ID | GGA (Global Positioning System Fix Data) |
GGA |
3 | UTC Time | hhmmss.sss |
063924.000 |
4 | Latitude | ddmm.mmmmmm |
3037.643956 |
5 | N/S Indicator | N (North), S (South) |
N |
6 | Longitude | dddmm.mmmmmm |
10348.010829 |
7 | E/W Indicator | E (East), W (West) |
E |
8 | Position Fix | 0 =Invalid, 1 =GPS, 2 =DGPS, 4 =RTK Fixed, 5 =RTK Float |
5 |
9 | Satellites Used | Number of satellites | 34 |
10 | HDOP | Horizontal Dilution of Precision (lower = better) | 0.46 |
11 | MSL Altitude | Meters above Mean Sea Level | 507.909 |
12 | Units | M (meters) |
M |
13 | Geoid Separation | Geoid height above/below WGS84 ellipsoid (m) | -32.181 |
14 | Separation Units | M (meters) |
M |
15 | Differential Age | Age of RTK corrections (valid for RTK only) | 1.0 |
16 | Base Station ID | Reference station ID | 3335 |
17 | Checksum | * + hex value |
*76 |
4. Product Features
-
LoRa Data Transmission: Utilizes LoRa wireless technology for stable, long-range, and low-power communication of RTCM correction data between the base station and rover(s).
-
User-Friendly: Designed for ease of use with a pre-configured data link, enabling rapid setup and operation right out of the box.
-
Low Cost of Use: Provides an accessible entry point into high-precision positioning technology, minimizing initial investment and complexity.
-
Centimeter-Level Accuracy in Open Areas: Achieves high-precision centimeter-level positioning under optimal open-sky conditions.
-
Single Base Station Supports Multiple Mobile: One base station can broadcast correction data to several Mobile units simultaneously, improving efficiency and scalability.
5. Specifications
5.1 Base Station
- Power Supply:
- Type-C
- Terminal: 5~10V
- GNSS Antenna Interface: SMA
- Reception Bands:
- GPS/QZSS: L1 C/A, L5
- GLONASS: L1
- Galileo: E1, E5a
- BDS: B1I, B2a
- Default Constellations: GPS + GLONASS + Galileo + BDS + QZSS
- Concurrent Constellations: 4 + QGNSS
- Function: Base station
- Sensitivity:
- Acquisition: -147 dBm
- Tracking: -165 dBm
- Reacquisition: -159 dBm
- Dynamic Performance:
- Max Altitude: 10000 m
- Max Velocity: 500 m/s
- Max Acceleration: 4g
- Raw Data Update Rate: 1 Hz
- Protocol: NMEA 0183 / RTCM 3.x
- Dimensions: 92 × 58 × 31 mm
5.2 Mobile
- Operating Voltage: 3.3V~5V
- Output Signal: I2C/UART
- Antenna Interface: SMA
- Reception Bands:
- GPS/QZSS: L1 C/A, L5
- GLONASS: L1
- Galileo: E1, E5a
- BDS: B1I, B2a
- Default Constellations: GPS + GLONASS + Galileo + BDS + QZSS
- Concurrent Constellations: 4 + QGNSS
- SBAS: WAAS, EGNOS, MSAS, GAGAN
- Function: RTK
- Horizontal Positioning Accuracy:
- Autonomous: 1 m
- RTK: 5 cm + 1 ppm
- Velocity Accuracy: 0.03 m/s
- 1PPS Accuracy: 20 ns
- RTK Convergence Time: <10 s
- Sensitivity:
- Acquisition: -145 dBm
- Tracking: -165 dBm
- Reacquisition: -157 dBm
- Dynamic Performance:
- Max Altitude: 10000 m
- Max Velocity: 500 m/s
- Max Acceleration: 4g
- Navigation Update Rate: RTK: 1 Hz
- Raw Data Update Rate: GNSS: 1 Hz
- Protocol: NMEA 0183 / RTCM 3.x
- Dimensions: 92 × 58 × 31 mm
5.3 LoRa Module Specifications
- RF Chip: LLCC68
- Operating Frequency: 433 MHz
- Modulation: LoRa Spread Spectrum
- Max TX Power: 22 dBm
- RX Sensitivity: -129 dBm
6. User Guide
6.1 Arduino IDE User Guide
6.1.1 Hardware preparation
- DFR0216-2 DFRduino UNO R3 × 1
- GNSS-RTK High-Precision Positioning Kit x1
6.1.2 Software preparation
- Arduino IDE Download Arduino IDE
- Download and install the RTK Library.
- How to install libraries?
6.1.3 API
/**
* @fn getUTC
* @brief Get UTC, standard time
* @return sTim_t type, represents the returned hour, minute and second
* @retval sTim_t.hour hour
* @retval sTim_t.minute minute
* @retval sTim_t.second second
*/
sTim_t getUTC(void);
/**
* @fn getDate
* @brief Get date information, year, month, day
* @return sTim_t type, represents the returned year, month, day
* @retval sTim_t.year year
* @retval sTim_t.month month
* @retval sTim_t.day day
*/
sTim_t getDate(void);
/**
* @fn getLat
* @brief Get latitude
* @return sLonLat_t type, represents the returned latitude
* @retval sLonLat_t.latDD Latitude degree(0-90)
* @retval sLonLat_t.latMM The first and second digits behind the decimal point
* @retval sLonLat_t.latMMMMM Latitude The third and seventh digits behind the decimal point
* @retval sLonLat_t.latitude Latitude value with 7 decimal digits
* @retval sLonLat_t.latDirection Direction of latitude
*/
sLonLat_t getLat(void);
/**
* @fn getLon
* @brief Get longitude
* @return sLonLat_t Type, represents the returned longitude
* @retval sLonLat_t.lonDDD Longitude degree(0-90)
* @retval sLonLat_t.lonMM Longitude The first and second digits behind the decimal point
* @retval sLonLat_t.lonMMMMM Longitude The third and seventh digits behind the decimal point
* @retval sLonLat_t.lonitude Longitude value with 7 decimal digits
* @retval sLonLat_t.lonDirection Direction of longitude
*/
sLonLat_t getLon(void);
/**
* @fn getNumSatUsed
* @brief Get the number of the used satellite used
* @return uint8_t type, represents the number of the used satellite
*/
uint8_t getNumSatUsed(void);
/**
* @fn getAlt
* @brief Altitude information
* @return double type, represents altitude
*/
double getAlt(void);
/**
* @fn getSep
* @brief At the height of geoid
* @return double
*/
double getSep(void);
/**
* @fn getHdop
* @brief Indicates the horizontal accuracy of positioning
* @return double
*/
double getHdop(void);
/**
* @fn getQuality
* @brief message Quality
* @return uint8_t
*/
uint8_t getQuality(void);
/**
* @fn getSiteID
* @brief The site id of differential gps data, commonly used for differential gps positioning
* @return uint16_t
*/
uint16_t getSiteID(void);
/**
* @fn getDifTime
* @brief The number of seconds in which a differential signal was last received
* @return double
*/
double getDifTime(void);
/**
* @fn setModule
* @brief Set the Module
* @param mode 4G or lora
*/
void setModule(eModuleMode_t mode);
/**
* @fn getModule
* @brief Get the Module run mode
* @return eModuleMode_t
*/
eModuleMode_t getModule(void);
/**
* @fn transmitAT
* @brief Interface for transparent transmission of gnss commands
* @return char * return commands
*/
char * transmitAT(const char* cmd);
/**
* @fn getGnssMessage
* @brief Get different types of gps data
* @param mode eGnssData_t type
* @return char*
*/
char * getGnssMessage(eGnssData_t mode);
/**
* @fn getAllGnss
* @brief Get GNSS data, call back and receive
* @return null
*/
void getAllGnss(void);
/**
* @fn setModuleBaud
* @brief Set the Module Baud rate
* @param baud eModuleBaud_t
*/
void setModuleBaud(eModuleBaud_t baud);
/**
* @fn setLoraBaud
* @brief Set the recevie Lora Baud rate
* @param baud eModuleBaud_t
*/
void setLoraBaud(eModuleBaud_t baud);
/**
* @fn getModuleBaud
* @brief Get the Module Baud rate
* @return uint32_t Baud rate of serial communication
*/
uint32_t getModuleBaud(void);
/**
* @fn getLoraBaud
* @brief Get the Lora Baud rate
* @return uint32_t Baud rate of serial communication
*/
uint32_t getLoraBaud(void);
/**
* @fn setCallback
* @brief Set callback function type
* @param call function name
* @return null
*/
void setCallback(void (*call)(char *, uint8_t));
6.1.4 Reading NMEA Data via I2C Protocol
Mobile Connection Diagram
- Remove the product from its packaging and connect the rover to the Arduino according to the wiring diagram provided above.
- Switch the selector switch on the rover to the I2C position.
- Download and install the RTK library.
- Open the Arduino IDE and upload the following code to the Arduino UNO.
- Place both the base station and rover in an open outdoor area. After powering on the base station, ensure its antenna remains stationary.
- Open the Serial Monitor in the Arduino IDE, set the baud rate to 115200, and observe the printed results.
/*!
* @file getAllGNSS.ino
* @brief read all gnss data
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author ZhixinLiu([email protected])
* @version V0.5.0
* @date 2024-04-23
* @url https://github.com/DFRobot/DFRobot_RTK_LoRa
*/
#include "DFRobot_RTK_LoRa.h"
void callback(char *data, uint8_t len)
{
for(uint8_t i = 0; i < len; i++){
Serial.print((char)data[i]);
}
}
#define I2C_COMMUNICATION //use I2C for communication, but use the serial port for communication if the line of codes were masked
#ifdef I2C_COMMUNICATION
DFRobot_RTK_LoRa_I2C rtk(&Wire ,DEVICE_ADDR);
#else
/* -----------------------------------------------------------------------------------------------------
* | Sensor | Connect line | Leonardo/Mega2560/M0 | UNO | ESP8266 | ESP32 | microbit | m0 |
* | VCC |=============>| VCC | VCC | VCC | VCC | X | vcc |
* | GND |=============>| GND | GND | GND | GND | X | gnd |
* | RX |=============>| Serial1 TX1 | 5 | 5/D6 | D2 | X | tx1 |
* | TX |=============>| Serial1 RX1 | 4 | 4/D7 | D3 | X | rx1 |
* ----------------------------------------------------------------------------------------------------*/
/* Baud rate cannot be changed */
#if defined(ARDUINO_AVR_UNO) || defined(ESP8266)
SoftwareSerial mySerial(4, 5);
DFRobot_RTK_LoRa_UART rtk(&mySerial, 57600);
#elif defined(ESP32)
DFRobot_RTK_LoRa_UART rtk(&Serial1, 115200 ,/*rx*/D2 ,/*tx*/D3);
#else
DFRobot_RTK_LoRa_UART rtk(&Serial1, 115200);
#endif
#endif
void setup()
{
Serial.begin(115200);
while(!rtk.begin()){
Serial.println("NO Deivces !");
delay(1000);
}
Serial.println("Device connected !");
rtk.setModule(eMoudleLora);
while(rtk.getModule() != eMoudleLora){
Serial.println("Module type is not lora! please wait!");
delay(1000);
}
rtk.setCallback(callback);
}
void loop()
{
rtk.getAllGnss();
}
For more advanced data analysis, please refer to the Standard Messages section (2.2) of the NMEA 0183 Protocol Standard.
6.1.5 Reading Data via UART
6.1.5.1 Modifying the Baud Rate
Note: If using an Arduino UNO, it is necessary to employ the configparam example routine within the library file. First, switch the module to I2C mode to configure the rover module's baud rate and modify it to 57600. Using boards with multiple hardware UART interfaces like the MEGA2560 or ESP32 does not require this baud rate modification step.
Mobile Connection Diagram
- Connect the module to Arduino as shown (or use Gravity I/O Expansion Board).
- Set the sensor's mode switch to I²C (for configuration only).
- Install the library.
- Upload the code below to Arduino UNO.
- Open Serial Monitor at 57600 baud to observe results.
- Note: Configuration mode only supports I²C.
**Parameter Configuration Example Code **
/*!
* @file configParam.ino
* @brief config moudle param
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author ZhixinLiu([email protected])
* @version V0.5.0
* @date 2024-04-24
* @url https://github.com/DFRobot/DFRobot_RTK_LoRa
*/
#include "DFRobot_RTK_LoRa.h"
// must use iic config parameter
DFRobot_RTK_LoRa_I2C rtk(&Wire ,DEVICE_ADDR);
void setup()
{
Serial.begin(115200);
while(!rtk.begin()){
Serial.println("NO Deivces !");
delay(1000);
}
Serial.println("Device connected !");
/**
* | Support Baud | UNO/ESP8266 | Leonardo/Mega2560 | ESP32 | M0 |
* | eBaud9600 | √ | √ | √ | √ |
* | eBaud14400 | √ | √ | √ | √ |
* | eBaud19200 | √ | √ | √ | √ |
* | eBaud38400 | √ | √ | √ | √ |
* | eBaud56000 | √ | √ | √ | √ |
* | eBaud57600 | √ | √ | √ | √ |
* | eBaud115200 | | √ | √ | √ |
* | eBaud256000 | | | √ | √ |
* | eBaud512000 | | | √ | √ |
* | eBaud921600 | | | √ | √ |
*/
rtk.setModuleBaud(eBaud115200);
Serial.print("module mode = ");
Serial.println(rtk.getModule());
Serial.print("moudle buad = ");
Serial.println(rtk.getModuleBaud());
}
void loop()
{
// Reserved interface, direct communication with gnss firmware, use with the original factory data manual
Serial.println(rtk.transmitAT("$PQTMVERNO*58\r\n"));
delay(2000);
}
Open Serial Monitor and press RESET to view current baud rate:
6.1.5.2 Obtaining Latitude, Longitude, and Positioning Status via UART Mode
Mobile Connection Diagram
UART Example Code
- Connect the rover to Arduino as shown
- Set the rover's mode switch to UART.
- Install the RTK Library (Installation guide).
- Upload the code to Arduino UNO.
- Place base station and rover outdoors; keep base station antenna stationary.
- Open Serial Monitor at 115200 baud to view data.
/*!
* @file getAllGNSS.ino
* @brief read all gnss data
* @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
* @license The MIT License (MIT)
* @author ZhixinLiu([email protected])
* @version V0.5.0
* @date 2024-04-23
* @url https://github.com/DFRobot/DFRobot_RTK_LoRa
*/
#include "DFRobot_RTK_LoRa.h"
void callback(char *data, uint8_t len)
{
for(uint8_t i = 0; i < len; i++){
Serial.print((char)data[i]);
}
}
// #define I2C_COMMUNICATION //use I2C for communication, but use the serial port for communication if the line of codes were masked
#ifdef I2C_COMMUNICATION
DFRobot_RTK_LoRa_I2C rtk(&Wire ,DEVICE_ADDR);
#else
/* -----------------------------------------------------------------------------------------------------
* | Sensor | Connect line | Leonardo/Mega2560/M0 | UNO | ESP8266 | ESP32 | microbit | m0 |
* | VCC |=============>| VCC | VCC | VCC | VCC | X | vcc |
* | GND |=============>| GND | GND | GND | GND | X | gnd |
* | RX |=============>| Serial1 TX1 | 5 | 5/D6 | D2 | X | tx1 |
* | TX |=============>| Serial1 RX1 | 4 | 4/D7 | D3 | X | rx1 |
* ----------------------------------------------------------------------------------------------------*/
/* Baud rate cannot be changed */
#if defined(ARDUINO_AVR_UNO) || defined(ESP8266)
SoftwareSerial mySerial(4, 5);
DFRobot_RTK_LoRa_UART rtk(&mySerial, 57600);
#elif defined(ESP32)
DFRobot_RTK_LoRa_UART rtk(&Serial1, 115200 ,/*rx*/D2 ,/*tx*/D3);
#else
DFRobot_RTK_LoRa_UART rtk(&Serial1, 115200);
#endif
#endif
void setup()
{
Serial.begin(115200);
while(!rtk.begin()){
Serial.println("NO Deivces !");
delay(1000);
}
Serial.println("Device connected !");
rtk.setModule(eMoudleLora);
while(rtk.getModule() != eMoudleLora){
Serial.println("Module type is not lora! please wait!");
delay(1000);
}
rtk.setCallback(callback);
}
void loop()
{
rtk.getAllGnss();
}
Result and Analysis
Name | meaning | remark |
---|---|---|
N | North | Latitude Hemisphere |
E | East | Longitude Hemisphere |
lat degree | Latitude | |
lon degree | Longitude | |
star | Number of satellites | Include GNSS,GPS,GLONASS,Galileo,BDS |
alt high | Meters above Mean Sea Level | |
sep | Geoid height above/below WGS84 ellipsoid (m) | Positive: the geoid is higher than the ellipsoid; Negative: The geoid is below the ellipsoid |
hdop | Horizontal Dilution of Precision (lower = better) | |
message mode | Positioning status | 0=Invalid, 1=GPS, 2=DGPS, 4=RTK Fixed, 5=RTK Float |
siteID | Reference station ID | Only RTK fixed interpretations or floating-point solutions are valid |
diftime | Age of RTK corrections (valid for RTK only) | Only RTK fixed interpretations or floating-point solutions are valid |
$GNGGA | NMEA Message | Please refer to the NMEA Data Resolution section |
$GNRMC | NMEA Message | Please refer to the NMEA Data Resolution section |
$GNGLL | NMEA Message | Please refer to the NMEA Data Resolution section |
$GNVTG | NMEA Message | Please refer to the NMEA Data Resolution section |
$GNGGA | NMEA Message | Please refer to the NMEA Data Resolution section |
6.2 Raspberry Pi User Guide
6.2.1 Hardware preparation
- Raspberry Pi 4B
- DFR0566 Raspberry Pi 4B/3B+ IO Expansion Board
- RTK High-Precision Positioning Kit
6.2.2 Software preparation
6.2.3 I²C Tutorial
Mobile Connection Diagram
Configure I²C speed as 400kbps in Raspberry Pi settings
Download the library file and run it, the default is I2C mode
Dial the hardware DIP switch to I2C mode, note: When the DIP switch fluctuates, please power off and restart the device after the dial is turned on to take effect.
cd ~
cd Desktop
mkdir df
cd df
git clone https://github.com/DFRobot/DFRobot_RTK_LoRa
cd DFRobot_RTK_LoRa/python/raspberrypi/examples
sudo python3 get_gnss.py
6.2.4 UART Tutorial
Mobile Connection Diagram
Switch to UART Mode
cd ~
cd Desktop
mkdir df
cd df
git clone https://github.com/DFRobot/DFRobot_RTK_LoRa
cd DFRobot_RTK_LoRa/python/raspberrypi/examples
sudo vi get_gnss.py ##Select the program to run and modify it to UART mode
Set hardware DIP switch to UART. Note: Reboot after switching.
sudo python3 get_gnss.py