MKR GPS Shield library only works if you call GPS.Available() non-stop

The MKR GPS Shield only works if I call GPS.Available() very frequently, like keep looping it for 10s before doing anything else.

The MKR GPS Shield does not appear to "lock" on satellites. If I go outside with clear sky and wait for 10 minutes, which any decent GNSS should get a lock. GPS.Available() returns 0.

The only way for the board to work is to call GPS.Available() non-stop. After reading a few posts, I'm not alone here.

The module only output data at 1Hz by default. It make no sense to call it in a non-stop loop.


Switched to Sparksfun u-box library and it works fine. Has cache. Can read from on-chip memory. Locks in no time. Does not matter how long you wait between calls. Can read actual time instead of time from epoch crap, which is different each GNSS.

I STAND BY MY WORD: Whoever wrote the official MKR GPS library should be ashamed of themselves, it's completely rubbish.

Getting Started

Our Arduino_MKRGPS library handles the two different interfaces and offer a consistent set of APIs designed for a full usage of the GPS acquired information

The library does not even touch the tip of iceberg of what this u-box module can do.

1 Like

Which GPS library is 'rubbish'?

So, write a GPS library that's better. It's all open source freeware. Did you test any example sketches that come with the library? Deviate significantly from those in your code?

As post 3 mentions if A is poo! and you do not want A then do B, write your own.

Thats the way most GPS libraries work, you need to feed the libraries with a constant stream of characters from the GPS so that the library is kept up to date with location etc.

The GPS is just a standard Ublox SAM M8Q, if you want to not use it in the standard way, i.e. constanly feeding the library with characters, then you can turn off all the NMEA stuff and poll it dirctly for location information etc.

You might want to try this library;

Its interrupt driven so the library is automagically kept up to date with stuff.

Thanks for the info !

Most GPS does not require non-stop calling to fix satellites and unfix them when you stop calling.

And the Ublox SAM M8Q does not need that either, at least the one I have does not. As long as mine stays powered, it keeps up to date.

Correct! I use Ultimate GPS and tinygps+. I do not need to send a thingy to the GPS module blah, blah, blah. Would that mean your GPS module is at fault that it is not doing the thing unless told to do so and not the fault of the library? Unlike other GPS modules that do the thing, automatically, and I just read the info when it's available.

Look at the example code for your device using the library:

  GPS Location
  This sketch uses the GPS to determine the location of the board
  and prints it to the Serial Monitor.
   - MKR board
   - MKR GPS Shield attached via I2C cable
  This example code is in the public domain.

#include <Arduino_MKRGPS.h>

void setup() {
  // initialize serial communications and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only

  // If you are using the MKR GPS as shield, change the next line to pass
  // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
  if (!GPS.begin()) {
    Serial.println("Failed to initialize GPS!");
    while (1);

void loop() {
  // check if there is new GPS data available
  if (GPS.available()) {
    // read GPS values
    float latitude   = GPS.latitude();
    float longitude  = GPS.longitude();
    float altitude   = GPS.altitude();
    float speed      = GPS.speed();
    int   satellites = GPS.satellites();

    // print GPS values
    Serial.print("Location: ");
    Serial.print(latitude, 7);
    Serial.print(", ");
    Serial.println(longitude, 7);

    Serial.print("Altitude: ");

    Serial.print("Ground speed: ");
    Serial.println(" km/h");

    Serial.print("Number of satellites: ");


GPS.available() just means if the GPS has data available do the thing. It's all good and you do not have an issue.

Ultimate GPS and MKR GPS Shield use different chip and different library. This thread is about MKR GPS and its official library. Do you have experience with the module and library in question ?

You do not have a problem. It's how it all works.
See, functionally the same as your code:

void fGPS_Parse(  void *pvParameters )
  // int iBit = 1;
  for (;;)
    xEventGroupWaitBits (eg, evtGPS_Parse, pdTRUE, pdTRUE, portMAX_DELAY) ;
    if ( xSemaphoreTake( sema_GPS_Gate, xTicksToWait0 ) == pdTRUE )
      //query GPS: has a new complete chunk of data been received?
      if ( GPSSerial.available() > 1 )
        if ( GPS.encode( )
          if (  GPS.location.isValid())
            if ( xSemaphoreTake( sema_Posit, xSemaphoreTicksToWait ) == pdTRUE )
              xPosit.Lat =;// store data into structure
              xPosit.Lon = GPS.location.lng();
              xSemaphoreGive( sema_Posit );
          } // if (  GPS.location.isValid())
          if (GPS.speed.isValid())
            if ( xSemaphoreTake( sema_Posit, xSemaphoreTicksToWait ) == pdTRUE )
              xPosit.MPH = GPS.speed.mph();
              xPosit.KPH = GPS.speed.kmph();
              xSemaphoreGive( sema_Posit );
          } //  if (GPS.speed.isValid())
          if (GPS.time.isValid())
            if ( xSemaphoreTake( sema_Time, xSemaphoreTicksToWait ) == pdTRUE )
              xTime.iSeconds = GPS.time.second();
              xTime.iMinutes = GPS.time.minute();
              xTime.iHours = GPS.time.hour();
              xSemaphoreGive( sema_Time );
          } // if (GPS.time.isValid())
          if (
            if ( xSemaphoreTake( sema_Date, xSemaphoreTicksToWait ) == pdTRUE )
              xDate.iMonth = month();
              xDate.iDay =;
              xDate.iYear =;
              xSemaphoreGive( sema_Date );
          } // if (
          if (  GPS.altitude.isValid() )
            if ( xSemaphoreTake( sema_Posit, xSemaphoreTicksToWait ) == pdTRUE )
              xPosit.Alti = GPS.altitude.meters();
              xSemaphoreGive( sema_Posit );
          } //  if (  GPS.altitude.isValid() )
          if ( GPS.course.isUpdated() )
            if ( xSemaphoreTake( sema_Posit, xSemaphoreTicksToWait ) == pdTRUE )
              xPosit.Hdg = GPS.course.deg();
              xSemaphoreGive( sema_Posit );
          } // if ( GPS.course.isUpdated() )
          if ( xSemaphoreTake( sema_Posit, xSemaphoreTicksToWait ) == pdTRUE )
            xQueueOverwrite( xQ_Posit, (void *) &xPosit );
            xSemaphoreGive( sema_Posit );
        } // if ( GPS.encode(
      } // if ( GPSSerial.available() > 0 )
      xSemaphoreGive( sema_GPS_Gate );
  } // for (;;)
  vTaskDelete( NULL );
} // void fGPS_Parse(  void *pvParameters )

It's how it works.

If all it does is pull data, then it should work if you call it once per second as long as the chip has satellites fixed.

But no, it does not work. It only gives data if I call it non-stop.

Do you use the official library ?

It can pull data when data is available.

Thus, if the GPS has data available at the moment you query the GPS unit at once a second, then the GPS unit will provide you with data. If, at the exact moment you query the GPS and it does not have data, then shrug.

Nope, it will only run on a MKR apparently.

There are several GPS libraries that have been around for a few years, so it might be better to use them since there is a fair number of people experienced in thier use.

There are probably very few people around with knowledge of that particular MKR GPS Shield library, so you might need to rely on support direct from Arduino.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.