Vijay Kumar
Published © GPL3+

Getting Started with Ai-Thinker GP-02: BDS/GPS/GNSS

Discover how to set up the Ai‑Thinker GP‑02 module with multiple ESP32 variants and an OLED display.

BeginnerProtip1 hour522
Getting Started with Ai-Thinker GP-02: BDS/GPS/GNSS

Things used in this project

Hardware components

FireBeetle 2 Board ESP32-S3 (N16R8) AIoT Microcontroller with Camera
DFRobot FireBeetle 2 Board ESP32-S3 (N16R8) AIoT Microcontroller with Camera
×1
Seeed Studio XIAO ESP32S3 Sense
Seeed Studio XIAO ESP32S3 Sense
×1
XIAO ESP32C3
Seeed Studio XIAO ESP32C3
×1
ESP32 DEV KIT V1
×1
Ai-Thinker GP-02 BDS/GPS/GNSS Module
×1
OLED Display
×1
Breadboard
×1
Jumper Cables
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Circuit Diagram

Seeed Studio XIAO ESP32 S3

Circuit Diagram

Seeed Studio XIAO ESP32 C3

Circuit Diagram

DF Robot FireBeetle 2 ESP32 S3

Circuit Diagram

ESP32 DEV KIT V1

Code

Seeed Studio XIAO ESP32 S3

C/C++
Code
// Include libraries for GPS parsing, I2C communication, graphics, and OLED display
#include <TinyGPSPlus.h>
#include <Wire.h>                    // I2C communication library
#include <Adafruit_GFX.h>            // Graphics library for OLED
#include <Adafruit_SSD1306.h>        // SSD1306 OLED display driver

// OLED display dimensions (128x64 pixels standard)
#define SCREEN_WIDTH 128    // OLED screen width in pixels
#define SCREEN_HEIGHT 64    // OLED screen height in pixels
#define ADDRESS 0x3C        // Replace this with the I2C address of your OLED display

// OLED reset pin configuration (-1 means use Arduino reset pin)
#define OLED_RESET -1                   // No dedicated reset pin, share Arduino reset

// Create OLED display object with specified dimensions, I2C interface, and reset pin
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Create GPS parser object
TinyGPSPlus gps;                    // TinyGPSPlus object for NMEA sentence parsing

// Define GPS serial port and pin assignments for XIAO ESP32S3/XIAO ESP32C3
#define gpsSerial Serial1               // Use hardware Serial1 (UART1) for GPS
#define RX_PIN D7                       // XIAO D7 (RX pin)  GPS TX
#define TX_PIN D6                       // XIAO D6 (TX pin)  GPS RX (optional)

// Setup function - runs once at startup
void setup() {
  // Initialize GPS serial port on Serial1 with specified pins and GPS baud rate (9600)
  gpsSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);  // 8 data bits, no parity, 1 stop bit

  // Initialize OLED display with internal power supply and I2C address
  if (!display.begin(SSD1306_SWITCHCAPVCC, ADDRESS)) {   // Try to start OLED at I2C address 
    Serial.println(F("SSD1306 allocation failed"));      // Print error if OLED fails
    for (;;);                                            // Infinite loop if OLED fails
  }
  
  // Clear OLED display buffer
  display.clearDisplay();
  
  // Configure OLED text rendering settings
  display.setTextSize(1);           // Set text size to 1 (smallest)
  display.setTextColor(SSD1306_WHITE);  // Set text color to white
  display.setCursor(0, 0);          // Set text cursor to top-left corner (x=0, y=0)
  
  // Display startup message on OLED
  display.println("Waiting for GPS...");
  display.display();                // Update OLED with buffer contents
}

// Main loop - runs continuously
void loop() {
  // Read all available GPS data from serial port
  while (gpsSerial.available() > 0) {
    // Read one byte from GPS serial port
    if (gps.encode(gpsSerial.read())) {     // Parse NMEA data, returns true if valid
      displayLocationInfo();                // Update display with GPS data when valid fix
    }
  }

  // Check if 5 seconds passed with no GPS data (less than 10 chars processed)
  if (millis() > 5000 && gps.charsProcessed() < 10) {
    display.clearDisplay();                 // Clear OLED buffer
    display.setCursor(0, 0);                // Reset cursor to top-left
    display.println("No GPS detected!");    // Show error message
    display.display();                      // Update OLED display
    while (true);                           // Stop program execution
  }
}

