Interfacing Quectel L86 GPS+GLONASS GNSS Module with Arduino

Learn how to interface the Quectel L86 GPS+GLONASS multi-GNSS module with Arduino. The module is based on the MediaTek MT3333 GNSS chip.
Interfacing Quectel L86 GPS+GLONAS GNSS Module with Arduino Featured Landscape by CIRCUITSTATE Electronics

We are back with another GNSS module and this time, it’s the L86 from Quectel. If you’ve never heard of them, Quectel is a Chinese company that makes GNSS and telecommunication modules and they are very popular among product designers. In this tutorial, we will take a closer look at the L86 GNSS module that combines both GPS and GLONASS constellations for positioning. The compact module comes with a ceramic patch antenna and also supports external antenna. You will find here the pinouts and code connecting this module with your Arduino boards.

If you are completely new to GPS/GNSS modules, you can check out our NEO-6M GPS tutorial. Even though written for another GPS module, it explains everything basic you need to know to start using GPS or other GNSS modules in your projects.

What is GPS/GNSS and How to Interface uBlox NEO-6M GPS Module with Arduino CIRCUITSTATE Electronics Feature Image

What is GPS/GNSS & How to Interface u-blox NEO-6M GPS Module with Arduino

Learn how GPS and other GNSS work, and interface the u-blox NEO-6M GY-NEO6MV2 module with Arduino boards using CSE_GNSS library and sample codes.

Quectel L86

Quectel L86 GPS+GLONASS GNSS Module on the EVE-GNSS Breakout Board CIRCUITSTATE Electronics
Quectel L86-M33 GNSS module on the Evelta 7Semi EVE-GNSS breakout board

The Quectel L86 (aka L86-M33) is a compact multi-GNSS module based on the MediaTek MT3333 GNSS chipset. It integrates a ceramic Patch-on-Top (POT) antenna on the module and can receive positioning signals from GPS, GLONASS, Galileo and QZSS constellations. It has a -149 dBm acquisition sensitivity and a -167 dBm tracking sensitivity. 99 acquisition channels and 33 tracking channels allow the module to acquire the position lock faster and continue tracking even in challenging situations like indoors. The EASY™ (Embedded Assist System) is a proprietary technology that allows the L86 to store the ephemeris data of up to 3 days in the RAM and use it to calculate and predict the satellite positions faster. With AlwaysLocate™ technology, L86 can adaptively adjust the on/off time to achieve balance between positioning accuracy and power consumption according to the environmental and motion conditions. The L86 is size and pin compatible with the older L80 GPS-only module. Now let’s take a look at the features and specifications as advertised by the manufacturer.

Features

  • Multi-GNSS engine for GPS, GLONASS, Galileo and QZSS.
  • Embedded patch antenna: 18.4 × 18.4 × 4.0 mm.
  • Extremely compact footprint: 16.0 × 16.0 × 6.45 mm.
  • Automatic antenna switching function.
  • Support short circuit protection and antenna detection.
  • Built-in LNA for better sensitivity.
  • EASY™, an advanced AGPS technology without external memory.
  • Ultra low power consumption in tracking mode, 26 mA.
  • AlwaysLocate™, an intelligent controller of periodic mode.
  • LOCUS, an embedded logger function without the need of host and external flash.
  • High sensitivity: -167 dBm @ Tracking, -149 dBm @ Acquisition.
  • 99 acquisition channels, 33 tracking channels.
  • Balloon mode, for high altitude up to 80 Km.
  • Support DGPS, SBAS (WAAS/EGNOS/MSAS/GAGAN).
  • Great anti-jamming performance due to multi-tone active interference canceller.
  • PPS VS. NMEA can be used for time service.
  • Support SDK command developed by Quectel.

