The L86-M33 is a GNSS receiver module, developed by Quectel, that is only capable of receiving signals from the GPS and GLONASS constellation. Some GNSS receivers can receive signals from additional constellations, such as Galileo and BeiDou.

/*                 GNSS Receiver: Quectel L86-M33 (library)                   */
/*                          Filename: L86-M33.h                               */
/*                      Communication Protocol: UART                          */
/*                               Author: Michael                              */

void PMTK_CMD_FULL_COLD_START(void)                                             // Factory settings (NMEA 0183 standard command)
{
     
    while (U1STAbits.UTXBF == 1);                                               // Wait for transmit buffer to be empty of at least one character
    U1TXREG = '$';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'P';      
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'M';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'T';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'K';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '1';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '4';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '*';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '3';      
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '7';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 13;                                                               // Carriage return to return cursor to beginning of current line
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 10;                                                               // Cursor moves to next line
    
}

void PMTK_API_SET_NMEA_OUTPUT(void)                                             // Output RMC only (NMEA 0183 standard command)
{
    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '$';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'P';      
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'M';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'T';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 'K';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '3';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '1';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '4';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';      
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '1';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = ',';    
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '0';     
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '*';      
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '2';      
    while (U1STAbits.UTXBF == 1);
    U1TXREG = '9';
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 13;
    while (U1STAbits.UTXBF == 1);
    U1TXREG = 10;
    
}

The following list describes how each of the functions in the L86-M33.h library work:

  • PMTK_CMD_FULL_COLD_START, line #6, sets the L86-M33 to factory settings.
  • PMTK_API_SET_NMEA_OUTPUT, line #38, sets the L86-M33 to display basic navigation data.

The PMTK NMEA Packet Protocol is a command standard, developed by MediaTek, used to configure a GNSS receiver, as shown in Table 1.

FieldBytesDescriptionExample
$1Preamble$
Talker ID1PP
NMEA Data Type3MTKMTK
Data FieldPacket Type3000 to 999314
Packet Datavar.( , ) delimited,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
*1End of data field*
Checksum2Hexadecimal number calculated by XOR of all characters between “$” and “*”29
<CR><LF>2End of packet<CR><LF>
Table 1: PMTK Commands

An example of a PMTK command is shown, i.e., $PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29<CR><LF>, which instructs a GNSS receiver to produce sentences with a RMC interval (Recommended Minimum Specific GNSS Sentence). The checksum, 29, can be calculated using a checksum calculator and copy-pasting in “PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0”.

Quectel uses a Software Development Kit (SDK) in developing commands specific to the L86-M33 GNSS receiver, as shown in Table 2.

FieldBytesDescriptionExample
$1Preamble$
Talker ID2PQPQ
Packet Type1 – 10Instruct decoder how to decode packetBAUD
Data Fieldvar.( , ) delimited,W,9600
*1End of data field*
Checksum2Hexadecimal number calculated by XOR of all characters between “$” and “*”4B
<CR><LF>2End of packet<CR><LF>
Table 2: SDK Commands (L86-M33)

An example of a SDK command is shown, i.e., $PQBAUD,W,9600*4B, which instructs the L8-M33 GNSS receiver to produce sentences at a rate of 9600bps. Note that a “W”/”R” character in the Data Field represents a write/read command, respectively.