// Function to display GPS location information on OLED
void displayLocationInfo() {
  display.clearDisplay();                   // Clear previous display content
  display.setCursor(0, 0);                  // Reset cursor to top-left corner

  // Display Latitude
  display.print("Lat: ");                   // Print "Lat: " label
  if (gps.location.isValid()) {             // Check if latitude data is valid
    display.println(gps.location.lat(), 6); // Print latitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display Longitude
  display.print("Lng: ");                   // Print "Lng: " label
  if (gps.location.isValid()) {             // Check if longitude data is valid
    display.println(gps.location.lng(), 6); // Print longitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display number of satellites
  display.print("Sats: ");                  // Print "Sats: " label
  display.println(gps.satellites.value());  // Print satellite count

  // Display altitude
  display.print("Alt: ");                   // Print "Alt: " label
  display.print(gps.altitude.meters());     // Print altitude in meters
  display.println(" m");                    // Print units

  // Display ground speed
  display.print("Spd: ");                   // Print "Spd: " label
  display.print(gps.speed.kmph());          // Print speed in km/h
  display.println(" km/h");                 // Print units

  // Display course / direction of movement
  display.print("Course: ");                // Print "Course: " label
  display.print(gps.course.deg());          // Print couse in degrees
  display.write(247);                       // Print units
  display.println();                     

  // Display UTC time
  display.print("UTC: ");                   // Print "UTC: " label
  if (gps.time.isValid()) {                 // Check if time data is valid
    // Format time as HH:MM:SS using printf-style formatting
    display.printf("%02d:%02d:%02d\n",
                   gps.time.hour(),
                   gps.time.minute(),
                   gps.time.second());
  } else {
    display.println("Invalid");             // Show "Invalid" if no time fix
  }

  // Display current date
  display.print("Date: ");                   // Print "Date: " label
  if (gps.date.isValid()) {                  // Check if date data is valid
    // Format date as DAY/MONTH/YEAR using printf-style formatting
    display.printf("%02d/%02d/%04d\n",
                  gps.date.day(),
                  gps.date.month(),
                  gps.date.year());
  } else {
    display.println("Invalid");               // Show "Invalid" if no time fix
  }
  display.display();                        // Push buffer to OLED screen (refresh display)
}

Seeed Studio XIAO ESP32 C3

C/C++
Code
// Include libraries for GPS parsing, I2C communication, graphics, and OLED display
#include <TinyGPSPlus.h>
#include <Wire.h>                    // I2C communication library
#include <Adafruit_GFX.h>            // Graphics library for OLED
#include <Adafruit_SSD1306.h>        // SSD1306 OLED display driver

// OLED display dimensions (128x64 pixels standard)
#define SCREEN_WIDTH 128    // OLED screen width in pixels
#define SCREEN_HEIGHT 64    // OLED screen height in pixels
#define ADDRESS 0x3C        // Replace this with the I2C address of your OLED display

// OLED reset pin configuration (-1 means use Arduino reset pin)
#define OLED_RESET -1                   // No dedicated reset pin, share Arduino reset

// Create OLED display object with specified dimensions, I2C interface, and reset pin
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Create GPS parser object
TinyGPSPlus gps;                    // TinyGPSPlus object for NMEA sentence parsing

// Define GPS serial port and pin assignments for XIAO ESP32S3/XIAO ESP32C3
#define gpsSerial Serial1               // Use hardware Serial1 (UART1) for GPS
#define RX_PIN D7                       // XIAO D7 (RX pin)  GPS TX
#define TX_PIN D6                       // XIAO D6 (TX pin)  GPS RX (optional)

// Setup function - runs once at startup
void setup() {
  // Initialize GPS serial port on Serial1 with specified pins and GPS baud rate (9600)
  gpsSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);  // 8 data bits, no parity, 1 stop bit

  // Initialize OLED display with internal power supply and I2C address
  if (!display.begin(SSD1306_SWITCHCAPVCC, ADDRESS)) {   // Try to start OLED at I2C address 
    Serial.println(F("SSD1306 allocation failed"));      // Print error if OLED fails
    for (;;);                                            // Infinite loop if OLED fails
  }
  
  // Clear OLED display buffer
  display.clearDisplay();
  
  // Configure OLED text rendering settings
  display.setTextSize(1);           // Set text size to 1 (smallest)
  display.setTextColor(SSD1306_WHITE);  // Set text color to white
  display.setCursor(0, 0);          // Set text cursor to top-left corner (x=0, y=0)
  
  // Display startup message on OLED
  display.println("Waiting for GPS...");
  display.display();                // Update OLED with buffer contents
}

// Main loop - runs continuously
void loop() {
  // Read all available GPS data from serial port
  while (gpsSerial.available() > 0) {
    // Read one byte from GPS serial port
    if (gps.encode(gpsSerial.read())) {     // Parse NMEA data, returns true if valid
      displayLocationInfo();                // Update display with GPS data when valid fix
    }
  }

  // Check if 5 seconds passed with no GPS data (less than 10 chars processed)
  if (millis() > 5000 && gps.charsProcessed() < 10) {
    display.clearDisplay();                 // Clear OLED buffer
    display.setCursor(0, 0);                // Reset cursor to top-left
    display.println("No GPS detected!");    // Show error message
    display.display();                      // Update OLED display
    while (true);                           // Stop program execution
  }
}

// Function to display GPS location information on OLED
void displayLocationInfo() {
  display.clearDisplay();                   // Clear previous display content
  display.setCursor(0, 0);                  // Reset cursor to top-left corner

  // Display Latitude
  display.print("Lat: ");                   // Print "Lat: " label
  if (gps.location.isValid()) {             // Check if latitude data is valid
    display.println(gps.location.lat(), 6); // Print latitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display Longitude
  display.print("Lng: ");                   // Print "Lng: " label
  if (gps.location.isValid()) {             // Check if longitude data is valid
    display.println(gps.location.lng(), 6); // Print longitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display number of satellites
  display.print("Sats: ");                  // Print "Sats: " label
  display.println(gps.satellites.value());  // Print satellite count

  // Display altitude
  display.print("Alt: ");                   // Print "Alt: " label
  display.print(gps.altitude.meters());     // Print altitude in meters
  display.println(" m");                    // Print units

  // Display ground speed
  display.print("Spd: ");                   // Print "Spd: " label
  display.print(gps.speed.kmph());          // Print speed in km/h
  display.println(" km/h");                 // Print units

  // Display course / direction of movement
  display.print("Course: ");                // Print "Course: " label
  display.print(gps.course.deg());          // Print couse in degrees
  display.write(247);                       // Print units
  display.println();                     

  // Display UTC time
  display.print("UTC: ");                   // Print "UTC: " label
  if (gps.time.isValid()) {                 // Check if time data is valid
    // Format time as HH:MM:SS using printf-style formatting
    display.printf("%02d:%02d:%02d\n",
                   gps.time.hour(),
                   gps.time.minute(),
                   gps.time.second());
  } else {
    display.println("Invalid");             // Show "Invalid" if no time fix
  }

  // Display current date
  display.print("Date: ");                   // Print "Date: " label
  if (gps.date.isValid()) {                  // Check if date data is valid
    // Format date as DAY/MONTH/YEAR using printf-style formatting
    display.printf("%02d/%02d/%04d\n",
                  gps.date.day(),
                  gps.date.month(),
                  gps.date.year());
  } else {
    display.println("Invalid");               // Show "Invalid" if no time fix
  }
  display.display();                        // Push buffer to OLED screen (refresh display)
}

DF Robot FireBeetle 2 ESP32 S3

C/C++
Code
// Include libraries for GPS parsing, I2C communication, graphics, and OLED display
#include <TinyGPSPlus.h>
#include <Wire.h>                    // I2C communication library
#include <Adafruit_GFX.h>            // Graphics library for OLED
#include <Adafruit_SSD1306.h>        // SSD1306 OLED display driver

// OLED display dimensions (128x64 pixels standard)
#define SCREEN_WIDTH 128    // OLED screen width in pixels
#define SCREEN_HEIGHT 64    // OLED screen height in pixels
#define ADDRESS 0x3C        // Replace this with the I2C address of your OLED display

// OLED reset pin configuration (-1 means use Arduino reset pin)
#define OLED_RESET -1                // No dedicated reset pin, share Arduino reset

// Create OLED display object with specified dimensions, I2C interface, and reset pin
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Create GPS parser object
TinyGPSPlus gps;                     // TinyGPSPlus object for NMEA sentence parsing

// Define GPS serial port and pin assignments for FireBeetle ESP32S3
#define gpsSerial Serial2              // Use hardware Serial2 (UART2) for GPS
#define RX_PIN 44                      // FireBeetle RX/GPIO44 (RX pin)  GPS TX
#define TX_PIN 43                      // FireBeetle TX/GPIO43 (TX pin)  GPS RX (optional)

// Setup function - runs once at startup
void setup() {
  // Initialize GPS serial port on Serial2 with specified pins and GPS baud rate (9600)
  gpsSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);  // 8 data bits, no parity, 1 stop bit

  // Initialize OLED display with internal power supply and I2C address
  if (!display.begin(SSD1306_SWITCHCAPVCC, ADDRESS)) {   // Try to start OLED at I2C address
    Serial.println(F("SSD1306 allocation failed"));      // Print error if OLED fails
    for (;;);                                            // Infinite loop if OLED fails
  }

  // Clear OLED display buffer
  display.clearDisplay();

  // Configure OLED text rendering settings
  display.setTextSize(1);               // Set text size to 1 (smallest)
  display.setTextColor(SSD1306_WHITE);  // Set text color to white
  display.setCursor(0, 0);              // Set text cursor to top-left corner (x=0, y=0)

  // Display startup message on OLED
  display.println("Waiting for GPS...");
  display.display();                    // Update OLED with buffer contents
}

// Main loop - runs continuously
void loop() {
  // Read all available GPS data from serial port
  while (gpsSerial.available() > 0) {
    // Read one byte from GPS serial port
    if (gps.encode(gpsSerial.read())) {     // Parse NMEA data, returns true if valid
      displayLocationInfo();                // Update display with GPS data when valid fix
    }
  }

  // Check if 5 seconds passed with no GPS data (less than 10 chars processed)
  if (millis() > 5000 && gps.charsProcessed() < 10) {
    display.clearDisplay();                 // Clear OLED buffer
    display.setCursor(0, 0);                // Reset cursor to top-left
    display.println("No GPS detected!");    // Show error message
    display.display();                      // Update OLED display
    while (true);                           // Stop program execution
  }
}

// Function to display GPS location information on OLED
void displayLocationInfo() {
  display.clearDisplay();                   // Clear previous display content
  display.setCursor(0, 0);                  // Reset cursor to top-left corner

  // Display Latitude
  display.print("Lat: ");                   // Print "Lat: " label
  if (gps.location.isValid()) {             // Check if latitude data is valid
    display.println(gps.location.lat(), 6); // Print latitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display Longitude
  display.print("Lng: ");                   // Print "Lng: " label
  if (gps.location.isValid()) {             // Check if longitude data is valid
    display.println(gps.location.lng(), 6); // Print longitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display number of satellites
  display.print("Sats: ");                  // Print "Sats: " label
  display.println(gps.satellites.value());  // Print satellite count

  // Display altitude
  display.print("Alt: ");                   // Print "Alt: " label
  display.print(gps.altitude.meters());     // Print altitude in meters
  display.println(" m");                    // Print units

  // Display ground speed
  display.print("Spd: ");                   // Print "Spd: " label
  display.print(gps.speed.kmph());          // Print speed in km/h
  display.println(" km/h");                 // Print units

  // Display course / direction of movement
  display.print("Course: ");                // Print "Course: " label
  display.print(gps.course.deg());          // Print couse in degrees
  display.write(247);                       // Print units
  display.println();                     

  // Display UTC time
  display.print("UTC: ");                   // Print "UTC: " label
  if (gps.time.isValid()) {                 // Check if time data is valid
    // Format time as HH:MM:SS using printf-style formatting
    display.printf("%02d:%02d:%02d\n",
                   gps.time.hour(),
                   gps.time.minute(),
                   gps.time.second());
  } else {
    display.println("Invalid");             // Show "Invalid" if no time fix
  }

  // Display current date
  display.print("Date: ");                   // Print "Date: " label
  if (gps.date.isValid()) {                  // Check if date data is valid
    // Format date as DAY/MONTH/YEAR using printf-style formatting
    display.printf("%02d/%02d/%04d\n",
                  gps.date.day(),
                  gps.date.month(),
                  gps.date.year());
  } else {
    display.println("Invalid");               // Show "Invalid" if no time fix
  }
  display.display();                        // Push buffer to OLED screen (refresh display)
}

ESP32 DEV KIT V1

C/C++
Code
// Include libraries for GPS parsing, I2C communication, graphics, and OLED display
#include <TinyGPSPlus.h>
#include <Wire.h>                    // I2C communication library
#include <Adafruit_GFX.h>            // Graphics library for OLED
#include <Adafruit_SSD1306.h>        // SSD1306 OLED display driver

// OLED display dimensions (128x64 pixels standard)
#define SCREEN_WIDTH 128    // OLED screen width in pixels
#define SCREEN_HEIGHT 64    // OLED screen height in pixels
#define ADDRESS 0x3C        // Replace this with the I2C address of your OLED display

// OLED reset pin configuration (-1 means use Arduino reset pin)
#define OLED_RESET -1                // No dedicated reset pin, share Arduino reset

// Create OLED display object with specified dimensions, I2C interface, and reset pin
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Create GPS parser object
TinyGPSPlus gps;                     // TinyGPSPlus object for NMEA sentence parsing

// Define GPS serial port and pin assignments for ESP32 DEV KIT V1
#define gpsSerial Serial2              // Use hardware Serial2 (UART2) for GPS
#define RX_PIN 16                      // ESP32 RX2/GPIO16 (RX pin)  GPS TX
#define TX_PIN 17                      // ESP32 TX2/GPIO17 (TX pin)  GPS RX (optional)

// Setup function - runs once at startup
void setup() {
  // Initialize GPS serial port on Serial2 with specified pins and GPS baud rate (9600)
  gpsSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);  // 8 data bits, no parity, 1 stop bit

  // Initialize OLED display with internal power supply and I2C address
  if (!display.begin(SSD1306_SWITCHCAPVCC, ADDRESS)) {   // Try to start OLED at I2C address
    Serial.println(F("SSD1306 allocation failed"));      // Print error if OLED fails
    for (;;);                                            // Infinite loop if OLED fails
  }

  // Clear OLED display buffer
  display.clearDisplay();

  // Configure OLED text rendering settings
  display.setTextSize(1);               // Set text size to 1 (smallest)
  display.setTextColor(SSD1306_WHITE);  // Set text color to white
  display.setCursor(0, 0);              // Set text cursor to top-left corner (x=0, y=0)

  // Display startup message on OLED
  display.println("Waiting for GPS...");
  display.display();                    // Update OLED with buffer contents
}

// Main loop - runs continuously
void loop() {
  // Read all available GPS data from serial port
  while (gpsSerial.available() > 0) {
    // Read one byte from GPS serial port
    if (gps.encode(gpsSerial.read())) {     // Parse NMEA sentence, returns true if valid
      displayLocationInfo();                // Update display with GPS data when valid fix
    }
  }

  // Check if 5 seconds passed with no GPS data (less than 10 chars processed)
  if (millis() > 5000 && gps.charsProcessed() < 10) {
    display.clearDisplay();                 // Clear OLED buffer
    display.setCursor(0, 0);                // Reset cursor to top-left
    display.println("No GPS detected!");    // Show error message
    display.display();                      // Update OLED display
    while (true);                           // Stop program execution
  }
}

// Function to display GPS location information on OLED
void displayLocationInfo() {
  display.clearDisplay();                   // Clear previous display content
  display.setCursor(0, 0);                  // Reset cursor to top-left corner

  // Display Latitude
  display.print("Lat: ");                   // Print "Lat: " label
  if (gps.location.isValid()) {             // Check if latitude data is valid
    display.println(gps.location.lat(), 6); // Print latitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display Longitude
  display.print("Lng: ");                   // Print "Lng: " label
  if (gps.location.isValid()) {             // Check if longitude data is valid
    display.println(gps.location.lng(), 6); // Print longitude with 6 decimal places
  } else {
    display.println("Invalid");             // Show "Invalid" if no valid fix
  }

  // Display number of satellites
  display.print("Sats: ");                  // Print "Sats: " label
  display.println(gps.satellites.value());  // Print satellite count

  // Display altitude
  display.print("Alt: ");                   // Print "Alt: " label
  display.print(gps.altitude.meters());     // Print altitude in meters
  display.println(" m");                    // Print units

  // Display ground speed
  display.print("Spd: ");                   // Print "Spd: " label
  display.print(gps.speed.kmph());          // Print speed in km/h
  display.println(" km/h");                 // Print units

  // Display course / direction of movement
  display.print("Course: ");                // Print "Course: " label
  display.print(gps.course.deg());          // Print couse in degrees
  display.write(247);                       // Print units
  display.println();                     

  // Display UTC time
  display.print("UTC: ");                   // Print "UTC: " label
  if (gps.time.isValid()) {                 // Check if time data is valid
    // Format time as HH:MM:SS using printf-style formatting
    display.printf("%02d:%02d:%02d\n",
                   gps.time.hour(),
                   gps.time.minute(),
                   gps.time.second());
  } else {
    display.println("Invalid");             // Show "Invalid" if no time fix
  }

  // Display current date
  display.print("Date: ");                   // Print "Date: " label
  if (gps.date.isValid()) {                  // Check if date data is valid
    // Format date as DAY/MONTH/YEAR using printf-style formatting
    display.printf("%02d/%02d/%04d\n",
                  gps.date.day(),
                  gps.date.month(),
                  gps.date.year());
  } else {
    display.println("Invalid");               // Show "Invalid" if no time fix
  }
  display.display();                        // Push buffer to OLED screen (refresh display)
}

Credits

Vijay Kumar
2 projects • 1 follower
CS student building IoT solutions, developing for 3+ years, started hardware journey through hands-on tinkering and experiments.

Comments