Vehicle trackers, data loggers and rovers often pair a GPS with other serial modules, and that is where the Mega shines: it has three spare hardware serial ports. The NEO-6M goes on Serial1 (pins 19/18), and the USB Serial Monitor stays free.
The sketch uses TinyGPSPlus to print position, speed, altitude and HDOP (fix quality) once a second. Because the UART does the receiving in hardware, nothing is lost while the Mega is printing — the checksum-error counter stays at zero.
Wiring
| Arduino Mega 2560 | NEO-6M GPS module (GY-NEO6MV2) | Wire | Notes |
|---|---|---|---|
| 5V | VCC | red | |
| D18 | RX | yellow | Via 1 kΩ / 2 kΩ divider — TX1 → GPS RX. Optional: only for sending configuration commands. |
| D19 | TX | green | GPS TX → RX1. 3.3 V into the Mega reads fine. |
| GND | GND | black |
3.3–5 V (on-board 3.3 V regulator) part, 5 V board. The module’s TX is a 3.3 V signal, which every board reads fine. Its RX pin is 3.3 V logic: from a 5 V Arduino TX, add a 1 kΩ / 2 kΩ divider. You only need RX if your sketch sends configuration commands.
Board quirks
- The Mega has four hardware UARTs. Serial1 = RX1 pin 19 / TX1 pin 18; Serial2 = 17/16; Serial3 = 15/14. Cross them: GPS TX goes to an RX pin.
- Hardware serial buffers bytes in the background, so long
Serial.prints don’t corrupt NMEA the way SoftwareSerial does on an Uno or Nano. The sketch prints the checksum-error count to prove it. - Leave pins 0/1 alone — they are Serial (USB) and used for uploads.
- First fix outdoors takes 30 s to a few minutes; the module LED blinks once a second once it has one.
Code
// NEO-6M GPS on an Arduino Mega 2560 using hardware Serial1 — no SoftwareSerial, no lost bytes.
// GPS TX → D19 (RX1), GPS RX ← D18 (TX1) through a 1 kΩ / 2 kΩ divider, VCC → 5V, GND → GND.
#include <TinyGPSPlus.h>
TinyGPSPlus gps;
void setup() {
Serial.begin(115200); // USB monitor
Serial1.begin(9600); // NEO-6M default
Serial.println(F("GPS on Serial1 - waiting for a fix"));
}
void loop() {
while (Serial1.available()) gps.encode(Serial1.read());
static unsigned long last = 0;
if (millis() - last < 1000) return;
last = millis();
if (gps.charsProcessed() < 10) {
Serial.println(F("No NMEA data - check GPS TX -> D19 (RX1)"));
return;
}
Serial.print(F("Sats: "));
Serial.print(gps.satellites.isValid() ? (int)gps.satellites.value() : 0);
if (gps.location.isValid()) {
Serial.print(F(" Lat: "));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" Lng: "));
Serial.print(gps.location.lng(), 6);
Serial.print(F(" Speed: "));
Serial.print(gps.speed.kmph(), 1);
Serial.print(F(" km/h Alt: "));
Serial.print(gps.altitude.meters(), 0);
Serial.print(F(" m HDOP: "));
Serial.print(gps.hdop.hdop(), 1);
} else {
Serial.print(F(" (no fix yet)"));
}
Serial.print(F(" Checksum errors: "));
Serial.println(gps.failedChecksum());
}// NEO-6M GPS on an Arduino Mega 2560 using hardware Serial1 — no SoftwareSerial, no lost bytes.
// GPS TX → D19 (RX1), GPS RX ← D18 (TX1) through a 1 kΩ / 2 kΩ divider, VCC → 5V, GND → GND.
#include <TinyGPSPlus.h>
TinyGPSPlus gps;
void setup() {
Serial.begin(115200); // USB monitor
Serial1.begin(9600); // NEO-6M default
Serial.println(F("GPS on Serial1 - waiting for a fix"));
}
void loop() {
while (Serial1.available()) gps.encode(Serial1.read());
static unsigned long last = 0;
if (millis() - last < 1000) return;
last = millis();
if (gps.charsProcessed() < 10) {
Serial.println(F("No NMEA data - check GPS TX -> D19 (RX1)"));
return;
}
Serial.print(F("Sats: "));
Serial.print(gps.satellites.isValid() ? (int)gps.satellites.value() : 0);
if (gps.location.isValid()) {
Serial.print(F(" Lat: "));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" Lng: "));
Serial.print(gps.location.lng(), 6);
Serial.print(F(" Speed: "));
Serial.print(gps.speed.kmph(), 1);
Serial.print(F(" km/h Alt: "));
Serial.print(gps.altitude.meters(), 0);
Serial.print(F(" m HDOP: "));
Serial.print(gps.hdop.hdop(), 1);
} else {
Serial.print(F(" (no fix yet)"));
}
Serial.print(F(" Checksum errors: "));
Serial.println(gps.failedChecksum());
}Library: TinyGPSPlus (Mikal Hart) — compiled with TinyGPSPlus 1.0.3.
Expected serial output
GPS on Serial1 - waiting for a fix
Sats: 0 (no fix yet) Checksum errors: 0
Sats: 8 Lat: 28.613939 Lng: 77.209023 Speed: 0.4 km/h Alt: 216 m HDOP: 1.1 Checksum errors: 0GPS on Serial1 - waiting for a fix Sats: 0 (no fix yet) Checksum errors: 0 Sats: 8 Lat: 28.613939 Lng: 77.209023 Speed: 0.4 km/h Alt: 216 m HDOP: 1.1 Checksum errors: 0