Specifications

  • Chipset: MediaTek MT3333
  • Constellations: GPS, GLONASS, Galileo, and QZSS
  • Frequency: GPS L1 (1575.42MHz), GLONASS L1 (1601.71MHz)
  • SBAS: WAAS, EGNOS, MSAS, GAGAN
  • Acquisition Channels: 99
  • Tracking Channels: 33
  • Sensitivity:
    • Acquisition: -149 dBm
    • Tracking: -167 dBm
    • Reacquisition: -161 dBm
  • Accuracy
    • Horizontal Position Accuracy: < 2.5 m CEP autonomous
    • Velocity Accuracy: <0.1 m/s without aid
    • Acceleration Accuracy: <0.1 m/s2
    • Timing Accuracy: 10 ns at 1 PPS out
  • Acquisition Time
    • Reacquisition Time: < 1 s
    • TTFF @ -130 dBm with EASY™:
      • Cold Start: < 15 s
      • Warm Start: < 5 s
      • Hot Start: < 1 s
    • TTFF @ -130 dBm without EASY™:
      • Cold Start: < 35 s
      • Warm Start: < 30 s
      • Hot Start: < 1 s
  • Data and Update Rate
    • Support Rate: UART 4800~115200 bps, Default 9600 bps
    • IO Voltage: 2.7V~2.9V
    • Data Protocol: NMEA 0183, PMTK
    • Output frequency: 1~10 Hz, Default 1 Hz
  • Operational Limits
    • Altitude: 18,000 m Max
    • Velocity: 515 m/s Max
    • Acceleration: Less than 4 G
  • Power Consumption
    • Supply Voltage: 3~4.3V
    • Acquisition: 30 mA @ 3.3V (GPS + GLONASS)
    • Tracking: 26 mA @ 3.3V (GPS + GLONASS)
  • Temperature Range: -40 °C ~ +85°C
  • Dimensions: 18.4 x 18.4 x 6.45 mm
  • Weight: 7.6 g

Block Diagram

Quectel L86 M33 GPS GLONASS GNSS Module Block Diagram by CIRCUITSTATE Electronics
Quectel L86 GNSS module internal block diagram
Quectel L86 M33 GPS GLONASS GNSS Module Mediatek MT3333 Block Diagram CIRCUITSTATE Electronics
MediaTek MT3333 GNSS chipset internal block diagram

Pinout

The L86 is available as an LCC (Leaded Chip Carrier) package with 12 pins. In addition to the POT antenna, the L86 can also switch the antennas to either the POT or an external antenna. The pinout diagram is given below.

Quectel L86 M33 GPS GLONASS GNSS Module Pinout by CIRCUITSTATE Electronics
Quectel L86 pinout
Pin #Pin NameDescription
1RXD1Data receive
2TXD1Data transmit
3GNDSupply ground
4VCCPositive supply
5V_BCKPBackup power supply for the RTC. Can connect to VCC or a battery.
61PPSOne pulse per second output
7FORCE_ONModule wake up pin
8AADET_NActive antenna detection
9NCNot connected
10RESETSystem reset. Active low.
11EX_ANTExternal active antenna input
12GNDSupply ground

Dimensions

Quectel L86 M33 GPS GLONASS GNSS Module Dimensions by CIRCUITSTATE Electronics
Quectel L86 mechanical drawing and dimensions

7Semi L86-M33 EVE-GNSS

The L86-M33 EVE-GNSS is a breakout module for the L86, from 7Semi, which is a brand of the popular Indian ecommerce website Evelta based in Mumbai. The L86-M33 makes it easy to interface the L86 module with any microcontroller of your choice. The L86-M33 is available for INR 925 while the L86 module is available for INR 670 from Evelta at the time of writing.

Features

  • 3.3V power supply.
  • CR1220 coin cell holder for RTC backup.
  • U.FL connector for external antenna.
  • Indicator LEDs
    • Power – Green
    • Position – Blue
    • Antenna – Red
  • 40 x 28 mm dimensions
Evelta 7Semi L86-M33 Quectel L86 GPS+GLONASS GNSS Breakout Module UFL Connector by CIRCUITSTATE Electronics
U.FL (UMCC) coaxial connector on the L86 EVE-GNSS board for connecting external active antenna. The antenna is selected automatically by the L86.

Schematic

Evelta has not released the schematic of the EVE-GNSS module, but it should be based on the design guidelines from Quectel as shown below.

Pinout

Evelta 7Semi L86-M33 Quectel L86 GPS+GLONASS GNSS Breakout Module Pinout CIRCUITSTATE Electronics
L86 EVE-GNSS board pinout and LEDs.

The above image shows the pins available on the EVE-GNSS board. Following is the pin names and their description.

