GNSS-RTK High Precision Positioning Kit

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

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

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

Full NMEA 0183 Reference

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

6.1.2 Software preparation

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

6.2.2 Software preparation

6.2.3 I²C Tutorial

Mobile Connection Diagram

Configure I²C speed as 400kbps in Raspberry Pi settings

Configure I²C Speed

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

7. Reference Materials

Base Station Schematic

Mobile Schematic

Quectel_L89_R2.0&LC29H&LC79H_AGNSS_Application_Note_V1.0

Quectel_LC29H_GNSS_Specification_V1.1