# Adafruit Ultimate GPS

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/031/842/medium800/gps_746_topkit.jpg?1461187930)

We carry a few different GPS modules here in the Adafruit shop, but none that satisfied our every desire - that's why we designed this little GPS breakout board. We believe this is the **Ultimate** GPS module, so we named it that. It's got everything you want and more:

- -165 dBm sensitivity, 10 Hz updates, 66 channels
- 5V friendly design and only 20mA current draw
- Breadboard friendly + two mounting holes
- RTC battery-compatible
- Built-in datalogging
- PPS output on fix
- Internal patch antenna + u.FL connector for external active antenna
- Fix status LED

Primary: Note there are two versions of the breakout board: one to wire to projects via serial lines & read from a microcontroller (#746) and one meant to connect to a USB cable to an appropriate computer (#4279) which is not programmable in Arduino. Be sure you find the directions for the version you are interested in.

The breakout is built around the MTK3339 chipset, a no-nonsense, high-quality GPS module that can track up to 22 satellites on 66 channels, has an excellent high-sensitivity receiver (-165 dB tracking!), and a built in antenna. It can do up to 10 location updates a second for high speed, high sensitivity logging or tracking. Power usage is incredibly low, only 20 mA during navigation.

![](https://cdn-learn.adafruit.com/assets/assets/000/031/843/medium800/gps_746_iso.jpg?1461187948)

## Ultimate GPS Breakout Board

**The Breadboard Breakout board comes with:** a ultra-low dropout 3.3V regulator so you can power it with 3.3-5VDC in, 5V level safe inputs, ENABLE pin so you can turn off the module using any microcontroller pin or switch, a footprint for optional CR1220 coin cell to keep the RTC running and allow warm starts and a tiny bright red LED. The LED blinks at about 1Hz while it's searching for satellites and blinks once every 15 seconds when a fix is found to conserve power. If you want to have an LED on all the time, we also provide the FIX signal out on a pin so you can put an external LED on.

## Ultimate GPS USB Board

**The USB Breakout board comes with:** 4-pin USB breakout for direct-soldering or connection to a USB host, two yellow receive/transmit LEDs let you know when data is being transmitted to or from the GPS module serial interface, a footprint for optional CR1220 coin cell to keep the RTC running and allow warm starts and a tiny bright red LED. The LED blinks at about 1Hz while it's searching for satellites and blinks once every 15 seconds when a fix is found to conserve power. If you want to have an LED on all the time, we also provide the FIX signal out on a pin so you can put an external LED on.

![](https://cdn-learn.adafruit.com/assets/assets/000/076/816/medium800/adafruit_products_4279_top_ORIG_2019_06.jpg?1560221463 Ultimate GPS USB Micro B board)

Info: 

![](https://cdn-learn.adafruit.com/assets/assets/000/109/808/medium800/adafruit_products_UGPS_USB_C.jpg?1647550249 Ultimate GPS USB-C board)

## Antenna Usage
![](https://cdn-learn.adafruit.com/assets/assets/000/031/844/medium800/gps_746_demo.jpg?1461187956)

Two features that really stand out about version 3 MTK3339-based module is the external antenna functionality and the the built in data-logging capability. The module has a standard ceramic patch antenna that gives it -165 dB sensitivity, but when you want to have a bigger antenna, you can snap on any 3V active GPS antenna via the uFL connector. The module will automatically detect the active antenna and switch over! [Most GPS antennas use SMA connectors so you may want to pick up one of our uFL to SMA adapters.](http://www.adafruit.com/products/851 "Link: http://www.adafruit.com/products/851")   
  
The other cool feature of the new MTK3339-based module (which we have tested with great success) is the built in datalogging ability. Since there is a microcontroller inside the module, with some empty FLASH memory, the newest firmware now allows sending commands to do internal logging to that FLASH. The only thing is that you do need to have a microcontroller send the "Start Logging" command. However, after that message is sent, the microcontroller can go to sleep and does not need to wake up to talk to the GPS anymore to reduce power consumption. The time, date, longitude, latitude, and height is logged every 15 seconds and only when there is a fix. The internal FLASH can store about 16 hours of data, it will automatically append data so you don't have to worry about accidentally losing data if power is lost. It is not possible to change what is logged and how often, as its hardcoded into the module but we found that this arrangement covers many of the most common GPS datalogging requirements.

## [Pick one up today at the Adafruit shop!](http://www.adafruit.com/products/746 "Link: http://www.adafruit.com/products/746")
## Specifications:

Module specs:

- Satellites: 22 tracking, 66 searching
- Patch Antenna Size: 15mm x 15mm x 4mm
- Update rate: 1 to 10 Hz
- Position Accuracy: 1.8 meters
- Velocity Accuracy: 0.1 meters/s
- Warm/cold start: 34 seconds
- Acquisition sensitivity: -145 dBm
- Tracking sensitivity: -165 dBm
- Maximum Velocity: 515m/s
- Vin range: 3.0-5.5VDC
- MTK3339 Operating current: 25mA tracking, 20 mA current draw during navigation
- Output: NMEA 0183, 9600 baud default
- DGPS/WAAS/EGNOS supported
- FCC E911 compliance and AGPS support (Offline mode : EPO valid up to 14 days )
- Up to 210 PRN channels
- Jammer detection and reduction
- Multi-path detection and compensation

Breakout board details:

- Weight (not including coin cell or holder): 8.5g
- Dimensions (not including coin cell or holder): 25.5mm x 35mm x 6.5mm / 1.0" x 1.35" x 0.25"

If you purchased a module before March 26th, 2012 and it says MTK3329 on the silkscreen, you have the PA6B version of this breakout with the MT3329 chipset. The MTK3329 does not have built in datalogging. If your module has sharpie marker crossing out the MTK3329 text or there is no text, you have a PA6C MTK3339 with datalogging ability. If you have the version with "v3" next to the name, you have the PA6H which has PPS output and external-antenna support.

This tutorial assumes you have a '3339 type module.

# Adafruit Ultimate GPS

## Pinouts

The plain GPS breakout is meant to be used with a microcontroller that has a 3/5V UART and has all the GPIO pins exposed on the bottom 0.1" header.

**If you are using a microcontroller board with general-purpose input/output (GPIO) pins or other TTL signal level serial communications, this is the version you should get.**

![Adafruit Ultimate GPS v3 part number 746](https://cdn-learn.adafruit.com/assets/assets/000/138/527/medium640/adafruit_products_20250710_194340.jpg?1753285325)

The USB version doesn't have those GPIO pins broken out. Instead it has a single USB serial port. There's 4 pads to the right side that are the USB pinouts for when you want to solder it directly to a USB host controller.

**Note: This version is not used to wire to Arduino or CircuitPython compatible microcontroller boards. Rather it connects via USB to a computer or a single board computer like Raspberry Pi via a USB connection.**

![adafruit_products_UGPS_USB_C.jpg](https://cdn-learn.adafruit.com/assets/assets/000/109/802/medium640/adafruit_products_UGPS_USB_C.jpg?1647549665)

![adafruit_products_UGPS_USB_micro_B.jpg](https://cdn-learn.adafruit.com/assets/assets/000/109/803/medium640/adafruit_products_UGPS_USB_micro_B.jpg?1647549712)

# Breakout Power Pins
![](https://cdn-learn.adafruit.com/assets/assets/000/031/848/medium800/gps_powerpin.jpg?1461188506)

These are the pins that are involved with powering the GPS. Starting from the right are the **required** power pins:

- **VIN** - power input, connect to 3-5VDC. It's important to connect to a _clean and quiet_ power supply. GPS's are very sensitive, so you want a nice and quiet power supply. Don't connect to a switching supply if you can avoid it, an LDO will be less noisy!
- **GND** - power and signal ground. Connect to your power supply and microcontroller ground.

Then, on the left are some optional power pins:

- **VBAT** &nbsp;is an input pin - it is connected to the GPS real time clock battery backup. We suggest using the battery spot on the back but if you have a project with a coin cell or other kind of battery that you want to use (and its under 3.3V) you can connect it to the VBAT pin. **For V1 and V2 modules:** If you do this, be sure to cut the trace on the back between the RTC solder pads
- **EN&nbsp;** is the Enable pin, it is pulled high with a 10K resistor. When this pin is pulled to ground, it will turn off the GPS module. This can be handy for very low power projects where you want to easily turn the module off for long periods. You will lose your fix if you disable the GPS and it will also take a long time to get fix back if you dont have the backup battery installed.
- **3.3V&nbsp;** is the output from the onboard 3.3V regulator. If you have a need for a clean 3.3V output, you can use this! It can provide at least 100mA output.

# Breakout Serial Data Pins
![](https://cdn-learn.adafruit.com/assets/assets/000/031/849/medium800/gps_uart.jpg?1461188514)

Next pins you'll want to use are the serial data pins:

- **TX** - the pin that transmits data _from_ the GPS module to your microcontroller or computer. It is 3.3V logic level. Data comes out at 9600 baud by default
- **RX** - the pin that you can use to send data _to_ the GPS. You can use use 3.3V or 5V logic, there is a logic level shifter. By default it expects 9600 baud data, and remember you need to send it checksum'med NMEA sentences

# Breakout Other Pins
![](https://cdn-learn.adafruit.com/assets/assets/000/031/850/medium800/gps_other.jpg?1461188517)

 **FIX** &nbsp;is an output pin - it is the same pin as the one that drives the red LED. When there is no fix, the FIX pin is going to pulse up and down once every second. When there is a fix, the pin is low (0V) for most of the time, once every 15 seconds it will pulse high for 200 milliseconds

**PPS** is a new pin output on V3 modules. Its a "pulse per second" output. Most of the time it is at logic low (ground) and then it pulses high (3.3V) once a second, for 50-100ms, so it should be easy for a microcontroller to sync up to it

## Versions

If you purchased a module before March 26th, 2012 and it says MTK3329 on the silkscreen, you have the PA6B version of this breakout with the MT3329 chipset. The MTK3329 does not have built in datalogging. If your module has sharpie marker crossing out the MTK3329 text or there is no text, you have a PA6C MTK3339 with datalogging ability. If you have the version with "v3" next to the name, you have the PA6H which has PPS output and external-antenna support

# Adafruit Ultimate GPS

## Battery Backup

The GPS has a built in real time clock, which can keep track of time even when it power is lost and it doesn't have a fix yet. It can also help reduce fix times, if you expect to have a flakey power connection (say you're using solar or similar). To use the RTC, we need to attach a battery. There is a spot on the back for a&nbsp; **CR1220** &nbsp;sized battery holder. We provide the holder but the battery is not included. You can use any 12mm coin cell - these are popular and we also carry them in the Adafruit shop.

Normally, if the GPS loses power, it will revert to the factory default for baud rates, configuration, etc. A backup battery will mean that those defaults will not be lost!

The backup real-time-clock circuitry draws 7 uA (0.007 mA) so a CR1220 will last 40mAh / 0.007mA = 5,714 hours = 240 days continuously. The backup battery is only used when there's no main 3V power to the GPS, so as long as it's only used as backup once in a while, it will last years

![](https://cdn-learn.adafruit.com/assets/assets/000/001/385/medium800/gps_back.jpeg?1396771683)

## If you have a v1 or v2 module ONLY:
Before inserting a battery into the battery holder, first cut the trace between the two solder pads on the back, labeled RTC (this disconnects the VIN pin from the battery input) Use a multimeter with continuity checking to verify the two pads are no longer tied together.  
  
V3 modules do not have a trace to cut, they have a built-in diode!  
![](https://cdn-learn.adafruit.com/assets/assets/000/001/386/medium800/gps_tracecut.jpeg?1396771689)

Remember, the GPS does not know what time zone you are in (even though it knows your location, there is no easy way to determine time zone without a massive lookup table) so all date/time data is in UTC (aka. Greenwich Mean Time) - You will have to write the code that converts that to your local time zone and account for Daylight Savings if required! Since that's pretty complicated, most people just stick to keeping everything in UTC

# Adafruit Ultimate GPS

## External Antenna

## New in version 3 of the Ultimate GPS breakout, we now have support for optional external antennas!
This is not available in v1 or v2 so if you do not see the uFL connector, you have an older version of the module which cannot support antennas ![](https://cdn-learn.adafruit.com/assets/assets/000/001/851/medium800/gps_746antenna_LRG.jpg?1396776241)

All Ultimate GPS modules have a built in patch antenna - this antenna provides -165 dBm sensitivity and is perfect for many projects. However, if you want to place your project in a box, it might not be possible to have the antenna pointing up, or it might be in a metal shield, or you may need more sensitivity. In these cases, [you may want to use an external active antenna.](https://www.adafruit.com/products/960)  
  
[Active antennas draw current, so they do provide more gain but at a power cost. Check the antenna datasheet for exactly how much current they draw - its usually around 10-20mA.](https://www.adafruit.com/products/960 "Link: https://www.adafruit.com/products/960")  
  
Most GPS antennas use SMA connectors, which are popular and easy to use. However, an SMA connector would be fairly big on the GPS breakout so we went with a uFL connector - which is lightweight, small and easy to manufacture. If you don't need an external antenna it wont add significant weight or space but [its easy to attach a uFL-\>SMA adapter cable](http://www.adafruit.com/products/851). Then connect the GPS antenna to the cable.

Warning: 

The Ultimate GPS will automagically detect an external active antenna is attached and 'switch over' - you do not need to send any commands  
  
There is an output sentence that will tell you the status of the antenna. **$PGTOP,11,x** where **x** is the status number. If **x** is **3** that means it is using the external antenna. If **x** is **2** it's using the internal antenna and if **x** is **1** there was an antenna short or problem.  
  
On newer shields & modules, you'll need to tell the firmware you want to have this report output, you can do that by adding a **gps.sendCommand(PGCMD\_ANTENNA)** around the same time you set the update rate/sentence output.

![](https://cdn-learn.adafruit.com/assets/assets/000/001/852/medium800/gps_antennastatus.gif?1447864309)

# Adafruit Ultimate GPS

## Direct Computer Wiring

GPS modules are great in that the moment you turn them on, they'll start spitting out data, and trying to get a 'fix' (location verification). Like pretty much every GPS in existence, the Adafruit Ultimate GPS uses TTL serial output to send data so the best way to first test the GPS is to wire it directly to the computer via the TTL serial to USB converter on an Arduino. You can also use an FTDI Friend or other TTL adapter but for this demonstration we'll use a classic Arduino.

Danger: This tutorial step won't work with a chip that has NATIVE USB - it's for an Arduino UNO compatible only. Go on to the next step, [Breakout Arduino Wiring](https://learn.adafruit.com/adafruit-ultimate-gps/arduino-wiring), but refer back here for this discussion of the GPS data!

First, load a "blank" sketch into the Arduino:

```auto
// this sketch will allow you to bypass the Atmega chip
// and connect the Ultimate GPS directly to the USB/Serial
// chip converter.
 
// Connect VIN to +5V
// Connect GND to Ground
// Connect GPS RX (data into GPS) to Digital 0
// Connect GPS TX (data out from GPS) to Digital 1
 
void setup() {}
void loop() {}
```

This is will free up the converter so you can directly wire and bypass the Arduino chip. Once you've uploaded this sketch, wire the GPS as follows. Your module may look slightly different, but as long as you are connecting to the right pin names, they all work identically for this part.

Note that TX on the Arduino is connected to TX on the Ultimate GPS, and similarly for RX. **This is not the usual wiring,** which would have TX\<-\>RX and RX\<-\>TX. It is wired this way because you are using the separate USB-serial converter on the Arduino board directly, by using the "blank" sketch above.

Danger: Use the wiring below **only** for the "blank" sketch above, with an Arduino Uno compatible only. For regular use, use the wiring shown on the [Breakout Arduino Wiring](https://learn.adafruit.com/adafruit-ultimate-gps/arduino-wiring) page.

![](https://cdn-learn.adafruit.com/assets/assets/000/001/380/medium800/gps_directwire.jpeg?1396771648)

Now plug in the USB cable, and open up the serial monitor from the Arduino IDE and be sure to select&nbsp; **9600 baud** &nbsp;in the drop down. You should see text like the following:![](https://cdn-learn.adafruit.com/assets/assets/000/018/682/medium800/gps_nmea_data.png?1407363321)

This is the raw GPS "NMEA sentence" output from the module. There are a few different kinds of NMEA sentences, the most common ones people use are the&nbsp; **$GPRMC** &nbsp;( **G** lobal&nbsp; **P** ositioning&nbsp; **R** ecommended **M** inimum&nbsp; **C** oordinates or something like that) and the&nbsp; **$GPGGA** &nbsp;sentences. These two provide the time, date, latitude, longitude, altitude, estimated land speed, and fix type. Fix type indicates whether the GPS has locked onto the satellite data and received enough data to determine the location (2D fix) or location+altitude (3D fix).

[For more details about NMEA sentences and what data they contain, check out this site](http://aprs.gids.nl/nmea/)

If you look at the data in the above window, you can see that there are a lot of commas, with no data in between them. That's because this module is on my desk, indoors, and does not have a 'fix'. To get a fix, we need to put the module outside.

Danger: 

If you can get a really long USB cord (or attach a GPS antenna to the v3 modules) and stick the GPS out a window, so its pointing at the sky, eventually the GPS will get a fix and the window data will change over to transmit valid data like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/001/382/medium800/gps_fixed.gif?1447864280)

Look for the line that says&nbsp; **$GPRMC,194509.000,A,4042.6142,N,07400.4168,W,2.03,221.11,160412,,,A\*77** &nbsp;  
This line is called the RMC (Recommended Minimum) sentence and has pretty much all of the most useful data. Each chunk of data is separated by a comma.

The first part&nbsp; **194509.000** &nbsp;is the current time **GMT** (Greenwich Mean Time). The first two numbers **&nbsp;19&nbsp;** indicate the hour (1900h, otherwise known as 7pm) the next two are the minute, the next two are the seconds and finally the milliseconds. So the time when this screenshot was taken is 7:45 pm and 9 seconds. The GPS does not know what time zone you are in, or about "daylight savings" so you will have to do the calculation to turn GMT into your timezone

The second part is the 'status code', if it is a&nbsp; **V** &nbsp;that means the data is&nbsp; **V** oid (invalid). If it is an&nbsp; **A** &nbsp;that means its&nbsp; **A** ctive (the GPS could get a lock/fix)

The next 4 pieces of data are the geolocation data. According to the GPS, my location is **&nbsp;4042.6142,N**** &nbsp;**(Latitude 40 degrees, 42.6142 decimal minutes North) &&nbsp;**07400.4168,W**. (Longitude 74 degrees, 0.4168 decimal minutes West) To look at this location in Google maps, type&nbsp;**+40&nbsp; 42.6142', -74&nbsp; 00.4168'**&nbsp;into the&nbsp;[google maps search box](http://maps.google.com/)&nbsp;. Unfortunately gmaps requires you to use +/- instead of NSWE notation. N and E are positive, S and W are negative.

Danger: 

The next data is the ground speed in knots. We're going&nbsp; **2.03** &nbsp;knots

After that is the tracking angle, this is meant to approximate what 'compass' direction we're heading at based on our past travel

The one after that is&nbsp; **160412** &nbsp;which is the current date (16th of April, 2012).

Finally there is the&nbsp; **\*XX** &nbsp;data which is used as a data transfer checksum

Once you get a fix using your GPS module, verify your location with google maps (or some other mapping software). Remember that GPS is often only accurate to 5-10 meters and worse if you're indoors or surrounded by tall buildings.

# Adafruit Ultimate GPS

## Breakout Arduino Wiring

Once you've gotten the GPS module tested with direct wiring, we can go forward and wire it up to a microcontroller. We'll be using an Arduino but you can adapt our code to any other microcontroller that can receive TTL serial at 9600 baud.

## Software Serial Boards
For an Arduino compatible, or any board that does not have an extra `HardwareSerial` port, we'll use `SoftwareSerial`. The examples in the **Adafruit\_GPS Arduino** library use pin 8 for Serial RX and pin 7 for Serial TX _on the Arduino-compatible board_. The constructor call in the example sketches is `SoftwareSerial(8, 7);`.

Connect **VIN** to +5V (or whatever the logic level is of your board), **GND** &nbsp;to Ground,&nbsp; **RX** to digital 7 and&nbsp; **TX** to digital 8. Note that the Arduino-compatible **TX** is connected to the GPS **RX** , and the Arduino-compatible **RX** is connected to the GPS **TX**.

![adafruit_products_gps_ss_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/099/285/medium640/adafruit_products_gps_ss_bb.png?1612729070)

## Hardware Serial Boards
If you're using a board with hardware serial support, like this Feather M0, wire up **VIN** to 3.3V (since that is the logic level of the Feather M0), **GND** to ground, and **GPS RX** to Feather TX and **GPS TX** to Feather RX.

![adafruit_products_gps_hs_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/112/153/medium640/adafruit_products_gps_hs_bb.png?1654002549)

Next up, download the Adafruit GPS library. This library does a lot of the 'heavy lifting' required for receiving data from GPS modules, such as reading the streaming data in a background interrupt and auto-magically parsing it. [You can check the code by visiting the GitHub repository](https://github.com/adafruit/Adafruit-GPS-Library "Link: https://github.com/adafruit/Adafruit-GPS-Library")

To install, open the Arduino library manager

![](https://cdn-learn.adafruit.com/assets/assets/000/099/281/medium800/adafruit_products_image.png?1612726778)

Search for **Adafruit GPS** and click **Install**

![](https://cdn-learn.adafruit.com/assets/assets/000/099/282/medium800/adafruit_products_image.png?1612726876)

Library installation is a frequent stumbling block…if you need assistance, our [All About Arduino Libraries](../../../../adafruit-all-about-arduino-libraries-install-use)&nbsp;guide spells it out in detail!

## Arduino UNO or other SoftwareSerial boards

If your microcontrollers _doesn't_ have a Hardware Serial interface available - say you're using an Arduino UNO or compatible, load up the `SoftwareSerial_echotest` example:

![](https://cdn-learn.adafruit.com/assets/assets/000/099/283/medium800/adafruit_products_image.png?1612726964)

## Leonardo/M0/M4/ESP32 and other Hardware Serial Boards

If you have a board with a spare Hardware Serial interface (which many boards other than the original Arduino UNO compatibles have) - we recommend using that since hardware serial will always give less errors and better performance than software serial!

We assume you'll be using `Serial1` - check your board documentation to figure out which pins that is!

![](https://cdn-learn.adafruit.com/assets/assets/000/099/284/medium800/adafruit_products_image.png?1612727196)

## Upload and Check Output

Whichever version you decide to use, upload the sketch to the microcontroller. Then open up the serial monitor. This sketch simply reads data from the software serial or hardware serial port and outputs that to USB.

Open up the Arduino IDE Serial Console and make sure to set the Serial baud rate to **115200**

![](https://cdn-learn.adafruit.com/assets/assets/000/099/286/medium800/adafruit_products_image.png?1612729336)

You can configure the GPS output you see by commenting/uncommenting lines in the **setup()** procedure. For example, we can ask the GPS to send different sentences, and change how often it sends data. 10 Hz (10 times a second) is the max speed, and is a lot of data. You may not be able to output "all data" at that speed because the 9600 baud rate is not fast enough.

```auto
// You can adjust which sentences to have the module emit, below
 
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data for high update rates!
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // uncomment this line to turn on all the available data - for 9600 baud you'll want 1 Hz rate
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_ALLDATA);
 
  // Set the update rate
  // 1 Hz update rate
  //GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  // 5 Hz update rate- for 9600 baud you'll have to set the output to RMC or RMCGGA only (see above)
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ);
  // 10 Hz update rate - for 9600 baud you'll have to set the output to RMC only (see above)
  //GPS.sendCommand(PMTK_SET_NMEA_UPDATE_10HZ);
```

In general, we find that most projects only need the RMC and GGA NMEA's so you don't need ALLDATA unless you have some need to know satellite locations.# Adafruit Ultimate GPS

## Breakout Arduino Parsing

Since all GPS's output NMEA sentences and often for our projects we need to extract the actual data from them, we've simplified the task tremendously when using the Adafruit GPS library. By having the library read, store and parse the data in a background interrupt it becomes trivial to query the library and get the latest updated information without any icky parsing work.

Open up the&nbsp; **File→Examples→Adafruit\_GPS→GPS\_HardwareSerial\_Parsing** or **GPS\_SoftwareSerial\_Parsing** sketch and upload it to the microcontroller. Use the same wiring as in the previous page. Then open up the serial monitor.

![](https://cdn-learn.adafruit.com/assets/assets/000/001/384/medium800/gps_parsed.gif?1447864284)

Info: 

In this sketch, we call**&nbsp;GPS.read()** constantly in the main loop (if you can, get this to run once a millisecond in an interrupt). Then in the main loop we can ask if a new chunk of data has been received by calling&nbsp;**GPS.newNMEAreceived()**, if this returns&nbsp; **true** &nbsp;then we can ask the library to parse that data with&nbsp;**GPS.parse(GPS.lastNMEA())**.

We do have to keep querying and parsing in the main loop - its not possible to do this in an interrupt because then we'd be dropping GPS data by accident.

Once data is parsed, we can just ask for data from the library like **&nbsp;GPS.day** ,&nbsp; **GPS.month** &nbsp;and&nbsp; **GPS.year** &nbsp;for the current date.&nbsp; **GPS.fix&nbsp;** will be 1 if there is a fix, 0 if there is none. If we have a fix then we can ask for&nbsp; **GPS.latitude** , **&nbsp;GPS.longitude** ,&nbsp; **GPS.speed** &nbsp;(in knots, not mph or k/hr!),&nbsp; **GPS.angle** , **&nbsp;GPS.altitude** &nbsp;(in centimeters) and&nbsp; **GPS.satellites&nbsp;** (number of satellites)

This should make it much easier to have location-based projects. We suggest keeping the update rate at 1Hz and request that the GPS only output RMC and GGA as the parser does not keep track of other data anyways.

# Adafruit Ultimate GPS

## CircuitPython & Python Setup

You can easily use a GPS module with Python or CircuitPython code in addition to Arduino.&nbsp; Python code is well suited for parsing and processing the text output from GPS modules, and this [Adafruit CircuitPython GPS](https://github.com/adafruit/Adafruit_CircuitPython_GPS)&nbsp;module handles most of the work for you!

# CircuitPython MicroController Wiring
First make sure to wire up the GPS module to your CircuitPython board so that the hardware UART pins are used.&nbsp; Here's an example with the Metro M0 Express:

- **Board 5V** or **3.3V** to **GPS module VIN**.
- **Board GND** to **GPS module GND**.
- **Board serial TX** to **GPS module RX**.
- **Board serial RX** to **GPS module TX**.

![adafruit_products_m0_express_gps_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/076/818/medium640/adafruit_products_m0_express_gps_bb.png?1560221862)

# Python Computer Wiring
Since there's _dozens_ of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms, [please visit the guide for CircuitPython on Linux to see whether your platform is supported](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux).

Here you have two options: An external USB-to-serial converter, or the built-in UART on the Pi's TX/RX pins. Here's an example of wiring up the [USB-to-serial converter](https://www.adafruit.com/product/954):

- **GPS Vin** &nbsp; to **USB**  **5V** or **3V** (red wire on USB console cable)
- **GPS Ground** to **USB Ground** (black wire)
- **GPS RX** to **USB TX** (green wire)
- **GPS TX** to **USB RX** (white wire)

![adafruit_products_sensors_usbgps_bb_narrow.png](https://cdn-learn.adafruit.com/assets/assets/000/062/854/medium640/adafruit_products_sensors_usbgps_bb_narrow.png?1538431002)

Warning: 

You can also skip the USB console cable, and just plug a USB C or Micro B cable directly from your computer to the **Ultimate GPS USB**

![adafruit_products_UGPS_USB_C.jpg](https://cdn-learn.adafruit.com/assets/assets/000/109/804/medium640/adafruit_products_UGPS_USB_C.jpg?1647549840)

![adafruit_products_UGPS_USB_micro_B.jpg](https://cdn-learn.adafruit.com/assets/assets/000/109/805/medium640/adafruit_products_UGPS_USB_micro_B.jpg?1647549888)

Here's an example using the Pi's built-in UART:

- **GPS Vin** &nbsp; to **3.**** 3V** (red wire)
- **GPS Ground** to **Ground** (black wire)
- **GPS RX** to **TX** (green wire)
- **GPS TX** to **RX** (white wire)

![adafruit_products_sensors_uartgps_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/062/852/medium640/adafruit_products_sensors_uartgps_bb.png?1538430197)

If you want to use the built-in UART, you'll need to disable the serial console and enable the serial port hardware in **raspi-config**. See [the UART/Serial section of the CircuitPython on Raspberry Pi guide](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/uart-serial) for detailed instructions on how to do this.

# CircuitPython Installation of GPS Library
Next you'll&nbsp;need to install the&nbsp;[Adafruit CircuitPython GPS](https://github.com/adafruit/Adafruit_CircuitPython_GPS)&nbsp;library on your CircuitPython board.&nbsp;&nbsp; **Remember this module is for Adafruit CircuitPython firmware and not MicroPython.org firmware!**

First make sure you are running the&nbsp;[latest version of Adafruit CircuitPython](https://github.com/adafruit/circuitpython/releases)&nbsp;for your board.

Next you'll need to install the necessary libraries to use the hardware. Carefully follow [the steps to find and install this library](https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries) from [Adafruit's CircuitPython library bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle).

- **adafruit\_gps.mpy**

You can also download the&nbsp; **adafruit\_gps.mpy** &nbsp;file from the&nbsp;[Adafruit CircuitPython GPS releases page](https://github.com/adafruit/Adafruit_CircuitPython_GPS/releases).

Before continuing make sure your board's **lib** folder has the **adafruit\_gps.mpy** file copied over.

# Python Installation of GPS Library
You'll need to install the **Adafruit\_Blinka** library that provides the CircuitPython support in Python. This may require verifying you are running Python 3. [Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux)!

Once that's done, from your command line run the following command:

```auto
sudo pip3 install adafruit-circuitpython-gps
```

# Adafruit Ultimate GPS

## CircuitPython & Python UART Usage

To demonstrate the usage of the GPS module in CircuitPython using UART, let's look at a complete program example, the **gps\_simpletest.py** file from the module's examples.

### CircuitPython Microcontroller

With a CircuitPython microcontroller, save this file as&nbsp; **code.py** on your board, then open the serial console to see its output.

### Linux/Computer/Raspberry Pi with Python
Warning: If you're running **gps_simpletest.py** on the Raspberry Pi (or any computer), you'll have to make some changes.

On the Raspberry Pi, comment out the `uart = busio(...)` line, and uncomment the `import serial` and `uart = serial.Serial(...)` lines, changing `/dev/ttyUSB0` to the appropriate serial port (the one that shows up when you plug in the GPS via USB).&nbsp; Now you can run the program with the following command:

```auto
python3 gps_simpletest.py
```

# Example Parsing Code
https://github.com/adafruit/Adafruit_CircuitPython_GPS/blob/main/examples/gps_simpletest.py

When the code runs it will print a message every second, either an update that it's still waiting for a GPS fix:

![](https://cdn-learn.adafruit.com/assets/assets/000/048/072/medium800/gps_Screen_Shot_2017-11-08_at_11.06.45_AM.png?1510170120)

 **Note:** Due to the antenna being built in, the PA1010D Mini GPS module may need a more unobstructed view of the sky than other GPS modules with eternal antennae. With any GPS module, if you are having trouble getting a fix, try moving it to a more ideal location.

Once a fix has been established, it will print details about the current location and other GPS data:

![](https://cdn-learn.adafruit.com/assets/assets/000/048/073/medium800/gps_Screen_Shot_2017-11-08_at_11.27.59_AM.png?1510170140)

Let's look at the code in a bit more detail to understand how it works.&nbsp; First the example needs to import a few modules like the built-in&nbsp;`busio`&nbsp;and&nbsp;`board`&nbsp;modules that access serial ports and other hardware:

```auto
import board
import busio
import time
```

Next the GPS module is imported:

```auto
import adafruit_gps
```

Now a&nbsp;[serial UART](http://circuitpython.readthedocs.io/en/latest/shared-bindings/busio/UART.html)&nbsp;is created and connected to the serial port pins the GPS module will use, this is the low level transport layer to communicate with the GPS module:

```auto
# Define RX and TX pins for the board's serial port connected to the GPS.
# These are the defaults you should use for the GPS FeatherWing.
# For other boards set RX = GPS module TX, and TX = GPS module RX pins.
RX = board.RX
TX = board.TX
 
# Create a serial connection for the GPS connection using default speed and
# a slightly higher timeout (GPS modules typically update once a second).
uart = busio.UART(TX, RX, baudrate=9600, timeout=3000)

# for a computer, use the pyserial library for uart access
#import serial
#uart = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=3000)
```

Once a `UART` object is available with a connected GPS module you can create an instance of the GPS parsing class. You need to pass this class the `UART` instance and it will internally read new data from the GPS module connected to it:

```auto
gps = adafruit_gps.GPS(uart)
```

# GPS Example Code Explained

Before reading GPS data the example configures the module by sending some&nbsp;[custom NMEA GPS commands](https://cdn-shop.adafruit.com/datasheets/PMTK_A11.pdf)&nbsp;that adjust the amount and rate of data.&nbsp; Read the comments to see some options for adjust the rate and amount of data, but typically you want the defaults of core location info at a rate of once a second:

```auto
# Initialize the GPS module by changing what data it sends and at what rate.
# These are NMEA extensions for PMTK_314_SET_NMEA_OUTPUT and
# PMTK_220_SET_NMEA_UPDATERATE but you can send anything from here to adjust
# the GPS module behavior:
#   https://cdn-shop.adafruit.com/datasheets/PMTK_A11.pdf
 
# Turn on the basic GGA and RMC info (what you typically want)
gps.send_command(b'PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn on just minimum info (RMC only, location):
#gps.send_command(b'PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn off everything:
#gps.send_command(b'PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn on everything (not all of it is parsed!)
#gps.send_command(b'PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0')
 
# Set update rate to once a second (1hz) which is what you typically want.
gps.send_command(b'PMTK220,1000')
# Or decrease to once every two seconds by doubling the millisecond value.
# Be sure to also increase your UART timeout above!
#gps.send_command(b'PMTK220,2000')
# You can also speed up the rate, but don't go too fast or else you can lose
# data during parsing.  This would be twice a second (2hz, 500ms delay):
#gps.send_command(b'PMTK220,500')
```

If you want you can send other custom commands to the GPS module with the&nbsp;`send_command` function shown above. You don't need to worry about adding a NMEA checksum to your command either, the function will do this automatically (or not, set `add_checksum=False`&nbsp;as a parameter and it will skip the checksum addition).&nbsp;

Now we can jump into a main loop that continually updates data from the GPS module and prints out status. The most important part of this loop is calling the GPS update function:

```auto
    # Make sure to call gps.update() every loop iteration and at least twice
    # as fast as data comes from the GPS unit (usually every second).
    # This returns a bool that's true if it parsed new data (you can ignore it
    # though if you don't care and instead look at the has_fix property).
    gps.update()
```

Like the comments mention, you must call `update` every loop iteration and ideally multiple times a second.&nbsp; Each time you call `update`, it allows the GPS library code to read new data from the GPS module and update its state.&nbsp; Since the GPS module is always sending data you have to be careful to constantly read data or else you might start to lose data as buffers are filled.

You can check the&nbsp;`has_fix`&nbsp;property to see if the module has a GPS location fix, and if so there are a host of attributes to read like&nbsp;`latitude`&nbsp;and&nbsp;`longitude`&nbsp;(available in degrees):

```auto
        if not gps.has_fix:
            # Try again if we don't have a fix yet.
            print('Waiting for fix...')
            continue
        # We have a fix! (gps.has_fix is true)
        # Print out details about the fix like location, date, etc.
        print('=' * 40)  # Print a separator line.
        print('Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}'.format(
                gps.timestamp_utc.tm_mon,   # Grab parts of the time from the
                gps.timestamp_utc.tm_mday,  # struct_time object that holds
                gps.timestamp_utc.tm_year,  # the fix time.  Note you might
                gps.timestamp_utc.tm_hour,  # not get all data like year, day,
                gps.timestamp_utc.tm_min,   # month!
                gps.timestamp_utc.tm_sec))
        print('Latitude: {} degrees'.format(gps.latitude))
        print('Longitude: {} degrees'.format(gps.longitude))
        print('Fix quality: {}'.format(gps.fix_quality))
        # Some attributes beyond latitude, longitude and timestamp are optional
        # and might not be present.  Check if they're None before trying to use!
        if gps.satellites is not None:
            print('# satellites: {}'.format(gps.satellites))
        if gps.altitude_m is not None:
            print('Altitude: {} meters'.format(gps.altitude_m))
        if gps.track_angle_deg is not None:
            print('Speed: {} knots'.format(gps.speed_knots))
        if gps.track_angle_deg is not None:
            print('Track angle: {} degrees'.format(gps.track_angle_deg))
        if gps.horizontal_dilution is not None:
            print('Horizontal dilution: {}'.format(gps.horizontal_dilution))
        if gps.height_geoid is not None:
```

Notice some of the attributes like&nbsp;`altitude_m`&nbsp;are checked to be `None` before reading.&nbsp; This is a smart check to put in your code, because those attributes are sometimes not sent by a GPS module.&nbsp; If an attribute isn't sent by the module it will be given a `None`/null value and attempting to print or read it in Python will fail.&nbsp; The core attributes of `latitude`,&nbsp;`longitude`, and&nbsp;`timestamp`&nbsp;are usually always available (if you're using the example as-is) but they might not be if you turn off those outputs with a custom NMEA command!

That's all there is to reading GPS location with CircuitPython code!

# Adafruit Ultimate GPS

## CircuitPython Datalogging

# Datalogging Example

Another handy task with GPS is logging all the raw output of the GPS module to a file.&nbsp; This is useful if you're importing the GPS data into a tool like Google Earth which can process raw NMEA sentences.&nbsp; You can perform this datalogging very easily with CircuitPython.

To store data you'll need to choose one of two options:

- Wire up a SD card holder to your board's SPI bus, or use a board with SD card holder built-in like the&nbsp;[Feather M0 Adalogger](https://www.adafruit.com/product/2796).&nbsp;&nbsp; **This is the recommended approach** &nbsp;as it gives you a lot of space to store data and you can easily copy the data to your computer from the card.
- Store data in your board's internal filesystem.&nbsp; This requires a little more setup but allows you to save to a file on the internal filesystem of your CircuitPython board, right next to where code and other data files live.&nbsp; This is more limited because depending on your board you might only have a few kilobytes or megabytes of space available and GPS sentences will quickly add up (easily filling multiple megabytes within a few hours of logging).

## Install SD Card Library

If you're storing data on a SD card you must ensure the SD card is wired to your board and you have installed the Adafruit SD card library.&nbsp; Luckily there's&nbsp;[an entire guide to follow to learn about this process of connecting a SD card and installing the necessary library](../../../../micropython-hardware-sd-cards/tdicola-overview).&nbsp; Be sure to carefully follow the guide so the card is connected, library installed, and you can confirm you're able to manually write data to the card from the Python prompt.

## Enable Internal Filesystem Writes

If you're storing data on the internal filesystem you&nbsp; **must** &nbsp;carefully&nbsp;[follow the steps in the CPU temperature logging guide to enable writing to internal storage](../../../../cpu-temperature-logging-with-circuit-python/writing-to-the-filesystem).&nbsp;&nbsp; **If you're writing to a SD card skip these steps and move on to look at the datalogging code below.** &nbsp; Edit the&nbsp; **boot.py** &nbsp;on your board (creating it if it doesn't exist) and add these lines:

```python
import digitalio
import board
import storage
 
switch = digitalio.DigitalInOut(board.D5)
switch.direction = digitalio.Direction.INPUT
switch.pull = digitalio.Pull.UP
 
# If the D5 is connected to ground with a wire
# you can edit files over the USB drive again.
storage.remount("/", not switch.value)
```

Remember once you remount("/")&nbsp; **you cannot edit code over the USB drive anymore!** &nbsp; That means you can't edit&nbsp; **boot.py** &nbsp;which is a bit of a conundrum. So we configure the&nbsp; **boot.py** &nbsp;to selectively mount the internal filesystem as writable based on a switch or even just alligator clip connected to ground.&nbsp; Like the&nbsp;[CPU temperature guide shows](../../../../cpu-temperature-logging-with-circuit-python/writing-to-the-filesystem#selectively-setting-readonly-to-false-on-boot)&nbsp;. In this example we're using&nbsp; **D5** &nbsp;but select any available pin.

This code will look at the D5 digital input when the board starts up and if it's connected to ground (use an alligator clip or wire, for example, to connect from D5 to board ground) it will disable internal filesystem writes and allow you to edit code over the USB drive as normal.&nbsp; Remove the alligator clip, reset the board, and the&nbsp; **boot.py** &nbsp;will switch to mounting the internal filesystem as writable so you can log images to it again (but not write any code!).&nbsp;

Remember when you enable USB drive writes (by connecting D5 to ground at startup) you&nbsp; **cannot write files** &nbsp;to the internal filesystem and any code in your&nbsp; **main.py** &nbsp;that attempts to do so (like the example below) will fail.&nbsp; Keep this in mind as you&nbsp;edit code--once you modify&nbsp;code you need to remove the alligator clip, reset the board to re-enable&nbsp;internal filesystem writes, and then watch the output of your program.

Danger: 

## Datalogging Example Code

The GPS library examples have a&nbsp; **datalogging.py** &nbsp;file you can edit and save as a&nbsp; **code.py** &nbsp;on your board:

https://github.com/adafruit/Adafruit_CircuitPython_GPS/blob/main/examples/gps_datalogging.py

By default this example expects to log GPS NMEA sentences to a file on the internal storage system at&nbsp; **/gps.txt**.&nbsp; New sentences will be appended to the end of the file every time the example starts running.

If you'd like to instead write to the SD card take note to uncomment&nbsp;the appropriate lines mentioned in the comments:

```auto
# Path to the file to log GPS data.  By default this will be appended to
# which means new lines are added at the end and all old data is kept.
# Change this path to point at internal storage (like '/gps.txt') or SD
# card mounted storage ('/sd/gps.txt') as desired.
#LOG_FILE = '/gps.txt'  # Example for writing to internal path /gps.txt
LOG_FILE = '/sd/gps.txt'     # Example for writing to SD card path /sd/gps.txt
```

And further below:

Should all be uncommented and look as above.&nbsp; This will configure the code to write GPS NMEA data to the&nbsp; **/sd/gps.txt** &nbsp;file, appending new data to the end of the file.

Once the example is running as a&nbsp; **main.py** &nbsp;on your board open the serial REPL and you should see the raw NMEA sentences printed out:

![](https://cdn-learn.adafruit.com/assets/assets/000/048/212/medium800/gps_Screen_Shot_2017-11-14_at_3.40.14_PM.png?1510704360)

Check the&nbsp; **gps.txt** &nbsp;file (either under the root or /sd path depending on how you setup the example) in a text editor and you'll see the same raw NMEA sentences:

![](https://cdn-learn.adafruit.com/assets/assets/000/048/213/medium800/gps_Screen_Shot_2017-11-14_at_3.40.39_PM.png?1510704380)

Awesome!&nbsp; That's all there is to basic datalogging of NMEA sentences with a GPS module and CircuitPython!

# Adafruit Ultimate GPS

## Python Docs

# Adafruit Ultimate GPS

## Built In Logging

One of the nice things about the MTK3339 is the built in data-logger. This basic data-logging capability can store date, time, latitude, longitude and altitude data into a 64K flash chip inside. Its not a high resolution logger - it only logs once every 15 seconds when there is a fix - but for 99% of projects that want to track location, this can be a great low power way to log data - no SD card or other EEPROM required! It can store up to 16 hours of data.

The GPS module does require a microcontroller to 'kick start' the logger by requesting it to start. If power is lost it will require another 'kick' to start. If you already have some data in the FLASH, a new trace will be created (so you wont lose old data) and if you run out of space it will simply halt and not overwrite old data. Despite this annoyance, its still a very nice extra and we have some library support to help you use it

For more details check out the [LOCUS (built-in-datalogging system) user guide](http://www.adafruit.com/datasheets/GTop%20LOCUS%20Library%20User%20Manual-v13.pdf)

First, we should try getting the logger to run.Open up the **File→Examples→Adafruit\_GPS→locus\_start** sketch. This will demonstrate how to start the logger (called LOCUS)

The key part is here:

```auto
Serial.print("STARTING LOGGING....");
  if (GPS.LOCUS_StartLogger())
    Serial.println(" STARTED!");
  else
    Serial.println(" no response :(");
  delay(1000);
```

You should start the logger and then check the response:![](https://cdn-learn.adafruit.com/assets/assets/000/001/387/medium800/gps_logstart.gif?1447864284)

# Logging Status
  
Once you've seen that the GPS is OK with logging, you can load up the status sketch which will also give you more data. Upload&nbsp; **File→Examples→Adafruit\_GPS→locus\_status** ![](https://cdn-learn.adafruit.com/assets/assets/000/001/388/medium800/gps_LOCUS-status.gif?1447864285)

This output gives you some more information. the first entry is the Log #. This is how many log traces are in the memory. Every time you start and save data, a new log is made. Full Stop means that once the logger has run out of memory it will stop. Next the output indicates that we are logging only during fix data and at set intervals, with an interval delay of 15 seconds. We are not logging based on distance or speed. The current status is LOGGING (active), there's also the number of records we've stored. Each record is a timestamped location. We log once every 15 seconds, you can see the records increment from 344 to 345 here. Lastly, we can see how much of the internal flash storage is used, only 4% at this point

In real use, you'll probably want to start the loggging and then have your microcontroller go to sleep to reserve power, waking up once in a while to check up on the logging status.

# Downloading Data

Finally, once we're done logging we need to extract the data. To do this we need to first get the raw data out of the FLASH and then decode the sentences. Upload **File→Examples→Adafruit\_GPS→locus\_dump&nbsp;** to the Arduino and open up the serial monitor

Danger: 

![](https://cdn-learn.adafruit.com/assets/assets/000/001/389/medium800/gps_logdump.gif?1447864285)

Copy and paste all the text after the —-'s (starting with **$PMTKLOX,0,86\*67** and ending with **$PMTK001,622,3\*36** ) [then paste it into the box located on this page](http://learn.adafruit.com/custom/ultimate-gps-parser)

OR

[you can try this python tool that don has kindly donated](https://github.com/don/locus) to the community!

# Using the GPS Tool

If you are having difficulty with the Arduino/javascript tool, you can also try using the GPS tool. The tool runs only under Windows but it is very powerful.  
  
Connect the GPS module to an Arduino [(connected with the Direct Wiring example)](http://learn.adafruit.com/adafruit-ultimate-gps/direct-computer-wiring) , FTDI adapter or other TTL converter and download the [GPS Tool](../../../../adafruit-ultimate-gps/downloads) - connect to the GPS via the COM port of the Arduino/FTDI/TTL cable. You can then query, dump and delete the log memory

# Adafruit Ultimate GPS

## LOCUS Parser

# Adafruit Ultimate GPS

## Resources

# Datasheets

- [MTK3329/MTK3339 command set sheet](http://www.adafruit.com/datasheets/PMTK_A11.pdf) for changing the fix data rate, baud rate, sentence outputs, etc!
- [PMTK 'complete' data](http://www.adafruit.com/datasheets/PMTK%20command%20packet-Complete-C39-A01.pdf)sheet (like the above but with even more commands)
- [Datasheet for the PA6B (MTK3329) GPS module itself](http://www.adafruit.com/datasheets/PA6B-Datasheet-A07.pdf)
- [Datasheet for the PA6C (MTK3339) GPS module itself](http://www.adafruit.com/datasheets/GlobalTop-FGPMMOPA6C-Datasheet-V0A-Preliminary.pdf)
- [Datasheet for the PA6H (MTK3339) GPS module itself](http://www.adafruit.com/datasheets/GlobalTop-FGPMMOPA6H-Datasheet-V0A.pdf)
- [MT3339 GPS PC Tool (windows only)](http://www.adafruit.com/datasheets/GlobalTop%20MT3339%20PC%20Tool%20v1.3%20without%20F2.0&I3.1.rar) and the [PC Tool manual](http://www.adafruit.com/datasheets/GlobalTop%20MT3339%20PC%20Tool%20Operation%20Manual%20v1.1.pdf)
- [Sample code and spec sheet for the LOCUS built-in logger](http://www.adafruit.com/datasheets/Locus_Sample_Code.zip)
- [LOCUS (built-in-datalogging system) user guide](http://www.adafruit.com/datasheets/GTop%20LOCUS%20Library%20User%20Manual-v13.pdf)
- [Mini GPS tool (windows only)](http://www.adafruit.com/datasheets/MiniGPS_Tool_1.7.1.zip)

# More reading:

- [Trimble's GPS tutorial](http://www.trimble.com/gps_tutorial/)
- [Garmin's GPS tutorial](http://www8.garmin.com/aboutGPS/)

# Adafruit GPS Library for Arduino

[https://github.com/adafruit/Adafruit-GPS-Library/](https://github.com/adafruit/Adafruit-GPS-Library/)

# EPO files for AGPS use

[Data format for EPO files](http://www.adafruit.com/datasheets/GTop%20EPO%20Format%20and%20Protocol-v14.pdf)

[MTK_EPO_Nov_12_2014.zip](https://learn.adafruit.com/system/assets/assets/000/021/226/original/MTK_EPO_Nov_12_2014.zip?1415819755)
# Adafruit Ultimate GPS

## F.A.Q.

### 

Modules shipped in 2013+ (and many in the later half of 2012) have firmware that has been tested by simulation at the GPS factory at 40km.   
  
You can tell what firmware you have by sending the firmware query command **$PMTK605\*31** (you can use the echo demo to send custom sentences to your GPS)  
  
If your module replies with **AXN\_2.10\_3339\_2012072601 5223** that means you have version #5223 which is the 40Km-supported firmware version. If the number is higher then 5223 then its even more recent, and should include the 40Km support as well  
  
**HOWEVER** these modules are not specifically designed for high-altitude balloon use. People have used them successfully but since we (at Adafruit) have not personally tested them for hi-alt use, we do not in any way guarantee they are suitable for high altitude use.

**Please do not ask us to 'prove' that they are good for high altitude use, we do not have any way to do so**

**If you want to measure high altitude with a GPS, please find a module that can promise/guarantee high altitude functionality**

### 

The ultimate GPS (all firmware versions from **20110922\_GTOP\_EVK01\_A2.10** and higher - any sold after 2011) have been tested to work fine through 2019.

They do not pass the 2038 rollover test, so you may need to update the firmware between now and 2038. This does not affect the 2019 rollover (there's one every ~20 years)

### 

[Here is the binary of the 5632 firmware](http://www.adafruit.com/downloads/AXN2.31_5632_3339_96.1151100.1.bin), you can [use this tool to upload it using an FTDI or USB-TTL cable (or direct wiring with FTDI)](http://www.adafruit.com/downloads/MT3339%20FlashTool%20v122%20for%20Customer.rar). We do not have a tutorial for updating the firmware, if you update the firmware and somehow brick the GPS, we do not offer replacements! Keep this in mind before performing the update process!

### 

We use SoftwareSerial to read from the GPS, which is 'bitbang' UART support. It isn't super great on the Arduino and does work but adding too many delay()s and not calling the GPS data parser enough will cause it to choke on data.   
  
If you are using Leonardo (or Micro/Flora/ATmega32u4) or Mega, consider using a HardwareSerial port instead of SoftwareSerial!

### 

People often get confused because the GPS is working but is "5 miles off" - this is because they are not parsing the lat/long data correctly. Despite appearances, the geolocation data is NOT in decimal degrees. It is in degrees and minutes in the following format: Latitude: DDMM.MMMM (The first two characters are the degrees.) Longitude: DDDMM.MMMM (The first three characters are the degrees.)

### 

The default baud rate to the GPS is 9600 - this can only do RMC messages at 10Hz. If you want more data output, you can increase the GPS baud rate (to 57600 for example) or go with something like 2 or 5Hz. There is a trade off with more data you want the GPS to output, the GPS baud rate, Arduino buffer/processing capability and update rate!   
  
Experimentation may be necessary to get the optimal results. We suggest RMC only for 10Hz since we've tested it.

### 

The real time clock in the GPS is NOT 'writable' or accessable otherwise from the Arduino. Its in the GPS only! Once the battery is installed, and the GPS gets its first data reception from satellites it will set the internal RTC. Then as long as the battery is installed, you can read the time from the GPS as normal. Even without a proper "gps fix" the time will be correct.  
  
The timezone cannot be changed, so you'll have to calculate local time based on UTC!

### 

Under ideal conditions, GPS modules emit a PPS signal within 10ns of the beginning of each GPS second. That's only a best-case value though.

In practice, each GPS module's sync to the GPS clock system depends on the quality of the fix, how long the GPS module has had a fix, and the group of satellites the module uses for its fix. We've observed offsets of about 300ns between modules that have just acquired a fix, improving to less than 100ns after the modules have had a good fix (Signal-to-Noise ratio higher than 20 for the satellites the modules use for their fix) for ten minutes.

When two GPS modules used the same group of satellites for their fix, there was less than 30ns of offset between PPS pulses as soon as the modules acquired a fix.

### 

The PPS pin only starts outputting after a **3D fix**. In our testing, it truly wants a 3D fix, not just a 2D fix. Therefore, the PPS output may not happen even though the FIX LED and pin are indicating a fix.

You can check the current mode via the **$GPGSA** sentence. The second value must be a **3** , as shown below:

$GPGSA,A, **3** ,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3\*35

If the value is a **1** (Fix not available) or a **2** (2D), **then the PPS pin may not output**.

### 

The PPS line is tied to the serial port **RI** (Ring Indicator) pin. You can read this with your serial-port interface code. for example here's a version in Python using pyserial:

```
import serial

ser = serial.Serial('/dev/ttyS34') # open serial port
print(ser.name) # check which port was really used

last_ri = ser.ri
while True:
    if ser.ri != last_ri:
        last_ri = ser.ri
        if last_ri:
            print("\n---------- Pulse high ----------")
        else:
            print("\n---------- Pulse low ----------")
    if ser.in_waiting:
        print(ser.read(ser.in_waiting).decode('utf-8'), end="")
```
# Adafruit Ultimate GPS

## Downloads

# Files

- [MTK3329/MTK3339 command set sheet](https://cdn-shop.adafruit.com/datasheets/PMTK_A11.pdf) for changing the fix data rate, baud rate, sentence outputs, etc!
- [LOCUS (built-in-datalogging system) user guide](https://cdn-shop.adafruit.com/datasheets/GTop%20LOCUS%20Library%20User%20Manual-v13.pdf)
- [Datasheet for the PA6B (MTK3329) GPS module itself - used in version 1 of this module](https://cdn-shop.adafruit.com/datasheets/PA6B-Datasheet-A07.pdf)
- [Datasheet for the PA6C (MTK3339) GPS module itself - used in version 2 of this module](https://cdn-shop.adafruit.com/datasheets/GlobalTop-FGPMMOPA6C-Datasheet-V0A-Preliminary.pdf)
- [Datasheet for the PA6H (MTK3339) GPS module itself - used in version 3 of this module](https://cdn-shop.adafruit.com/datasheets/GlobalTop-FGPMMOPA6H-Datasheet-V0A.pdf)
- [Datasheet for the PA1616S (MTK3339) GPS module itself - used in version 3.1 of this module](https://cdn-shop.adafruit.com/product-files/746/CD+PA1616S+Datasheet.v03.pdf)
- [MT3339 GPS PC Tool (windows only)](https://cdn-shop.adafruit.com/datasheets/GlobalTop%20MT3339%20PC%20Tool%20v1.3%20without%20F2.0&I3.1.rar) and the [PC Tool manual](https://cdn-shop.adafruit.com/datasheets/GlobalTop%20MT3339%20PC%20Tool%20Operation%20Manual%20v1.1.pdf)
- [Mini GPS tool (windows only)](https://cdn-shop.adafruit.com/datasheets/MiniGPS_Tool_1.7.1.zip)
- [EagleCAD PCB files on GitHub](https://github.com/adafruit/Adafruit-Ultimate-GPS)
- [Fritzing object in the Adafruit Fritzing Library](https://github.com/adafruit/Fritzing-Library)

# Ultimate GPS USB-C Schematic and Fab Print
![](https://cdn-learn.adafruit.com/assets/assets/000/109/800/medium800/adafruit_products_UltimateGPS_USBC_sch.png?1647548405)

![](https://cdn-learn.adafruit.com/assets/assets/000/109/801/medium800/adafruit_products_UltimateGPS_USBC_fab_print.png?1647548413)

# Ultimate GPS v3 Schematic
![](https://cdn-learn.adafruit.com/assets/assets/000/022/494/medium800/gpssch.png?1421536475)

# Ultimate GPS Fabrication Print

Dimensions in Inches

![](https://cdn-learn.adafruit.com/assets/assets/000/022/495/medium800/gpsprint.png?1421536490)

# Ultimate GPS USB Micro B Version Schematic And Fab Print
![](https://cdn-learn.adafruit.com/assets/assets/000/076/956/medium800/adafruit_products_Ultimate_GPS_USB_Sch.png?1560353144)

![](https://cdn-learn.adafruit.com/assets/assets/000/079/165/medium800/adafruit_products_Ultimate_GPS_USB_Fab_Print.png?1565208353)


## Featured Products

### Adafruit Ultimate GPS Breakout - 66 channel w/10 Hz updates

[Adafruit Ultimate GPS Breakout - 66 channel w/10 Hz updates](https://www.adafruit.com/product/746)
We carry a few different GPS modules here in the Adafruit shop, but none that satisfied our every desire - that's why we designed this little GPS breakout board. We believe this is the **Ultimate** GPS module, so we named it that. It's got everything you want and...

Out of Stock
[Buy Now](https://www.adafruit.com/product/746)
[Related Guides to the Product](https://learn.adafruit.com/products/746/guides)
### Adafruit Ultimate GPS GNSS with USB - 99 channel w/10 Hz updates

[Adafruit Ultimate GPS GNSS with USB - 99 channel w/10 Hz updates](https://www.adafruit.com/product/4279)
The Ultimate GPS module you know and love has a _glow-up_ to let it be easily used with any computer, not just microcontrollers! With the built-in USB-to-Serial converter, you can now plug-n-play the Ultimate GPS into your computer, laptop, embedded Linux computer, and more. Power and...

In Stock
[Buy Now](https://www.adafruit.com/product/4279)
[Related Guides to the Product](https://learn.adafruit.com/products/4279/guides)
### Adafruit METRO 328 Fully Assembled - Arduino IDE compatible

[Adafruit METRO 328 Fully Assembled - Arduino IDE compatible](https://www.adafruit.com/product/50)
We sure love the ATmega328 here at Adafruit, and we use them&nbsp;_a lot_&nbsp;for our own projects. The processor has plenty of GPIO, Analog inputs, hardware UART SPI and I2C, timers and PWM galore - just enough for most simple projects. When we need to go small, we use a <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/50)
[Related Guides to the Product](https://learn.adafruit.com/products/50/guides)
### GPS Antenna - External Active Antenna - 3-5V 28dB 5 Meter SMA

[GPS Antenna - External Active Antenna - 3-5V 28dB 5 Meter SMA](https://www.adafruit.com/product/960)
Give your Ultimate GPS V3 a boost with this external active antenna. This GPS antenna draws about 10mA and will give you an additional 28 dB of gain. It's got a 5 meter long cable so it will easily reach wherever you need it to. The antenna is magnetic so it will stick to the top of a car...

In Stock
[Buy Now](https://www.adafruit.com/product/960)
[Related Guides to the Product](https://learn.adafruit.com/products/960/guides)
### SMA to uFL/u.FL/IPX/IPEX RF Adapter Cable

[SMA to uFL/u.FL/IPX/IPEX RF Adapter Cable](https://www.adafruit.com/product/851)
This RF adapter cable is super handy for anyone doing RF work. Often times, small electronics save space by having a pick-and-placeable u.FL connector (also called uFL, IPEX, IPAX, IPX, MHF, and AM). But most antennas have SMA or RP-SMA connectors on them. This little cable will bridge the...

In Stock
[Buy Now](https://www.adafruit.com/product/851)
[Related Guides to the Product](https://learn.adafruit.com/products/851/guides)
### CR1220 12mm Diameter - 3V Lithium Coin Cell Battery

[CR1220 12mm Diameter - 3V Lithium Coin Cell Battery](https://www.adafruit.com/product/380)
These are the highest quality & capacity batteries, the same as shipped with the iCufflinks,&nbsp;iNecklace, Datalogging and GPS Shields, GPS HAT, etc. One battery per order (you'll want one battery per cufflink or pendant.)  
  
Brand may vary but all battery brands are verified...

In Stock
[Buy Now](https://www.adafruit.com/product/380)
[Related Guides to the Product](https://learn.adafruit.com/products/380/guides)
### Breadboarding wire bundle

[Breadboarding wire bundle](https://www.adafruit.com/product/153)
75 flexible stranded core wires with stiff ends molded on in red, orange, yellow, green, blue, brown, black and white. These are a major improvement over the "box of bent wires" that are sometimes sold with breadboards, and faster than stripping your own solid core wires. Makes...

In Stock
[Buy Now](https://www.adafruit.com/product/153)
[Related Guides to the Product](https://learn.adafruit.com/products/153/guides)
### Half Sized Premium Breadboard - 400 Tie Points

[Half Sized Premium Breadboard - 400 Tie Points](https://www.adafruit.com/product/64)
This is a cute, half-size breadboard with&nbsp;400 tie points, good for small projects. It's 3.25" x 2.2" / 8.3cm&nbsp;x 5.5cm&nbsp;with a standard double-strip in the middle and two power rails on both sides.&nbsp;You can pull the power rails off easily to make the breadboard as...

In Stock
[Buy Now](https://www.adafruit.com/product/64)
[Related Guides to the Product](https://learn.adafruit.com/products/64/guides)

## Related Guides

- [Arduino Lesson 14. Servo Motors](https://learn.adafruit.com/adafruit-arduino-lesson-14-servo-motors.md)
- [0.96" mini Color OLED](https://learn.adafruit.com/096-mini-color-oled.md)
- [RGB LED Matrix Basics](https://learn.adafruit.com/32x16-32x32-rgb-led-matrix.md)
- [Adafruit IO Basics: NeoPixel Controller](https://learn.adafruit.com/adafruit-io-basics-neopixel-controller.md)
- [LSM303 Accelerometer + Compass Breakout](https://learn.adafruit.com/lsm303-accelerometer-slash-compass-breakout.md)
- [Digital Circuits 7: MCUs... how do they work?](https://learn.adafruit.com/mcus-how-do-they-work.md)
- [8BitBox](https://learn.adafruit.com/8bitbox.md)
- [1.8" TFT Display Breakout and Shield](https://learn.adafruit.com/1-8-tft-display.md)
- [CircuitPython Libraries on Linux and the NVIDIA Jetson Nano](https://learn.adafruit.com/circuitpython-libraries-on-linux-and-the-nvidia-jetson-nano.md)
- [Bluetooth Controlled Motorized Camera Slider](https://learn.adafruit.com/bluetooth-motorized-camera-slider.md)
- [Electronic Demon Costume](https://learn.adafruit.com/electronic-demon-costume.md)
- [LED Lightbox](https://learn.adafruit.com/led-lightbox.md)
- [WiFi Controlled LED Christmahanukwanzaa Tree](https://learn.adafruit.com/wifi-controlled-led-christmahanukwanzaa-tree.md)
- [IR Sensor](https://learn.adafruit.com/ir-sensor.md)
- [Adafruit PN532 RFID/NFC Breakout and Shield](https://learn.adafruit.com/adafruit-pn532-rfid-nfc.md)
