Built-in project · Arduino Uno R3

GPS position on an Arduino Uno

A NEO-6M on an Uno with SoftwareSerial and TinyGPS++. It prints latitude, longitude, satellites and time once a second. The whole build, an Arduino Uno and 1 more part, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Beginner Runs in your browser. Free, and no account needed.

Step by step, with the wiring and the common mistakes: Arduino NEO-6M GPS: Wiring, TinyGPS++ and Code

GPS position · Arduino Uno R3live0.000 s 0.00x
Click the GPS to lose the fix, and again to get it back
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// GPS position: a NEO-6M on an Uno, the way the tutorials wire it.
//
//   NEO-6M TX  -> pin 4   (the sketch's RX)
//   NEO-6M RX  <- pin 3   (the sketch's TX; the module ignores it here)
//   NEO-6M VCC -> 5V, GND -> GND
//
// The module sends NMEA sentences at 9600 baud, once a second. TinyGPS++
// reads them one character at a time, and the sketch prints the position
// each time a new one arrives.
//
// The serial monitor runs at 115200, as in the TinyGPS++ examples. Mokxi's
// Serial has no send buffer: it waits for each byte to leave. At 9600 a
// printed line takes about 70 ms, the GPS keeps talking meanwhile, and
// SoftwareSerial's 64-byte buffer overflows: the sentence with the satellite
// count and the altitude is the one that gets lost. A real Uno buffers its
// Serial output, so a short line costs far less there; a long print or a long
// delay() can still make it miss bytes.
//
// There is no sky here. Mokxi does not model satellites or a radio. The
// position is a property of the module: click it and change lat and lon in
// the properties panel to move it. Click the module on the canvas to lose the
// fix, and click again to get it back.

#include <SoftwareSerial.h>
#include <TinyGPS++.h>

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;
SoftwareSerial gpsSerial(RXPin, TXPin);

void setup() {
  Serial.begin(115200);
  gpsSerial.begin(GPSBaud);
  Serial.println("Waiting for the GPS...");
}

void twoDigits(int value) {
  if (value < 10) Serial.print('0');
  Serial.print(value);
}

void showPosition() {
  Serial.print("Lat: ");
  Serial.print(gps.location.lat(), 6);
  Serial.print("  Lng: ");
  Serial.print(gps.location.lng(), 6);
  Serial.print("  Sats: ");
  Serial.print(gps.satellites.value());
  Serial.print("  Alt: ");
  Serial.print(gps.altitude.meters(), 1);
  Serial.print(" m  UTC ");
  twoDigits(gps.time.hour());
  Serial.print(':');
  twoDigits(gps.time.minute());
  Serial.print(':');
  twoDigits(gps.time.second());
  Serial.println();
}

// Every character the module sent since last time, into the parser.
void readGps() {
  while (gpsSerial.available() > 0) {
    gps.encode(gpsSerial.read());
  }
}

unsigned long lastLine = 0;
bool warned = false;

void loop() {
  readGps();
  // The GGA sentence brings the position, the satellites and the altitude
  // together, once a second. (RMC updates the position too, a moment
  // earlier, but carries no altitude.)
  if (gps.location.isUpdated() && gps.altitude.isUpdated()) {
    showPosition();
    lastLine = millis();
  }
  // Sentences but no position: the module has no fix.
  if (gps.charsProcessed() > 10 && millis() - lastLine > 3000) {
    Serial.println("No fix yet: waiting for satellites.");
    lastLine = millis();
  }
  // Nothing at all after five seconds is a wiring fault, not a sky fault.
  if (!warned && millis() > 5000 && gps.charsProcessed() < 10) {
    Serial.println("No data from the GPS: check TX goes to pin 4.");
    warned = true;
  }
}

Parts list

3 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

4 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Arduino Uno R3 pin 4; GPS module, NEO-6M pin TX
  • Arduino Uno R3 pin 3; GPS module, NEO-6M pin RX
  • Arduino Uno R3 pin 5V; GPS module, NEO-6M pin VCC
  • Ground: Arduino Uno R3 pin GND; GPS module, NEO-6M pin GND

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.