Pin NameDescription
RXData receive
TXData transmit
GNDSupply ground
3.3VPositive supply
V_BACKBackup power supply for the RTC. It is connected to the RTC battery.
F_ONModule wake up pin
RESETSystem reset. Active low.
L86 EVE-GNSS board pinout

There are three LEDs on the board. ANT LED (Red) is connected to the AADET_N pin of the L86. When the external antenna is connected and selected, the ANT LED will turn off. With the internal POT antenna, the LED will remain on. The GPS LED (Blue) is connected to the 1PPS of the L86 and indicates the position lock status. PWR (Green) indicates the power supply input.

Wiring

We are going to use a FireBeetle-ESP32-E board for interfacing the L86 module and read data from it. The FireBeetle-ESP32-E is a versatile development board from DFRobot, and comes with a USB-C connector instead of the old USB-Micro. You can use any other Arduino boards as well for running the example code provided.

Evelta 7Semi L86-M33 Quectel L86 GPS+GLONASS GNSS Breakout Module Wiring with ESP32 CIRCUITSTATE Electronics
Wiring the L86 EVE-GNSS module with ESP32

We just need to connect the 3.3V power to the L86 module and connect the RX and TX pins to any of the UART pins of the ESP32 board. Note that the L86 EVE-GNSS module does not have any voltage regulators onboard and therefore can not accept any voltages higher than 3.3V. For example, supplying 5V will likely damage the module. Following table shows the wiring we used.

GNSS BoardESP32FireBeetle-ESP32E
3.3V3.3V3.3V
GNDGNDGND
RXGPIO16D11
TXGPIO17D10
Wiring list

If this is the first time you are using an ESP32 board, we have a great tutorial for beginners.

Gettgin Started with Espressif ESP32 WiFi BLE SoC Using DOIT-ESP32-DevKit-V1 CIRCUITSTATE Electronics Featured Image

Getting Started with Espressif ESP32 Wi-Fi & Bluetooth SoC using DOIT-ESP32-DevKit-V1 Development Board

Learn how to use Espressif ESP32 SoC for Wi-Fi and Bluetooth development using DOIT ESP32 DevKit V1 development board. Use Arduino, ESP-IDF, PlatformIO and VS Code for software development.

CSE_GNSS Library

68747470733a2f2f736f6369616c6966792e6769742e63692f4349524355495453544154452f4353455f474e53532f696d6167653f6465736372697074696f6e3d3126666f6e743d4b6f486f26666f726b733d31266973737565733d31266c6f676f3d68747470732533412532462532467777772e6369726375697473746174652e636f6d25324677702d636f6e74656e7425324675706c6f6164732532463230323425324630352532464349524355495453544154452d522d456d626c656d2d32303035323032342d322e737667266e616d653d31267061747465726e3d43697263756974253230426f6172642670756c6c733d31267374617267617a6572733d31267468656d653d4175746f

The CSE_GNSS is an open-source Arduino library from CIRCUITSTATE Electronics, and can be used to read any GPS/GNSS module with the standard NMEA output and decode the messages. You can define custom NMEA data sentences and extract the positional parameters effortlessly. There are two examples available in the library as of now.

  1. View_GNSS_Data.ino – Reads the raw data from the GNSS module and prints it to the serial monitor. This sketch is useful for verifying the wiring and the output of the GNSS module you have.

  2. Print_GPRMC.ino – As the name suggests, this reads the $GPRMC sentence from the GNSS module, extract the data and print them to the serial monitor.

We will modify these Arduino examples slightly for our Quectel L86 GNSS module.

Arduino Code

The following is an Arduino code for reading raw NMEA data and printing them to the serial monitor. It is the View_GNSS_Data.ino example modified for ESP32.


//======================================================================================//
/**
 * @file View_GNSS_Data.ino
 * @brief Reads raw data from the GNSS module and prints it on the serial monitor.
 * @date +05:30 12:37:39 AM 03-08-2024, Saturday
 * @version 1.0.1
 * @author Vishnu Mohanan (@vishnumaiea)
 * @par GitHub Repository: https://github.com/CIRCUITSTATE/CSE_GNSS
 * @par MIT License
 * 
 */
//======================================================================================//

#include <Arduino.h>
#include <CSE_GNSS.h>

//======================================================================================//

