Overview
In this post, we will make an ESP32 GPS Tracker using Quectel L86 GPS Module & OLED Display. The L86 GPS Module from Quectel is the tiny, low cost and low-power-consuming GPS Module available in the market. It has an integrated patch antenna and new generation MediaTek MT3333 GNSS chipset which has exceptional performance both in acquisition and tracking, and space-saving design.
It acquires and tracks satellites in the shortest time even at the indoor signal level. Compared to NEO-6M GPS Module and RYS8830 GPS/GNSS Receiver, this module has the best performance It is designed to be compatible with Quectel’s GPS L80 Module to provide a flexible and scalable platform for migrating from GPS to GNSS.
In this tutorial, we will interface Quectel L86 GPS Module with ESP32 and make our own GPS Tracker. The L86 GPS Module can give the value of Latitude, Longitude, Speed, Altitude, Date, and Time once it is synchronized with the satellite. We will display these parameters on a 0.96″ OLED Screen. Then using the ESP32 WiFi chip we will send the GPS coordinates to ESP32 Webserver.
You may refer to some previous GPS Tracker-based projects:
- Real Time GPS Tracker using ESP8266 & Blynk with Maps
- GPS Tracker using A9G GPRS/GPS Module & Arduino
- GPS+GSM Based Vehicle Tracking System using Arduino
- LoRa Based Low Power GPS Tracker with Arduino & ESP8266
Bill of Materials
You need to purchase the following components for building this project.
| S.N. | Components | Quantity | Purchase Links |
|---|---|---|---|
| 1 | ESP32 WiFi Module | 1 | Amazon | AliExpress |
| 2 | GPS Module Neo-6M/L86 | 1 | Amazon | AliExpress |
| 3 | 0.96" I2C OLED Module | 1 | Amazon | AliExpress |
| 4 | Jumper Wires | 10 | Amazon | AliExpress |
| 5 | Breadboard | 1 | Amazon | AliExpress |
Quectel L86 GPS Module
The L86 is an ideal solution for wearable fitness devices due to its ultra-compact design and low power demands. L86 GNSS module with an embedded patch antenna and LNA brings the high performance of the MTK positioning engine to industrial applications. It is able to achieve the industry’s highest level of sensitivity, accuracy, and TTFF with the lowest power consumption in a small-footprint leadless package. The embedded flash memory provides the capacity for users to store some useful navigation data and allows for future updates.
The L86 has a patch antenna on top measuring 18.4±0.15 ×18.4±0.15 ×6.45±0.1mm , with 99 acquisition channels and 33 tracking channels. It acquires and tracks satellites in the shortest time even at the indoor signal level. The module operates at 3V~4.3V with a typical power consumption of 26mA and in Standby mode power consumption is around 1.0mA.
Key Features
1. Power Consumption: Acquisition 26mA, Tracking 22mA, Standby 1.0mA, Backup: 7uA
2. Receiver Type: GPS L1 1575.42MHz C/A Code, GLONASS L1 1598.0625~1605.375MHz C/A Code, 99 search channels, 33 simultaneous tracking channels
3. Sensitivity: Acquisition -148dBm, Re-acquisition -160dBm, Tracking -165dBm
4. Power Supply: 3V~4.3V
5. Update Rate: Up to 10Hz, 1Hz by default
6. Accuracy of 1PPS Signal: Typical accuracy: <15ns, Time pulse width 100ms
7. Acceleration Accuracy: Without aid 0.1m/s2
8. Dynamic Performance: Maximum altitude 18000m, Maximum velocity 515m/s, Acceleration 4G
9. UART Port: TXD1 & RXD1 Supports baud rate from 4800bps to 115200bps, 9600bps by default
10. Velocity Accuracy: 0.1m/s
11. Working Temperature Range: -40~85 C
12. Embedded patch antenna
13. Built-in LNA for better sensitivity
L86 Pinout
The Quectel L86 GPS Module has 12 pins as shown in the image above. The function of each pin is defined below.
| S.N. | Pin Name | Function |
|---|---|---|
| 1 | RXD1 | UART Receiver |
| 2 | TXD1 | UART Transmitter |
| 3 | GND | Ground Logic |
| 4 | VCC | 2.8V~4.3V Supply, Typically 3.3V |
| 5 | V_BCKP | Backup power/Supply power for RTC |
| 6 | 1PPS | One pulse per second, Synchronized at the rising edge, the pulse width is 100ms |
| 7 | FORCE_ON | Logic high will force module to be waked up from backup mode |
| 8 | AADET_N | Active antenna detection |
| 9 | NC | Not Connected |
| 10 | RESET | System reset |
| 11 | EX_ANT | External active antenna RF input |
| 12 | GND | Ground Logic |
To learn more about this module you can refer to L86 Datasheet
Soldering Header Pins to L86 Module
The L86 is a tiny SMD-type Module that doesn’t have any male/female header pins for testing. So you can use the male header pin with 2.54 spacing and solder them on the L86 PCB from the bottom.
Interfacing Quectel L86 GPS Module with ESP32 & OLED Display
Now let us interface L86 GPS Module with ESP32. You can connect the L80 GPS Module with ESP32 WiFi Module o as per the circuit diagram below.
The connection is fairly simple. Connect the VCC/GND for the power supply. Similarly, connect the VCC backup (V_BCKP) with VCC or to an external battery. The GPS Module won’t work if this pin is not powered. Connect the RX/TX of L86 to the TX2/RX2 of the ESP32. This is for Serial Communication using UART2 of ESP32.
Connect the OLED Display SDA SCL Pin to ESP32 D21 & D22 Pin. You can power the OLED Display using the 3.3V & GND pin of ESP32. Hence the hardware setup & connections for ESP32 GPS Tracker is ready.
Project PCB Gerber File & PCB Ordering Online
If you don’t want to assemble the circuit on a breadboard and you want PCB for the project, then here is the PCB for you. I used EasyEDA to design the PCB. The PCB Board for ESP32 GPS Tracker looks something like below.
The Gerber File for the PCB is given below. You can simply download the Gerber File and order the PCB from ALLPCB at 1$ only.
You can use this Gerber file to order high quality PCB for this project. To do that visit the ALLPCB official website by clicking here: https://www.allpcb.com/.
You can now upload the Gerber File by choosing the Quote Now option. From these options, you can choose the Material Type, Dimensions, Quantity, Thickness, Solder Mask Color and other required parameters.
After filling all details, select your country and shipping method. Finally you can place the order.
You can assemble the components on the PCB Board.
Source Code/Program & Testing
The best part about the L86 GPS/GNSS Module is, it supports Tiny GPS++ Library. Download the library and add it to the library folder. You also need SSD1306 OLED Library for this project.
Now copy the following code and upload it to the ESP32 Board.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
#include <Wire.h> #include <Adafruit_SSD1306.h> #include <TinyGPS++.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels //On ESP32: GPIO-21(SDA), GPIO-22(SCL) #define OLED_RESET -1 //Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C //See datasheet for Address Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define RXD2 16 #define TXD2 17 HardwareSerial neogps(1); TinyGPSPlus gps; void setup() { Serial.begin(115200); //Begin serial communication Arduino IDE (Serial Monitor) //Begin serial communication Neo6mGPS neogps.begin(9600, SERIAL_8N1, RXD2, TXD2); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } display.clearDisplay(); display.display(); delay(2000); } void loop() { boolean newData = false; for (unsigned long start = millis(); millis() - start < 1000;) { while (neogps.available()) { if (gps.encode(neogps.read())) { newData = true; } } } //If newData is true if(newData == true) { newData = false; Serial.println(gps.satellites.value()); print_speed(); } else { display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.setTextSize(3); display.print("No Data"); display.display(); } } void print_speed() { display.clearDisplay(); display.setTextColor(SSD1306_WHITE); if (gps.location.isValid() == 1) { //String gps_speed = String(gps.speed.kmph()); display.setTextSize(1); display.setCursor(25, 5); display.print("Lat: "); display.setCursor(50, 5); display.print(gps.location.lat(),6); display.setCursor(25, 20); display.print("Lng: "); display.setCursor(50, 20); display.print(gps.location.lng(),6); display.setCursor(25, 35); display.print("Speed: "); display.setCursor(65, 35); display.print(gps.speed.kmph()); display.setTextSize(1); display.setCursor(0, 50); display.print("SAT:"); display.setCursor(25, 50); display.print(gps.satellites.value()); display.setTextSize(1); display.setCursor(70, 50); display.print("ALT:"); display.setCursor(95, 50); display.print(gps.altitude.meters(), 0); display.display(); } else { display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.setTextSize(3); display.print("No Data"); display.display(); } } |
After uploading the code, the OLED Display will display no data message as GPS Module is not synchronized with the Satellite. For the first time, it might take 2-3 minutes to retrieve data. Next time onwards it retrieves the location very quickly.
The OLED Display will show the Latitude, Longitude, Altitude, Speed & total satellite. You can take the device outside and power it using a power bank or your Car USB and trace the GPS Location.
ESP32 GPS Tracker on Webserver
Instead of displaying the value on OLED Display, we can connect the ESP32 WiFi Module to WiFi Network. Using the static webpage, we can create a Webserver where we can display the GPS Data.
The complete code for ESP32 GPS Tracker Webserver is given below. In this code, change the WiFi SSID & Password.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
#include <Wire.h> #include <Adafruit_SSD1306.h> #include <TinyGPS++.h> #include <WiFi.h> #include<WiFiServer.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels const char* ssid = "BELL685"; //ssid of your wifi const char* password = "644642755D2F"; //password of your wifi WiFiServer server(80); //On ESP32: GPIO-21(SDA), GPIO-22(SCL) #define OLED_RESET -1 //Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C //See datasheet for Address Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); #define RXD2 16 #define TXD2 17 HardwareSerial neogps(1); TinyGPSPlus gps; void setup() { Serial.begin(115200); //Begin serial communication Arduino IDE (Serial Monitor) //Begin serial communication Neo6mGPS neogps.begin(9600, SERIAL_8N1, RXD2, TXD2); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.clearDisplay(); display.display(); delay(2000); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); //connecting to wifi while (WiFi.status() != WL_CONNECTED)// while wifi not connected { delay(500); Serial.print("."); //print "...." } Serial.println(""); Serial.println("WiFi connected"); server.begin(); Serial.println("Server started"); Serial.println(WiFi.localIP()); // Print the IP address display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.setTextSize(2); display.print("IP Address"); display.setCursor(20, 30); display.setTextSize(1); display.print(WiFi.localIP()); display.display(); delay(5000); } void loop() { boolean newData = false; for (unsigned long start = millis(); millis() - start < 1000;) { while (neogps.available()) { if (gps.encode(neogps.read())) { newData = true; } } } //If newData is true if (newData == true) { newData = false; Serial.println(gps.satellites.value()); print_speed(); } else { display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.setTextSize(3); display.print("No Data"); display.display(); } WiFiClient client = server.available(); // Check if a client has connected if (!client) { return; } // Prepare the response String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n <!DOCTYPE html> <html> <head> <title>GPS DATA</title> <style>"; s += "a:link {background-color: RED;text-decoration: none;}"; s += "table, th, td </style> </head> <body style=background-color:WHITE>"; s += "<h1 style=color:RED;font-size:400%"; s += " ALIGN=CENTER>GPS RECEIVER DATA </h1>" ; s += "<p ALIGN=CENTER style=color:BLUE;font-size:250% >"; s += "<b>Location Details</b></p> <table ALIGN=CENTER style="; s += "font-size:250%;"; s += "> <tr> <th>Latitude :- </th>"; s += "<td ALIGN=CENTER >"; s += (gps.location.lat()); s += "</td> </tr> <tr> <th>Longitude :-</th> <td ALIGN=CENTER >"; s += (gps.location.lng()); s += "</td> </tr> <tr> <th>Speed :-</th> <td ALIGN=CENTER >"; s += (gps.speed.kmph()); s += (" kmph"); s += "</td></tr> <tr> <th>Altitude :-</th> <td ALIGN=CENTER >"; s += (gps.altitude.meters()); s += (" m"); s += "</td> </tr> </table> "; s += "</body> </html> "; client.print(s); // all the values are send to the webpage delay(100); } void print_speed() { display.clearDisplay(); display.setTextColor(SSD1306_WHITE); if (gps.location.isValid() == 1) { //String gps_speed = String(gps.speed.kmph()); display.setTextSize(1); display.setCursor(25, 5); display.print("Lat: "); display.setCursor(50, 5); display.print(gps.location.lat(), 6); display.setCursor(25, 20); display.print("Lng: "); display.setCursor(50, 20); display.print(gps.location.lng(), 6); display.setCursor(25, 35); display.print("Speed: "); display.setCursor(65, 35); display.print(gps.speed.kmph()); display.setTextSize(1); display.setCursor(0, 50); display.print("SAT:"); display.setCursor(25, 50); display.print(gps.satellites.value()); display.setTextSize(1); display.setCursor(70, 50); display.print("ALT:"); display.setCursor(95, 50); display.print(gps.altitude.meters(), 0); display.display(); } else { display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.setTextSize(3); display.print("No Data"); display.display(); } } |
After uploading the code, you can open the Serial Monitor to get the IP Address of the ESP32 Module.
Go to your web browser and enter the IP Address that you got from Serial Monitor. Then hit enter.
















3 Comments
How can I send more decimals in latitude and longitude to display in my web browser?
Bro juat leaked where he lives
You can use No-IP offers DDNS and DNS solutions for home. That will hide your location