Arduino Tutorial
GPS Navigation
This Arduino GPS Navigation tutorial utilizes the Adafruit Ultimate GPS Breakout (66-channel, 10 Hz updates) along with the TinyGPS++ library to provide real-time location tracking and navigation. The system allows a user to request:
1. Current Location (Latitude & Longitude) by typing "Show Location" in the Serial Monitor.
2. Navigation Data (Distance & Bearing to a target location) by typing "Chart Course to Target".
Application for Autonomous Rover Missions
This GPS tutorial is crucial for navigation in autonomous rover missions.
Required Hardware
To complete this tutorial, you will need:
- Arduino Uno
- Adafruit Ultimate GPS (MTK3329/MTK3339)
- Jumper Wires
- Breadboard
- USB Cable for Arduino
Required Libraries
Install the following libraries in the Arduino IDE:
- Adafruit_GPS Library
- SoftwareSerial Library
Wiring Diagram
Below is a simple wiring guide for connecting the Adafruit GPS module to the Arduino:
- VCC (GPS) → 5V (Arduino)
- GND (GPS) → GND (Arduino)
- TX (GPS) → Digital Pin 8 (Arduino)
- RX (GPS) → Digital Pin 7 (Arduino)
Sample Arduino Code
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
// Define GPS Module connection (SoftwareSerial for Arduino Uno)
SoftwareSerial mySerial(8,7); // RX (GPS) -> 8, TX (GPS) -> 7
Adafruit_GPS GPS(&mySerial);
TinyGPSPlus gpsParser;
#define GPSECHO false // Set to true for debugging
// Target GPS Coordinates (specified location)
// Example Location is Confluence Hall
const double targetLat = 39.080709173856086;
const double targetLon = -108.56006936806281;
void setup() {
// Startup sequence for serial connections
Serial.begin(115200);
delay(5000);
GPS.begin(9600);
Serial.print("Initializing GPS Module...");
// GPS configuration commands
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); // Minimum recommended data
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // Set update rate to 1Hz
// Serial feedback for user
Serial.println("Searching for Starlink...");
// Wait until the GPS gets a valid fix
while (true) {
// Read a character from the GPS module's serial output
char c = GPS.read();
// If GPSECHO is enabled, print the raw GPS data to Serial Monitor for debugging
if (c && GPSECHO) Serial.write(c);
// Check if a new NMEA sentence has been received from the GPS module
if (GPS.newNMEAreceived()) {
break; // Exit the loop once valid GPS data is received
}
// Print a dot (.) every second to indicate waiting for GPS fix
Serial.print(".");
delay(1000); // Wait 1 second before checking again
}
Serial.println("\nGPS fix acquired! Type 'Show Location' or 'Chart Course to Target'.");
}
void loop() {
// Read data from the GPS module
char c = GPS.read();
// If GPSECHO is enabled, print raw GPS data to Serial Monitor for debugging
if (c && GPSECHO) Serial.write(c);
// Check if a new NMEA sentence has been received
if (GPS.newNMEAreceived()) {
// Attempt to parse the received GPS data
// If parsing fails, exit the function and wait for the next data update
if (!GPS.parse(GPS.lastNMEA())) return;
}
// Check if there is incoming data from the Serial Monitor (user input)
if (Serial.available()) {
// Read the full command string from Serial Monitor until newline character ('\n')
String command = Serial.readStringUntil('\n');
command.trim(); // Remove any leading/trailing whitespace and new lines
// Compare the user input and execute the corresponding function
if (command.equalsIgnoreCase("Show Location")) {
displayCurrLoc(); // Display current latitude and longitude
}
else if (command.equalsIgnoreCase("Chart Course to Target")) {
navigateToTarget(); // Compute and display distance & bearing to the target location
}
}
}
// Function to display the current location
void displayCurrLoc() {
Serial.println("\nCurrent Location:");
Serial.print("Latitude: ");
Serial.println(GPS.latitudeDegrees, 6);
Serial.print("Longitude: ");
Serial.println(GPS.longitudeDegrees, 6);
}
// Function to calculate distance and bearing to the target location
void navigateToTarget() {
// Retrieve the current latitude and longitude from the GPS module
double currentLat = GPS.latitudeDegrees;
double currentLon = GPS.longitudeDegrees;
// Calculate the distance (in meters) from the current location to the target location
double distanceToTarget = gpsParser.distanceBetween(
currentLat, currentLon, targetLat, targetLon
);
// Calculate the course (bearing in degrees) from the current location to the target location
double courseToTarget = gpsParser.courseTo(
currentLat, currentLon, targetLat, targetLon
);
Serial.println("\nNavigation Data:");
Serial.print("Distance to Target: "); Serial.print(distanceToTarget, 2); Serial.println(" meters");
Serial.print("Course to Target: "); Serial.print(courseToTarget, 2); Serial.println(" degrees");
}