#define   PORT_GPS_SERIAL         Serial1   // GPS serial port
#define   PORT_DEBUG_SERIAL       Serial    // Debug serial port

// For ESP32
#define   PIN_GPS_SERIAL_TX       16
#define   PIN_GPS_SERIAL_RX       17

#define   VAL_GPS_BAUDRATE        9600
#define   VAL_DEBUG_BAUDRATE      115200

//======================================================================================//
// Forward declarations

void setup();
void loop();

//======================================================================================//

// Set the serial ports and the baudrate for the GNSS module.
// Both ports have to be manually initialized through begin() call.
CSE_GNSS GNSS_Module (&PORT_GPS_SERIAL, &PORT_DEBUG_SERIAL);

//======================================================================================//
/**
 * @brief Setup the serial ports and pins.
 * 
 */
void setup() {
  PORT_DEBUG_SERIAL.begin (VAL_DEBUG_BAUDRATE);

  // For ESP32 boards
  PORT_GPS_SERIAL.begin (VAL_GPS_BAUDRATE, SERIAL_8N1, PIN_GPS_SERIAL_RX, PIN_GPS_SERIAL_TX);
  
  GNSS_Module.begin();  // Initialize the GNSS module.

  PORT_DEBUG_SERIAL.println();
  PORT_DEBUG_SERIAL.println ("--- CSE_GNSS [View_GNSS_Data] ---");
  delay (1000);
}

//======================================================================================//
/**
 * @brief Runs indefinitely.
 * 
 */
void loop() {
  GNSS_Module.read (1024); // Read multiple NMEA data lines from the GNSS module

  // Print the data
  for (int i = 0; i < GNSS_Module.gnssDataBufferLength; i++) {
    PORT_DEBUG_SERIAL.print (GNSS_Module.gnssDataBuffer [i]);
  }

  PORT_DEBUG_SERIAL.println();

  delay (500);
}

//======================================================================================//
C++

Since the ESP32 has multiple hardware serial ports, we are using Serial1 to talk to the GNSS module. The default Serial port will be used for debugging messages. In the loop() function, we will just read 1024 bytes and print them to the serial monitor. Now compile and upload the code to your ESP32 board. After opening the serial monitor, you will start to see NMEA data coming from the GNSS module.

$GPRMC,111023.623,V,,,,,0.00,0.00,020723,,,N,V*34
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,111023.623,,,,,0,0,,,M,,M,,*4F
$GPGSA,A,1,,,,,,,,,,,,,,,,1*03
$GPGSA,A,1,,,,,,,,,,,,,,,,2*00
$GPGSV,4,1,14,18,61,085,,32,60,279,,28,31,187,,23,29,026,,0*65
$GPGSV,4,2,14,10,29,343,,27,28,295,,195,26,129,,24,18,052,,0*52
$GPGSV,4,3,14,29,14,162,,25,08,139,,26,05,221,,31,04,205,,0*69
$GPGSV,4,4,14,08,01,314,,194,01,106,,0*55
$GLGSV,2,1,08,83,57,148,,84,53,342,,69,29,353,18,70,28,280,,1*77
$GLGSV,2,2,08,82,14,154,,79,13,105,,80,12,155,,71,01,240,,1*7C
$GPGLL,,,,,111023.623,V,N*7D
$GPTXT,01,01,02,ANTSTATUS=OPEN*2B
$GPRMC,111024.623,V,,,,,0.08,0.00,020723,,,N,V*3B
$GPVTG,0.00,T,,M,0.08,N,0.15,K,N*3E
$GPGGA,111024.623,,,,,0,0,,,M,,M,,*48
$GPGSA,A,1,,,,,,,,,,,,,,,,1*03
$GPGSA,A,1,,,,,,,,,,,,,,,,2*00
$GPGSV,4,1,14,18,61,085,,32,60,279,,28,31,187,,23,29,026,,0*65
$GPGSV,4,2,14,10,29,343,,27,28,295,,195,26,129,,24,18,052,,0*52
$GPGSV,4,3,14,29,14,162,,25,08,139,,26,05,221,,31,04,205,,0*69
$GPGSV,4,4,14,08,01,314,,194,01,106,,0*55
$GLGSV,2,1,08,83,57,148,,84,53,342,,69,29,353,18,70,28,280,,1*77
$GLGSV,2,2,08,82,14,154,,79,13,105,,80,12,155,,71,01,240,,1*7C
$GPGLL,,,,,111024.623,V,N*7A
$GPTXT,01,01,02,ANTSTATUS=OPEN*2B
$GPRMC,111025.623,V,,,,,0.64,194.86,020723,,,N,V*32
$GPVTG,194.86,T,,M,0.64,N,1.18,K,N*3A
$GPGGA,111025.623,,,,,0,0,,,M,,M,,*49
$GPGSA,A,1,,,,,,,,,,,,,,,,1*03
$GPGSA,A,1,,,,,,,,,,,,,,,,2*00
Serial Monitor

Now we can try reading and decoding the $GPRMC data. GP indicates GPS and used when the positioning data comes only from the GPS satellites. Upload the following code and open the serial monitor. This is a version of the Print_GPRMC.ino example modified for ESP32.


//======================================================================================//
/**
 * @file Print_GPRMC.ino
 * @brief Reads the NMEA output from the GNSS module and prints it on the serial monitor.
 * @date +05:30 12:28:39 AM 03-08-2024, Saturday
 * @version 1.0.1
 * @author Vishnu Mohanan (@vishnumaiea)
 * @par GitHub Repository: https://github.com/CIRCUITSTATE/CSE_GNSS
 * @par MIT License
 * 
 */
//======================================================================================//

#include <Arduino.h>
#include <CSE_GNSS.h>

//======================================================================================//

#define   PORT_GPS_SERIAL         Serial1   // GPS serial port
#define   PORT_DEBUG_SERIAL       Serial    // Debug serial port

// For ESP32
#define   PIN_GPS_SERIAL_TX       16
#define   PIN_GPS_SERIAL_RX       17

#define   VAL_GPS_BAUDRATE        9600
#define   VAL_DEBUG_BAUDRATE      115200

//======================================================================================//
// Forward declarations

void setup();
void loop();

//======================================================================================//

// Set the serial ports and the baudrate for the GNSS module.
// Both ports have to be manually initialized through begin() call.
CSE_GNSS GNSS_Module (&PORT_GPS_SERIAL, &PORT_DEBUG_SERIAL);

// Following is how we define the format of the GPRMC (with Second mode indicator)
String GPRMC_Sample = "$GPRMC,120556.096,V,,,,,0.00,204.84,020723,,,N,V*33"; // A sample reference line
String GPRMC_Data_Names [] = {"Header", "UTC", "Status", "Latitude", "Latitude Direction", "Longitude", "Longitude Direction", "Speed", "Course", "Date", "Mag Variation", "Mag Variation Direction", "Mode", "Second Mode", "Checksum"};
String GPRMC_Description = "Recommended Minimum Specific GNSS Data"; // A human readable description of the data.

// Format: Name, Description, Data Count, Data Names, Sample
NMEA_Data NMEA_GPRMC ("GPRMC", GPRMC_Description, 15, GPRMC_Data_Names, GPRMC_Sample); // An object to save and handle the data.

//======================================================================================//
/**
 * @brief Setup the serial ports and pins.
 * 
 */
void setup() {
  PORT_DEBUG_SERIAL.begin (VAL_DEBUG_BAUDRATE);

  // For ESP32 boards
  PORT_GPS_SERIAL.begin (VAL_GPS_BAUDRATE, SERIAL_8N1, PIN_GPS_SERIAL_RX, PIN_GPS_SERIAL_TX);
  
  GNSS_Module.begin();  // Initialize the GNSS module.
  GNSS_Module.addData (&NMEA_GPRMC); // Add the data object to the GNSS module.

  PORT_DEBUG_SERIAL.println();
  PORT_DEBUG_SERIAL.println ("--- CSE_GNSS [Print_GPRMC] ---");
  delay (1000);
}

//======================================================================================//
/**
 * @brief Runs indefinitely.
 * 
 */
void loop() {
  GNSS_Module.read (1024);
  GNSS_Module.extractNMEA();
  String GNSS_Data = GNSS_Module.getNmeaDataString();

  GNSS_Module.getDataRef ("GPRMC").find (GNSS_Data); // Find the GPRMC sentences in the read data
  GNSS_Module.getDataRef ("GPRMC").print(); // Print the GNRMC sentences in preformatted format
  delay (10);
}

//======================================================================================//
C++

Unlike the NEO-6M GY-NEO6MV2 module we have tested before, the GPRMC sentence of L86 here has 15 fields instead of 14, by default. This is because of the presence of the extra Second Mode Indicator. Because the CSE_GNSS library allows us to define the message formats and fields, we can easily change this in the code as seen in the lines below.

// Following is how we define the format of the GPRMC (with Second mode indicator)
String GPRMC_Sample = "$GPRMC,120556.096,V,,,,,0.00,204.84,020723,,,N,V*33"; // A sample reference line
String GPRMC_Data_Names [] = {"Header", "UTC", "Status", "Latitude", "Latitude Direction", "Longitude", "Longitude Direction", "Speed", "Course", "Date", "Mag Variation", "Mag Variation Direction", "Mode", "Second Mode", "Checksum"};
String GPRMC_Description = "Recommended Minimum Specific GNSS Data"; // A human readable description of the data.

// Format: Name, Description, Data Count, Data Names, Sample
NMEA_Data NMEA_GPRMC ("GPRMC", GPRMC_Description, 15, GPRMC_Data_Names, GPRMC_Sample); // An object to save and handle the data.
C++

The remaining logic of the code is very simple. In the loop() function, we will read a fixed number of bytes from the GNSS module. Here, we are reading 1024 bytes. You can change this to any other number depending on the RAM available or the number of data lines you want to read at a time. The read data is stored into an internal buffer. The extractNMEA() function then extracts the NMEA data from the buffer. This process removes any invalid characters such as leading or trailing whitespaces. Next, we can convert the data in the buffer to an Arduino String using getDataString() function. In the next two lines, we will search the line for the GPRMC header, decode the data and save them to the NMEA_GPRMC object.

After flashing the code, you can open the serial monitor and get a similar output like below. You have to be an open space with clear sky. Make sure to direct the patch antenna to the open sky. It can take some time to find multiple satellites and synchronize the time on the module. For us, it took around 3 minutes to get a lock initially. After the initial lock, you will get the position faster from then onward.

NMEA_Data check(): $GPGLL,,,,,140056.083,V,N*77
NMEA_Data check(): Invalid header.
NMEA_Data check(): $GPTXT,01,01,02,ANTSTATUS=OPEN*2B
NMEA_Data check(): Invalid header.
NMEA_Data check(): $GPRMC,140057.083,V,,,,,0.00,204.84,020723,,,N,V*35
NMEA_Data check(): Valid GPRMC sentence.
NMEA_Data set(): $GPRMC,140057.083,V,,,,,0.00,204.84,020723,,,N,V*35
NMEA_Data check(): $GPRMC,140057.083,V,,,,,0.00,204.84,020723,,,N,V*35
NMEA_Data check(): Valid GPRMC sentence.
NMEA_Data parse(): $GPRMC,140057.083,V,,,,,0.00,204.84,020723,,,N,V*35
NMEA_Data print(): 
GPRMC: $GPRMC,140057.083,V,,,,,0.00,204.84,020723,,,N,V*35
  Header: $GPRMC
  UTC: 140057.083
  Status: V
  Latitude: 
  Latitude Direction: 
  Longitude: 
  Longitude Direction: 
  Speed: 0.00
  Course: 204.84
  Date: 020723
  Mag Variation: 
  Mag Variation Direction: 
  Mode: N
  Second Mode: V
  Checksum: 35
Serial Monitor

That’s everything for this tutorial. Please let us know your feedback and suggestions to improve this article in the comments. Happy positioning 🛰️

  1. Quectel L86 GNSS – Product Page
  2. Buy Quectel L86 – Evelta
  3. Buy 7Semi L86-M33 EVE-GNSS Breakout Module – Evelta
  4. CSE_GNSS Arduino Library by CIRCUITSTATE – GitHub
  5. What is GPS/GNSS & How to Interface u-blox NEO-6M GPS Module with Arduino – CIRCUITSTATE Electronics

Share to your friends
Vishnu Mohanan

Vishnu Mohanan

Founder and CEO at CIRCUITSTATE Electronics

Articles: 97

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.